mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Add facility to run tasks on dedicated threads using the ThreadManager interface.
Useful for things that should be run ASAP even if the threadpool is full, at a small extra cost. (Not recommended for very small tasks). Considering using this to resolve the deadlocks in #16802.
This commit is contained in:
parent
b04dd81cba
commit
6b0903f566
6 changed files with 26 additions and 7 deletions
|
@ -213,7 +213,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
VulkanContext *vulkan_;
|
||||
VulkanContext *vulkan_ = nullptr;
|
||||
Promise<VkShaderModule> *module_ = nullptr;
|
||||
VkShaderStageFlagBits vkstage_;
|
||||
bool ok_ = false;
|
||||
|
|
|
@ -18,11 +18,12 @@ public:
|
|||
// Public variables since it doesn't make sense
|
||||
// to bother with accessors for all these.
|
||||
int status = 100;
|
||||
// Intentional misspelling.
|
||||
char *referer = nullptr;
|
||||
|
||||
char *referer = nullptr; // Intentional misspelling.
|
||||
char *user_agent = nullptr;
|
||||
char *resource = nullptr;
|
||||
char *params = nullptr;
|
||||
|
||||
int content_length = -1;
|
||||
std::unordered_map<std::string, std::string> other;
|
||||
enum RequestType {
|
||||
|
|
|
@ -81,7 +81,7 @@ Request::~Request() {
|
|||
}
|
||||
delete in_;
|
||||
if (!out_->Empty()) {
|
||||
ERROR_LOG(IO, "Output not empty - connection abort?");
|
||||
ERROR_LOG(IO, "Output not empty - connection abort? (%s)", this->header_.resource);
|
||||
}
|
||||
delete out_;
|
||||
}
|
||||
|
|
|
@ -217,6 +217,16 @@ void ThreadManager::Init(int numRealCores, int numLogicalCoresPerCpu) {
|
|||
}
|
||||
|
||||
void ThreadManager::EnqueueTask(Task *task) {
|
||||
if (task->Type() == TaskType::DEDICATED_THREAD) {
|
||||
std::thread th([=](Task *task) {
|
||||
SetCurrentThreadName("DedicatedThreadTask");
|
||||
task->Run();
|
||||
task->Release();
|
||||
}, task);
|
||||
th.detach();
|
||||
return;
|
||||
}
|
||||
|
||||
_assert_msg_(IsInitialized(), "ThreadManager not initialized");
|
||||
|
||||
int minThread;
|
||||
|
@ -270,6 +280,8 @@ void ThreadManager::EnqueueTask(Task *task) {
|
|||
}
|
||||
|
||||
void ThreadManager::EnqueueTaskOnThread(int threadNum, Task *task) {
|
||||
_assert_msg_(task->Type() != TaskType::DEDICATED_THREAD, "Dedicated thread tasks can't be put on specific threads");
|
||||
|
||||
_assert_msg_(threadNum >= 0 && threadNum < (int)global_->threads_.size(), "Bad threadnum or not initialized");
|
||||
ThreadContext *thread = global_->threads_[threadNum];
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
enum class TaskType {
|
||||
CPU_COMPUTE,
|
||||
IO_BLOCKING,
|
||||
DEDICATED_THREAD, // These can never get stuck in queue behind others, but are more expensive to launch. Cannot use I/O.
|
||||
};
|
||||
|
||||
// Implement this to make something that you can run on the thread manager.
|
||||
|
|
|
@ -98,12 +98,17 @@ static Promise<VkShaderModule> *CompileShaderModuleAsync(VulkanContext *vulkan,
|
|||
|
||||
#if defined(_DEBUG)
|
||||
// Don't parallelize in debug mode, pathological behavior due to mutex locks in allocator which is HEAVILY used by glslang.
|
||||
return Promise<VkShaderModule>::AlreadyDone(compile());
|
||||
bool singleThreaded = true;
|
||||
#else
|
||||
return Promise<VkShaderModule>::Spawn(&g_threadManager, compile, TaskType::CPU_COMPUTE);
|
||||
bool singleThreaded = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (singleThreaded) {
|
||||
return Promise<VkShaderModule>::AlreadyDone(compile());
|
||||
} else {
|
||||
return Promise<VkShaderModule>::Spawn(&g_threadManager, compile, TaskType::CPU_COMPUTE);
|
||||
}
|
||||
}
|
||||
|
||||
VulkanFragmentShader::VulkanFragmentShader(VulkanContext *vulkan, FShaderID id, FragmentShaderFlags flags, const char *code)
|
||||
: vulkan_(vulkan), id_(id), flags_(flags) {
|
||||
|
|
Loading…
Add table
Reference in a new issue