Browse Source
core: hle: server_session: Use separate threads for each service connection.
pull/15/merge
core: hle: server_session: Use separate threads for each service connection.
pull/15/merge
6 changed files with 140 additions and 23 deletions
-
2src/core/CMakeLists.txt
-
2src/core/hle/kernel/kernel.cpp
-
20src/core/hle/kernel/server_session.cpp
-
12src/core/hle/kernel/server_session.h
-
100src/core/hle/kernel/service_thread.cpp
-
27src/core/hle/kernel/service_thread.h
@ -0,0 +1,100 @@ |
|||
// Copyright 2020 yuzu emulator team
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <condition_variable>
|
|||
#include <functional>
|
|||
#include <mutex>
|
|||
#include <thread>
|
|||
#include <vector>
|
|||
#include <queue>
|
|||
|
|||
#include "common/assert.h"
|
|||
#include "common/scope_exit.h"
|
|||
#include "core/core.h"
|
|||
#include "core/hle/kernel/kernel.h"
|
|||
#include "core/hle/kernel/server_session.h"
|
|||
#include "core/hle/kernel/service_thread.h"
|
|||
#include "core/hle/lock.h"
|
|||
#include "video_core/renderer_base.h"
|
|||
|
|||
namespace Kernel { |
|||
|
|||
class ServiceThread::Impl final { |
|||
public: |
|||
explicit Impl(KernelCore& kernel); |
|||
~Impl(); |
|||
|
|||
void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context); |
|||
|
|||
private: |
|||
std::vector<std::thread> threads; |
|||
std::queue<std::function<void()>> requests; |
|||
std::mutex queue_mutex; |
|||
std::condition_variable condition; |
|||
bool stop{}; |
|||
}; |
|||
|
|||
ServiceThread::Impl::Impl(KernelCore& kernel) { |
|||
constexpr std::size_t SizeOfPool{1}; |
|||
for (std::size_t i = 0; i < SizeOfPool; ++i) |
|||
threads.emplace_back([&] { |
|||
// Wait for first request before trying to acquire a render context
|
|||
{ |
|||
std::unique_lock lock{queue_mutex}; |
|||
condition.wait(lock, [this] { return stop || !requests.empty(); }); |
|||
} |
|||
|
|||
kernel.RegisterHostThread(); |
|||
|
|||
while (true) { |
|||
std::function<void()> task; |
|||
|
|||
{ |
|||
std::unique_lock lock{queue_mutex}; |
|||
condition.wait(lock, [this] { return stop || !requests.empty(); }); |
|||
if (stop && requests.empty()) { |
|||
return; |
|||
} |
|||
task = std::move(requests.front()); |
|||
requests.pop(); |
|||
} |
|||
|
|||
task(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
void ServiceThread::Impl::QueueSyncRequest(ServerSession& session, |
|||
std::shared_ptr<HLERequestContext>&& context) { |
|||
{ |
|||
std::unique_lock lock{queue_mutex}; |
|||
requests.emplace([session{SharedFrom(&session)}, context{std::move(context)}]() { |
|||
session->CompleteSyncRequest(*context); |
|||
return; |
|||
}); |
|||
} |
|||
condition.notify_one(); |
|||
} |
|||
|
|||
ServiceThread::Impl::~Impl() { |
|||
{ |
|||
std::unique_lock lock{queue_mutex}; |
|||
stop = true; |
|||
} |
|||
condition.notify_all(); |
|||
for (std::thread& thread : threads) { |
|||
thread.join(); |
|||
} |
|||
} |
|||
|
|||
ServiceThread::ServiceThread(KernelCore& kernel) : impl{std::make_unique<Impl>(kernel)} {} |
|||
|
|||
ServiceThread::~ServiceThread() = default; |
|||
|
|||
void ServiceThread::QueueSyncRequest(ServerSession& session, |
|||
std::shared_ptr<HLERequestContext>&& context) { |
|||
impl->QueueSyncRequest(session, std::move(context)); |
|||
} |
|||
|
|||
} // namespace Kernel
|
|||
@ -0,0 +1,27 @@ |
|||
// Copyright 2020 yuzu emulator team |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
|
|||
namespace Kernel { |
|||
|
|||
class HLERequestContext; |
|||
class KernelCore; |
|||
class ServerSession; |
|||
|
|||
class ServiceThread final { |
|||
public: |
|||
explicit ServiceThread(KernelCore& kernel); |
|||
~ServiceThread(); |
|||
|
|||
void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context); |
|||
|
|||
private: |
|||
class Impl; |
|||
std::unique_ptr<Impl> impl; |
|||
}; |
|||
|
|||
} // namespace Kernel |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue