1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-30 11:52:11 +01:00

Don't use std::thread.

Wine needs to setup each thread that has an access to Windows APIs. It means that in winelib builds, we can't let standard C++ library create threads and need to use Wine for that instead. I wrote a thin wrapper around Windows thread functions so that the rest of code just has to use new dxvk::thread class instead of std::thread.
This commit is contained in:
Jacek Caban 2018-07-16 18:45:54 +02:00 committed by Philip Rebohle
parent cea1f15eab
commit 6d16bb4c87
9 changed files with 77 additions and 14 deletions

View File

@ -527,7 +527,7 @@ namespace dxvk {
// TODO implement properly in DxvkDevice
while (Resource->isInUse())
std::this_thread::yield();
dxvk::this_thread::yield();
}
return true;

View File

@ -4,8 +4,8 @@
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
#include "../util/thread.h"
#include "dxvk_context.h"
namespace dxvk {
@ -200,7 +200,7 @@ namespace dxvk {
std::condition_variable m_condOnAdd;
std::condition_variable m_condOnSync;
std::queue<Rc<DxvkCsChunk>> m_chunksQueued;
std::thread m_thread;
dxvk::thread m_thread;
uint32_t m_chunksPending = 0;
@ -208,4 +208,4 @@ namespace dxvk {
};
}
}

View File

@ -4,7 +4,6 @@
#include <chrono>
#include <condition_variable>
#include <fstream>
#include <thread>
#include "dxvk_include.h"

View File

@ -13,7 +13,7 @@ namespace dxvk {
m_compilerThreads.resize(threadCount);
for (uint32_t i = 0; i < threadCount; i++) {
m_compilerThreads.at(i) = std::thread(
m_compilerThreads.at(i) = dxvk::thread(
[this] { this->runCompilerThread(); });
}
}

View File

@ -4,8 +4,8 @@
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
#include "../util/thread.h"
#include "dxvk_include.h"
namespace dxvk {
@ -49,7 +49,7 @@ namespace dxvk {
std::mutex m_compilerLock;
std::condition_variable m_compilerCond;
std::queue<PipelineEntry> m_compilerQueue;
std::vector<std::thread> m_compilerThreads;
std::vector<dxvk::thread> m_compilerThreads;
void runCompilerThread();

View File

@ -3,8 +3,8 @@
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
#include "../util/thread.h"
#include "dxvk_cmdlist.h"
#include "dxvk_sync.h"
@ -56,10 +56,10 @@ namespace dxvk {
std::condition_variable m_condOnAdd;
std::condition_variable m_condOnTake;
std::queue<Rc<DxvkCommandList>> m_entries;
std::thread m_thread;
dxvk::thread m_thread;
void threadFunc();
};
}
}

View File

@ -1,7 +1,7 @@
#pragma once
#include <atomic>
#include <thread>
#include "../thread.h"
namespace dxvk::sync {
@ -24,7 +24,7 @@ namespace dxvk::sync {
void lock() {
while (!this->try_lock())
std::this_thread::yield();
dxvk::this_thread::yield();
}
void unlock() {
@ -44,4 +44,4 @@ namespace dxvk::sync {
};
}
}

63
src/util/thread.h Normal file
View File

@ -0,0 +1,63 @@
#pragma once
#include "util_error.h"
#include <windef.h>
#include <winbase.h>
/*
* This is needed mostly for winelib builds. Wine needs to setup each thread that
* calls Windows APIs. It means that in winelib builds, we can't let standard C++
* library create threads and need to use Wine for that instead. We use a thin wrapper
* around Windows thread functions so that the rest of code just has to use
* dxvk::thread class instead of std::thread.
*/
namespace dxvk {
class thread {
private:
HANDLE m_handle;
template<typename T>
class thread_proc {
private:
T proc;
public:
thread_proc(T &proc) : proc(proc) {}
static DWORD WINAPI nativeProc(void *arg) {
thread_proc *proc = reinterpret_cast<thread_proc*>(arg);
proc->proc();
delete proc;
return 0;
}
};
public:
template<class T>
explicit thread(T &&func) {
thread_proc<T> *proc = new thread_proc<T>(func);
m_handle = ::CreateThread(nullptr, 0, thread_proc<T>::nativeProc, proc, 0, nullptr);
if (!m_handle) {
delete proc;
throw DxvkError("Failed to create thread");
}
}
thread() : m_handle(nullptr) {}
~thread() {
if (m_handle)
::CloseHandle(m_handle);
}
void join() {
::WaitForSingleObject(m_handle, INFINITE);
}
};
namespace this_thread {
inline void yield() {
Sleep(0);
}
}
}

View File

@ -6,6 +6,7 @@
#include <thread>
#include "../../src/util/thread.h"
#include "../test_utils.h"
using namespace dxvk;