faster mutex on windows
This commit is contained in:
parent
190c4a9e5b
commit
07ed4f9d43
18 changed files with 125 additions and 157 deletions
|
@ -180,7 +180,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
void addResource(ResourceType type, const char* path) override {
|
||||
const Path path_obj(path);
|
||||
const u32 hash = path_obj.getHash();
|
||||
MT::CriticalSectionLock lock(m_resources_mutex);
|
||||
MT::MutexGuard lock(m_resources_mutex);
|
||||
if(m_resources.find(hash).isValid()) {
|
||||
m_resources[hash] = {path_obj, type};
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
if (lua_type(L, -1) != LUA_TTABLE) return;
|
||||
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_resources_mutex);
|
||||
MT::MutexGuard lock(m_resources_mutex);
|
||||
LuaWrapper::forEachArrayItem<Path>(L, -1, "array of strings expected", [this](const Path& p){
|
||||
const ResourceType type = getResourceType(p.c_str());
|
||||
if (type != INVALID_RESOURCE_TYPE) {
|
||||
|
@ -362,7 +362,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
{
|
||||
Array<Path> res(m_app.getAllocator());
|
||||
|
||||
MT::CriticalSectionLock lock(m_resources_mutex);
|
||||
MT::MutexGuard lock(m_resources_mutex);
|
||||
m_resources.eraseIf([&](const ResourceItem& ri){
|
||||
if (!equalStrings(getResourceFilePath(ri.path.c_str()), path)) return false;
|
||||
res.push(ri.path);
|
||||
|
@ -391,7 +391,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
{
|
||||
if (startsWith(path, ".lumix")) return;
|
||||
|
||||
MT::CriticalSectionLock lock(m_changed_mutex);
|
||||
MT::MutexGuard lock(m_changed_mutex);
|
||||
m_changed_files.push(Path(path));
|
||||
}
|
||||
|
||||
|
@ -452,7 +452,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
char ext[16];
|
||||
PathUtils::getExtension(Span(ext), Span(src.c_str(), src.length()));
|
||||
const u32 hash = crc32(ext);
|
||||
MT::CriticalSectionLock lock(m_plugin_mutex);
|
||||
MT::MutexGuard lock(m_plugin_mutex);
|
||||
auto iter = m_plugins.find(hash);
|
||||
if (!iter.isValid()) {
|
||||
logError("Editor") << "Unknown resource type " << src;
|
||||
|
@ -496,7 +496,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
)
|
||||
{
|
||||
logInfo("Editor") << res.getPath() << " is not compiled, pushing to compile queue";
|
||||
MT::CriticalSectionLock lock(m_to_compile_mutex);
|
||||
MT::MutexGuard lock(m_to_compile_mutex);
|
||||
const Path path(filepath);
|
||||
auto iter = m_to_compile_subresources.find(path);
|
||||
if (!iter.isValid()) {
|
||||
|
@ -516,7 +516,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
|
||||
Path popCompiledResource()
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_compiled_mutex);
|
||||
MT::MutexGuard lock(m_compiled_mutex);
|
||||
if(m_compiled.empty()) return Path();
|
||||
const Path p = m_compiled.back();
|
||||
m_compiled.pop();
|
||||
|
@ -535,7 +535,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
AssetCompilerImpl* compiler = LuaWrapper::toType<AssetCompilerImpl*>(L, index);
|
||||
ASSERT(compiler);
|
||||
|
||||
MT::CriticalSectionLock lock(compiler->m_resources_mutex);
|
||||
MT::MutexGuard lock(compiler->m_resources_mutex);
|
||||
lua_createtable(L, 0, compiler->m_resources.size());
|
||||
for (ResourceItem& ri : compiler->m_resources) {
|
||||
lua_pushinteger(L, ri.type.type);
|
||||
|
@ -566,7 +566,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
ImGui::ProgressBar(((float)m_compile_batch_count - m_batch_remaining_count) / m_compile_batch_count);
|
||||
StaticString<MAX_PATH_LENGTH> path;
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_to_compile_mutex);
|
||||
MT::MutexGuard lock(m_to_compile_mutex);
|
||||
path = m_res_in_progress;
|
||||
}
|
||||
ImGui::TextWrapped("%s", path.data);
|
||||
|
@ -582,7 +582,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
if (!p.isValid()) break;
|
||||
|
||||
// this can take some time, mutex is probably not the best option
|
||||
MT::CriticalSectionLock lock(m_compiled_mutex);
|
||||
MT::MutexGuard lock(m_compiled_mutex);
|
||||
|
||||
for (Resource* r : m_to_compile_subresources[p]) {
|
||||
m_load_hook.continueLoad(*r);
|
||||
|
@ -593,7 +593,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
for (;;) {
|
||||
Path path_obj;
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_changed_mutex);
|
||||
MT::MutexGuard lock(m_changed_mutex);
|
||||
if (m_changed_files.empty()) break;
|
||||
|
||||
m_changed_files.removeDuplicates();
|
||||
|
@ -627,7 +627,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
|
||||
void removePlugin(IPlugin& plugin) override
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_plugin_mutex);
|
||||
MT::MutexGuard lock(m_plugin_mutex);
|
||||
bool removed;
|
||||
do {
|
||||
removed = false;
|
||||
|
@ -646,7 +646,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
const char** i = extensions;
|
||||
while(*i) {
|
||||
const u32 hash = crc32(*i);
|
||||
MT::CriticalSectionLock lock(m_plugin_mutex);
|
||||
MT::MutexGuard lock(m_plugin_mutex);
|
||||
m_plugins.insert(hash, &plugin);
|
||||
++i;
|
||||
}
|
||||
|
@ -662,10 +662,10 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
}
|
||||
|
||||
MT::Semaphore m_semaphore;
|
||||
MT::CriticalSection m_to_compile_mutex;
|
||||
MT::CriticalSection m_compiled_mutex;
|
||||
MT::CriticalSection m_plugin_mutex;
|
||||
MT::CriticalSection m_changed_mutex;
|
||||
MT::Mutex m_to_compile_mutex;
|
||||
MT::Mutex m_compiled_mutex;
|
||||
MT::Mutex m_plugin_mutex;
|
||||
MT::Mutex m_changed_mutex;
|
||||
HashMap<Path, Array<Resource*>> m_to_compile_subresources;
|
||||
HashMap<Path, Array<Path>> m_dependencies;
|
||||
Array<Path> m_changed_files;
|
||||
|
@ -676,7 +676,7 @@ struct AssetCompilerImpl : AssetCompiler
|
|||
HashMap<u32, IPlugin*, HashFuncDirect<u32>> m_plugins;
|
||||
AssetCompilerTask m_task;
|
||||
FileSystemWatcher* m_watcher;
|
||||
MT::CriticalSection m_resources_mutex;
|
||||
MT::Mutex m_resources_mutex;
|
||||
HashMap<u32, ResourceItem, HashFuncDirect<u32>> m_resources;
|
||||
HashMap<u32, ResourceType, HashFuncDirect<u32>> m_registered_extensions;
|
||||
|
||||
|
@ -691,7 +691,7 @@ int AssetCompilerTask::task()
|
|||
while (!m_finished) {
|
||||
m_compiler.m_semaphore.wait();
|
||||
const Path p = [&]{
|
||||
MT::CriticalSectionLock lock(m_compiler.m_to_compile_mutex);
|
||||
MT::MutexGuard lock(m_compiler.m_to_compile_mutex);
|
||||
Path p = m_compiler.m_to_compile.back();
|
||||
m_compiler.m_res_in_progress = p.c_str();
|
||||
m_compiler.m_to_compile.pop();
|
||||
|
@ -705,7 +705,7 @@ int AssetCompilerTask::task()
|
|||
if (!compiled) {
|
||||
logError("Editor") << "Failed to compile resource " << p;
|
||||
}
|
||||
MT::CriticalSectionLock lock(m_compiler.m_compiled_mutex);
|
||||
MT::MutexGuard lock(m_compiler.m_compiled_mutex);
|
||||
m_compiler.m_compiled.push(p);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ int LogUI::addNotification(const char* text)
|
|||
|
||||
void LogUI::push(LogLevel level, const char* message)
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_guard);
|
||||
MT::MutexGuard lock(m_guard);
|
||||
++m_new_message_count[(int)level];
|
||||
Message& msg = m_messages.emplace(m_allocator);
|
||||
msg.text = message;
|
||||
|
@ -133,7 +133,7 @@ int LogUI::getUnreadErrorCount() const
|
|||
|
||||
void LogUI::onGUI()
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_guard);
|
||||
MT::MutexGuard lock(m_guard);
|
||||
showNotifications();
|
||||
|
||||
if (!m_is_open) return;
|
||||
|
|
|
@ -63,7 +63,7 @@ class LUMIX_EDITOR_API LogUI
|
|||
bool m_are_notifications_hovered;
|
||||
bool m_scroll_to_bottom = false;
|
||||
bool m_autoscroll = true;
|
||||
MT::CriticalSection m_guard;
|
||||
MT::Mutex m_guard;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ private:
|
|||
private:
|
||||
IAllocator& m_source;
|
||||
StackTree m_stack_tree;
|
||||
MT::CriticalSection m_mutex;
|
||||
MT::Mutex m_mutex;
|
||||
AllocationInfo* m_root;
|
||||
AllocationInfo m_sentinels[2];
|
||||
size_t m_total_size;
|
||||
|
|
|
@ -92,7 +92,7 @@ struct FileSystemImpl final : public FileSystem
|
|||
|
||||
bool hasWork() override
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
return !m_queue.empty();
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ struct FileSystemImpl final : public FileSystem
|
|||
{
|
||||
if (!file.isValid()) return AsyncHandle::invalid();
|
||||
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
AsyncItem& item = m_queue.emplace(m_allocator);
|
||||
++m_last_id;
|
||||
if (m_last_id == 0) ++m_last_id;
|
||||
|
@ -142,7 +142,7 @@ struct FileSystemImpl final : public FileSystem
|
|||
|
||||
void cancel(AsyncHandle async) override
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
for (AsyncItem& item : m_queue) {
|
||||
if (item.id == async.value) {
|
||||
item.flags.set(AsyncItem::Flags::CANCELED);
|
||||
|
@ -269,7 +269,7 @@ struct FileSystemImpl final : public FileSystem
|
|||
Array<AsyncItem> m_queue;
|
||||
Array<AsyncItem> m_finished;
|
||||
Array<u8> m_bundled;
|
||||
MT::CriticalSection m_mutex;
|
||||
MT::Mutex m_mutex;
|
||||
MT::Semaphore m_semaphore;
|
||||
|
||||
u32 m_last_id;
|
||||
|
@ -284,7 +284,7 @@ int FSTask::task()
|
|||
|
||||
StaticString<MAX_PATH_LENGTH> path;
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_fs.m_mutex);
|
||||
MT::MutexGuard lock(m_fs.m_mutex);
|
||||
ASSERT(!m_fs.m_queue.empty());
|
||||
path = m_fs.m_queue[0].path;
|
||||
if (m_fs.m_queue[0].isCanceled()) {
|
||||
|
@ -312,7 +312,7 @@ int FSTask::task()
|
|||
}
|
||||
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_fs.m_mutex);
|
||||
MT::MutexGuard lock(m_fs.m_mutex);
|
||||
if (!m_fs.m_queue[0].isCanceled()) {
|
||||
m_fs.m_finished.emplace(static_cast<AsyncItem&&>(m_fs.m_queue[0]));
|
||||
m_fs.m_finished.back().data = static_cast<OutputMemoryStream&&>(data);
|
||||
|
|
|
@ -80,8 +80,8 @@ struct System
|
|||
}
|
||||
|
||||
|
||||
MT::CriticalSection m_sync;
|
||||
MT::CriticalSection m_job_queue_sync;
|
||||
MT::Mutex m_sync;
|
||||
MT::Mutex m_job_queue_sync;
|
||||
Array<WorkerTask*> m_workers;
|
||||
Array<WorkerTask*> m_backup_workers;
|
||||
Array<Job> m_job_queue;
|
||||
|
@ -189,7 +189,7 @@ void trigger(SignalHandle handle)
|
|||
{
|
||||
LUMIX_FATAL((handle & HANDLE_ID_MASK) < 4096);
|
||||
|
||||
MT::CriticalSectionLock lock(g_system->m_sync);
|
||||
MT::MutexGuard lock(g_system->m_sync);
|
||||
|
||||
Signal& counter = g_system->m_signals_pool[handle & HANDLE_ID_MASK];
|
||||
--counter.value;
|
||||
|
@ -199,7 +199,7 @@ void trigger(SignalHandle handle)
|
|||
while (isValid(iter)) {
|
||||
Signal& signal = g_system->m_signals_pool[iter & HANDLE_ID_MASK];
|
||||
if(signal.next_job.task) {
|
||||
MT::CriticalSectionLock queue_lock(g_system->m_job_queue_sync);
|
||||
MT::MutexGuard queue_lock(g_system->m_job_queue_sync);
|
||||
pushJob(signal.next_job);
|
||||
}
|
||||
signal.generation = (((signal.generation >> 16) + 1) & 0xffFF) << 16;
|
||||
|
@ -250,7 +250,7 @@ static LUMIX_FORCE_INLINE void runInternal(void* data
|
|||
if (on_finish) *on_finish = j.dec_on_finish;
|
||||
|
||||
if (!isValid(precondition) || isSignalZero(precondition, false)) {
|
||||
MT::CriticalSectionLock lock(g_system->m_job_queue_sync);
|
||||
MT::MutexGuard lock(g_system->m_job_queue_sync);
|
||||
pushJob(j);
|
||||
}
|
||||
else {
|
||||
|
@ -273,7 +273,7 @@ static LUMIX_FORCE_INLINE void runInternal(void* data
|
|||
|
||||
void enableBackupWorker(bool enable)
|
||||
{
|
||||
MT::CriticalSectionLock lock(g_system->m_sync);
|
||||
MT::MutexGuard lock(g_system->m_sync);
|
||||
|
||||
for (WorkerTask* task : g_system->m_backup_workers) {
|
||||
if (task->m_is_enabled != enable) {
|
||||
|
@ -300,7 +300,7 @@ void enableBackupWorker(bool enable)
|
|||
void incSignal(SignalHandle* signal)
|
||||
{
|
||||
ASSERT(signal);
|
||||
MT::CriticalSectionLock lock(g_system->m_sync);
|
||||
MT::MutexGuard lock(g_system->m_sync);
|
||||
|
||||
if (isValid(*signal) && !isSignalZero(*signal, false)) {
|
||||
++g_system->m_signals_pool[*signal & HANDLE_ID_MASK].value;
|
||||
|
@ -344,7 +344,7 @@ void runEx(void* data, void(*task)(void*), SignalHandle* on_finished, SignalHand
|
|||
WorkerTask* worker = getWorker();
|
||||
while (!worker->m_finished) {
|
||||
if (worker->m_is_backup) {
|
||||
MT::CriticalSectionLock guard(g_system->m_sync);
|
||||
MT::MutexGuard guard(g_system->m_sync);
|
||||
while (!worker->m_is_enabled) {
|
||||
PROFILE_BLOCK("disabled");
|
||||
Profiler::blockColor(0xff, 0, 0xff);
|
||||
|
@ -355,7 +355,7 @@ void runEx(void* data, void(*task)(void*), SignalHandle* on_finished, SignalHand
|
|||
FiberDecl* fiber = nullptr;
|
||||
Job job;
|
||||
while (!worker->m_finished) {
|
||||
MT::CriticalSectionLock lock(g_system->m_job_queue_sync);
|
||||
MT::MutexGuard lock(g_system->m_job_queue_sync);
|
||||
|
||||
if (!worker->m_ready_fibers.empty()) {
|
||||
fiber = worker->m_ready_fibers.back();
|
||||
|
@ -521,7 +521,7 @@ void wait(SignalHandle handle)
|
|||
FiberDecl* this_fiber = getWorker()->m_current_fiber;
|
||||
|
||||
runInternal(this_fiber, [](void* data){
|
||||
MT::CriticalSectionLock lock(g_system->m_job_queue_sync);
|
||||
MT::MutexGuard lock(g_system->m_job_queue_sync);
|
||||
FiberDecl* fiber = (FiberDecl*)data;
|
||||
if (fiber->current_job.worker_index == ANY_WORKER) {
|
||||
g_system->m_ready_fibers.push(fiber);
|
||||
|
|
|
@ -26,21 +26,21 @@ namespace MT
|
|||
#endif
|
||||
|
||||
|
||||
class alignas(8) LUMIX_ENGINE_API CriticalSection
|
||||
class alignas(8) LUMIX_ENGINE_API Mutex
|
||||
{
|
||||
friend class ConditionVariable;
|
||||
public:
|
||||
CriticalSection();
|
||||
~CriticalSection();
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
CriticalSection(const CriticalSection&) = delete;
|
||||
Mutex(const Mutex&) = delete;
|
||||
|
||||
void enter();
|
||||
void exit();
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
u8 data[64];
|
||||
u8 data[8];
|
||||
#else
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
|
@ -67,7 +67,7 @@ class ConditionVariable
|
|||
public:
|
||||
ConditionVariable();
|
||||
~ConditionVariable();
|
||||
void sleep(CriticalSection& cs);
|
||||
void sleep(Mutex& cs);
|
||||
void wakeup();
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
|
@ -78,21 +78,21 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class CriticalSectionLock
|
||||
class MutexGuard
|
||||
{
|
||||
public:
|
||||
explicit CriticalSectionLock(CriticalSection& cs)
|
||||
: m_critical_section(cs)
|
||||
explicit MutexGuard(Mutex& cs)
|
||||
: m_mutex(cs)
|
||||
{
|
||||
cs.enter();
|
||||
}
|
||||
~CriticalSectionLock() { m_critical_section.exit(); }
|
||||
~MutexGuard() { m_mutex.exit(); }
|
||||
|
||||
CriticalSectionLock(const CriticalSectionLock&) = delete;
|
||||
void operator=(const CriticalSectionLock&) = delete;
|
||||
MutexGuard(const MutexGuard&) = delete;
|
||||
void operator=(const MutexGuard&) = delete;
|
||||
|
||||
private:
|
||||
CriticalSection& m_critical_section;
|
||||
Mutex& m_mutex;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ struct IAllocator;
|
|||
namespace MT
|
||||
{
|
||||
|
||||
class CriticalSection;
|
||||
class Mutex;
|
||||
|
||||
class LUMIX_ENGINE_API Thread
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ public:
|
|||
void setAffinityMask(u64 affinity_mask);
|
||||
|
||||
// call only from task's thread
|
||||
void sleep(CriticalSection& cs);
|
||||
void sleep(Mutex& cs);
|
||||
void wakeup();
|
||||
|
||||
bool isRunning() const;
|
||||
|
|
|
@ -46,36 +46,31 @@ ConditionVariable::ConditionVariable() {
|
|||
InitializeConditionVariable(cv);
|
||||
}
|
||||
|
||||
void ConditionVariable::sleep(CriticalSection& cs) { SleepConditionVariableCS((CONDITION_VARIABLE*)data, (CRITICAL_SECTION*)cs.data, INFINITE); }
|
||||
void ConditionVariable::sleep(Mutex& mutex) { SleepConditionVariableSRW((CONDITION_VARIABLE*)data, (SRWLOCK*)mutex.data, INFINITE, 0); }
|
||||
void ConditionVariable::wakeup() { WakeConditionVariable((CONDITION_VARIABLE*)data); }
|
||||
|
||||
CriticalSection::CriticalSection()
|
||||
Mutex::Mutex()
|
||||
{
|
||||
static_assert(sizeof(data) >= sizeof(CRITICAL_SECTION), "Size is not enough");
|
||||
static_assert(alignof(CriticalSection) == alignof(CRITICAL_SECTION), "Alignment does not match");
|
||||
static_assert(sizeof(data) >= sizeof(SRWLOCK), "Size is not enough");
|
||||
static_assert(alignof(Mutex) == alignof(SRWLOCK), "Alignment does not match");
|
||||
memset(data, 0, sizeof(data));
|
||||
CRITICAL_SECTION* cs = new (NewPlaceholder(), data) CRITICAL_SECTION;
|
||||
InitializeCriticalSectionAndSpinCount(cs, 0x400);
|
||||
SRWLOCK* lock = new (NewPlaceholder(), data) SRWLOCK;
|
||||
InitializeSRWLock(lock);
|
||||
}
|
||||
|
||||
|
||||
CriticalSection::~CriticalSection()
|
||||
{
|
||||
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)data;
|
||||
DeleteCriticalSection(cs);
|
||||
cs->~CRITICAL_SECTION();
|
||||
Mutex::~Mutex() {
|
||||
SRWLOCK* lock = (SRWLOCK*)data;
|
||||
lock->~SRWLOCK();
|
||||
}
|
||||
|
||||
void CriticalSection::enter()
|
||||
{
|
||||
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)data;
|
||||
EnterCriticalSection(cs);
|
||||
void Mutex::enter() {
|
||||
SRWLOCK* lock = (SRWLOCK*)data;
|
||||
AcquireSRWLockExclusive(lock);
|
||||
}
|
||||
|
||||
void CriticalSection::exit()
|
||||
{
|
||||
CRITICAL_SECTION* cs = (CRITICAL_SECTION*)data;
|
||||
LeaveCriticalSection(cs);
|
||||
void Mutex::exit() {
|
||||
SRWLOCK* lock = (SRWLOCK*)data;
|
||||
ReleaseSRWLockExclusive (lock);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -134,8 +134,8 @@ void Thread::setAffinityMask(u64 affinity_mask)
|
|||
}
|
||||
}
|
||||
|
||||
void Thread::sleep(CriticalSection& cs) {
|
||||
m_implementation->m_cv.sleep(cs);
|
||||
void Thread::sleep(Mutex& mutex) {
|
||||
m_implementation->m_cv.sleep(mutex);
|
||||
}
|
||||
|
||||
void Thread::wakeup() {
|
||||
|
|
|
@ -28,7 +28,7 @@ private:
|
|||
u32 allocated_count = 0;
|
||||
u32 reserved_count = 0;
|
||||
void* free_pages = nullptr;
|
||||
MT::CriticalSection mutex;
|
||||
MT::Mutex mutex;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ struct PathManagerImpl : PathManager
|
|||
}
|
||||
|
||||
void serialize(IOutputStream& serializer) override {
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
clear();
|
||||
serializer.write((i32)m_paths.size());
|
||||
for (int i = 0; i < m_paths.size(); ++i) {
|
||||
|
@ -42,7 +42,7 @@ struct PathManagerImpl : PathManager
|
|||
}
|
||||
|
||||
void deserialize(IInputStream& serializer) override {
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
i32 size;
|
||||
serializer.read(size);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
|
@ -64,12 +64,12 @@ struct PathManagerImpl : PathManager
|
|||
}
|
||||
|
||||
PathInternal* getPath(u32 hash, const char* path) {
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
return getPathMultithreadUnsafe(hash, path);
|
||||
}
|
||||
|
||||
PathInternal* getPath(u32 hash) {
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
int index = m_paths.find(hash);
|
||||
if (index < 0) {
|
||||
return nullptr;
|
||||
|
@ -93,12 +93,12 @@ struct PathManagerImpl : PathManager
|
|||
}
|
||||
|
||||
void incrementRefCount(PathInternal* path) {
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
++path->m_ref_count;
|
||||
}
|
||||
|
||||
void decrementRefCount(PathInternal* path) {
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
--path->m_ref_count;
|
||||
if (path->m_ref_count == 0) {
|
||||
m_paths.erase(path->m_id);
|
||||
|
@ -108,7 +108,7 @@ struct PathManagerImpl : PathManager
|
|||
|
||||
IAllocator& m_allocator;
|
||||
AssociativeArray<u32, PathInternal*> m_paths;
|
||||
MT::CriticalSection m_mutex;
|
||||
MT::Mutex m_mutex;
|
||||
Path* m_empty_path;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ struct ThreadContext
|
|||
u32 end = 0;
|
||||
u32 rows = 0;
|
||||
bool open = false;
|
||||
MT::CriticalSection mutex;
|
||||
MT::Mutex mutex;
|
||||
StaticString<64> name;
|
||||
bool show_in_profiler = false;
|
||||
u32 thread_id;
|
||||
|
@ -155,7 +155,7 @@ static struct Instance
|
|||
thread_local ThreadContext* ctx = [&](){
|
||||
ThreadContext* new_ctx = LUMIX_NEW(allocator, ThreadContext)(allocator);
|
||||
new_ctx->thread_id = OS::getCurrentThreadID();
|
||||
MT::CriticalSectionLock lock(mutex);
|
||||
MT::MutexGuard lock(mutex);
|
||||
contexts.push(new_ctx);
|
||||
return new_ctx;
|
||||
}();
|
||||
|
@ -166,7 +166,7 @@ static struct Instance
|
|||
|
||||
DefaultAllocator allocator;
|
||||
Array<ThreadContext*> contexts;
|
||||
MT::CriticalSection mutex;
|
||||
MT::Mutex mutex;
|
||||
OS::Timer timer;
|
||||
bool paused = false;
|
||||
bool context_switches_enabled = false;
|
||||
|
@ -195,7 +195,7 @@ void write(ThreadContext& ctx, u64 timestamp, EventType type, const T& value)
|
|||
v.header.time = timestamp;
|
||||
v.value = value;
|
||||
|
||||
MT::CriticalSectionLock lock(ctx.mutex);
|
||||
MT::MutexGuard lock(ctx.mutex);
|
||||
u8* buf = ctx.buffer.begin();
|
||||
const int buf_size = ctx.buffer.size();
|
||||
|
||||
|
@ -232,7 +232,7 @@ void write(ThreadContext& ctx, EventType type, const T& value)
|
|||
v.header.time = OS::Timer::getRawTimestamp();
|
||||
v.value = value;
|
||||
|
||||
MT::CriticalSectionLock lock(ctx.mutex);
|
||||
MT::MutexGuard lock(ctx.mutex);
|
||||
u8* buf = ctx.buffer.begin();
|
||||
const int buf_size = ctx.buffer.size();
|
||||
|
||||
|
@ -264,7 +264,7 @@ void write(ThreadContext& ctx, EventType type, const u8* data, int size)
|
|||
header.size = u16(sizeof(header) + size);
|
||||
header.time = OS::Timer::getRawTimestamp();
|
||||
|
||||
MT::CriticalSectionLock lock(ctx.mutex);
|
||||
MT::MutexGuard lock(ctx.mutex);
|
||||
u8* buf = ctx.buffer.begin();
|
||||
const u32 buf_size = ctx.buffer.size();
|
||||
|
||||
|
@ -492,7 +492,7 @@ void frame()
|
|||
void showInProfiler(bool show)
|
||||
{
|
||||
ThreadContext* ctx = g_instance.getThreadContext();
|
||||
MT::CriticalSectionLock lock(ctx->mutex);
|
||||
MT::MutexGuard lock(ctx->mutex);
|
||||
|
||||
ctx->show_in_profiler = show;
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ void showInProfiler(bool show)
|
|||
void setThreadName(const char* name)
|
||||
{
|
||||
ThreadContext* ctx = g_instance.getThreadContext();
|
||||
MT::CriticalSectionLock lock(ctx->mutex);
|
||||
MT::MutexGuard lock(ctx->mutex);
|
||||
|
||||
ctx->name = name;
|
||||
}
|
||||
|
@ -529,7 +529,7 @@ int GlobalState::threadsCount() const
|
|||
const char* GlobalState::getThreadName(int idx) const
|
||||
{
|
||||
ThreadContext* ctx = g_instance.contexts[idx];
|
||||
MT::CriticalSectionLock lock(ctx->mutex);
|
||||
MT::MutexGuard lock(ctx->mutex);
|
||||
return ctx->name;
|
||||
}
|
||||
|
||||
|
|
|
@ -488,7 +488,7 @@ void Allocator::deallocate_aligned(void* user_ptr)
|
|||
}
|
||||
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
if (info == m_root)
|
||||
{
|
||||
m_root = info->next;
|
||||
|
@ -537,7 +537,7 @@ void* Allocator::allocate(size_t size)
|
|||
AllocationInfo* info;
|
||||
size_t system_size = getNeededMemory(size);
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
system_ptr = m_source.allocate(system_size);
|
||||
info = new (NewPlaceholder(), getAllocationInfoFromSystem(system_ptr)) AllocationInfo();
|
||||
|
||||
|
@ -593,7 +593,7 @@ void Allocator::deallocate(void* user_ptr)
|
|||
}
|
||||
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
if (info == m_root)
|
||||
{
|
||||
m_root = info->next;
|
||||
|
|
|
@ -291,36 +291,10 @@ typedef struct _RTL_CONDITION_VARIABLE {
|
|||
|
||||
typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
|
||||
|
||||
typedef struct _RTL_CRITICAL_SECTION_DEBUG {
|
||||
WORD Type;
|
||||
WORD CreatorBackTraceIndex;
|
||||
struct _RTL_CRITICAL_SECTION *CriticalSection;
|
||||
LIST_ENTRY ProcessLocksList;
|
||||
DWORD EntryCount;
|
||||
DWORD ContentionCount;
|
||||
DWORD Flags;
|
||||
WORD CreatorBackTraceIndexHigh;
|
||||
WORD SpareWORD;
|
||||
} RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG;
|
||||
|
||||
typedef struct _RTL_CRITICAL_SECTION {
|
||||
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
|
||||
|
||||
//
|
||||
// The following three fields control entering and exiting the critical
|
||||
// section for the resource
|
||||
//
|
||||
|
||||
LONG LockCount;
|
||||
LONG RecursionCount;
|
||||
HANDLE OwningThread; // from the thread's ClientId->UniqueThread
|
||||
HANDLE LockSemaphore;
|
||||
ULONG_PTR SpinCount; // force size on 64-bit systems when packed
|
||||
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
|
||||
typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION;
|
||||
typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION;
|
||||
typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
|
||||
|
||||
typedef struct _RTL_SRWLOCK {
|
||||
PVOID Ptr;
|
||||
} RTL_SRWLOCK, *PRTL_SRWLOCK;
|
||||
typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
|
||||
|
||||
typedef struct _SECURITY_ATTRIBUTES
|
||||
{
|
||||
|
@ -552,14 +526,13 @@ WINBASEAPI DWORD WINAPI SetFilePointer(HANDLE hFile,
|
|||
PLONG lpDistanceToMoveHigh,
|
||||
DWORD dwMoveMethod);
|
||||
WINBASEAPI BOOL WINAPI SetEndOfFile(HANDLE hFile);
|
||||
WINBASEAPI VOID WINAPI InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
|
||||
WINBASEAPI BOOL WINAPI InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount);
|
||||
WINBASEAPI VOID WINAPI DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
|
||||
WINBASEAPI VOID WINAPI EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
|
||||
WINBASEAPI VOID WINAPI LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
|
||||
|
||||
WINBASEAPI BOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD dwMilliseconds);
|
||||
WINBASEAPI VOID WINAPI InitializeSRWLock(PSRWLOCK SRWLock);
|
||||
WINBASEAPI VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK SRWLock);
|
||||
WINBASEAPI VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK SRWLock);
|
||||
|
||||
WINBASEAPI VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
|
||||
WINBASEAPI BOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK SRWLock, DWORD dwMilliseconds, ULONG Flags);
|
||||
WINBASEAPI VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
|
||||
|
||||
WINBASEAPI HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
|
||||
|
|
|
@ -114,7 +114,7 @@ static struct {
|
|||
Pool<Buffer, Buffer::MAX_COUNT> buffers;
|
||||
Pool<Texture, Texture::MAX_COUNT> textures;
|
||||
Pool<Program, Program::MAX_COUNT> programs;
|
||||
MT::CriticalSection handle_mutex;
|
||||
MT::Mutex handle_mutex;
|
||||
Lumix::OS::ThreadID thread;
|
||||
int instance_attributes = 0;
|
||||
int max_vertex_attributes = 16;
|
||||
|
@ -1290,7 +1290,7 @@ void destroy(ProgramHandle program)
|
|||
const GLuint handle = p.handle;
|
||||
CHECK_GL(glDeleteProgram(handle));
|
||||
|
||||
MT::CriticalSectionLock lock(g_gpu.handle_mutex);
|
||||
MT::MutexGuard lock(g_gpu.handle_mutex);
|
||||
g_gpu.programs.dealloc(program.value);
|
||||
}
|
||||
|
||||
|
@ -1552,7 +1552,7 @@ bool loadTexture(TextureHandle handle, const void* input, int input_size, u32 fl
|
|||
|
||||
ProgramHandle allocProgramHandle()
|
||||
{
|
||||
MT::CriticalSectionLock lock(g_gpu.handle_mutex);
|
||||
MT::MutexGuard lock(g_gpu.handle_mutex);
|
||||
|
||||
if(g_gpu.programs.isFull()) {
|
||||
logError("Renderer") << "Not enough free program slots.";
|
||||
|
@ -1569,7 +1569,7 @@ ProgramHandle allocProgramHandle()
|
|||
|
||||
BufferHandle allocBufferHandle()
|
||||
{
|
||||
MT::CriticalSectionLock lock(g_gpu.handle_mutex);
|
||||
MT::MutexGuard lock(g_gpu.handle_mutex);
|
||||
|
||||
if(g_gpu.buffers.isFull()) {
|
||||
logError("Renderer") << "Not enough free buffer slots.";
|
||||
|
@ -1586,7 +1586,7 @@ BufferHandle allocBufferHandle()
|
|||
|
||||
TextureHandle allocTextureHandle()
|
||||
{
|
||||
MT::CriticalSectionLock lock(g_gpu.handle_mutex);
|
||||
MT::MutexGuard lock(g_gpu.handle_mutex);
|
||||
|
||||
if(g_gpu.textures.isFull()) {
|
||||
logError("Renderer") << "Not enough free texture slots.";
|
||||
|
@ -1722,7 +1722,7 @@ void destroy(TextureHandle texture)
|
|||
const GLuint handle = t.handle;
|
||||
CHECK_GL(glDeleteTextures(1, &handle));
|
||||
|
||||
MT::CriticalSectionLock lock(g_gpu.handle_mutex);
|
||||
MT::MutexGuard lock(g_gpu.handle_mutex);
|
||||
g_gpu.textures.dealloc(texture.value);
|
||||
}
|
||||
|
||||
|
@ -1735,7 +1735,7 @@ void destroy(BufferHandle buffer)
|
|||
const GLuint handle = t.handle;
|
||||
CHECK_GL(glDeleteBuffers(1, &handle));
|
||||
|
||||
MT::CriticalSectionLock lock(g_gpu.handle_mutex);
|
||||
MT::MutexGuard lock(g_gpu.handle_mutex);
|
||||
g_gpu.buffers.dealloc(buffer.value);
|
||||
}
|
||||
|
||||
|
|
|
@ -128,10 +128,10 @@ struct MTBucketArray
|
|||
|
||||
static inline MTBucketArray* s_free_arrays[64] = {};
|
||||
static inline u32 s_num_free_arrays = 0;
|
||||
static inline MT::CriticalSection s_cs;
|
||||
static inline MT::Mutex s_cs;
|
||||
|
||||
static MTBucketArray* allocArray(IAllocator& allocator) {
|
||||
MT::CriticalSectionLock lock(s_cs);
|
||||
MT::MutexGuard lock(s_cs);
|
||||
if (s_num_free_arrays == 0) {
|
||||
return LUMIX_NEW(allocator, MTBucketArray<T>)(allocator);
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ struct MTBucketArray
|
|||
}
|
||||
|
||||
static void freeArray(MTBucketArray* a) {
|
||||
MT::CriticalSectionLock lock(s_cs);
|
||||
MT::MutexGuard lock(s_cs);
|
||||
a->clear();
|
||||
ASSERT(s_num_free_arrays < lengthOf(s_free_arrays) - 1);
|
||||
s_free_arrays[s_num_free_arrays] = a;
|
||||
|
@ -210,7 +210,7 @@ struct MTBucketArray
|
|||
void end(const Bucket& bucket)
|
||||
{
|
||||
const int bucket_idx = int(((u8*)bucket.values - m_values_mem) / BUCKET_SIZE);
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
m_counts[bucket_idx] = bucket.count;
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ struct MTBucketArray
|
|||
T* value_ptr() const { return (T*)m_values_mem; }
|
||||
|
||||
IAllocator& m_allocator;
|
||||
MT::CriticalSection m_mutex;
|
||||
MT::Mutex m_mutex;
|
||||
u8* const m_keys_mem;
|
||||
u8* const m_values_mem;
|
||||
u8* m_keys_end;
|
||||
|
@ -2718,7 +2718,7 @@ struct PipelineImpl final : Pipeline
|
|||
|
||||
u32 m_histogram[SIZE];
|
||||
bool m_sorted;
|
||||
MT::CriticalSection m_cs;
|
||||
MT::Mutex m_cs;
|
||||
|
||||
void compute(const u64* keys, const u64* values, int size, u16 shift) {
|
||||
memset(m_histogram, 0, sizeof(m_histogram));
|
||||
|
@ -2748,7 +2748,7 @@ struct PipelineImpl final : Pipeline
|
|||
begin = MT::atomicAdd(&counter, STEP);
|
||||
}
|
||||
|
||||
MT::CriticalSectionLock lock(m_cs);
|
||||
MT::MutexGuard lock(m_cs);
|
||||
m_sorted &= sorted;
|
||||
for (u32 i = 0; i < lengthOf(m_histogram); ++i) {
|
||||
m_histogram[i] += histogram[i];
|
||||
|
|
|
@ -57,7 +57,7 @@ struct TransientBuffer {
|
|||
return slice;
|
||||
}
|
||||
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
if (!m_overflow.buffer.isValid()) {
|
||||
m_overflow.buffer = gpu::allocBufferHandle();
|
||||
m_overflow.data = (u8*)OS::memReserve(128 * 1024 * 1024);
|
||||
|
@ -106,7 +106,7 @@ struct TransientBuffer {
|
|||
i32 m_offset = 0;
|
||||
u32 m_size = 0;
|
||||
u8* m_ptr = nullptr;
|
||||
MT::CriticalSection m_mutex;
|
||||
MT::Mutex m_mutex;
|
||||
|
||||
struct {
|
||||
gpu::BufferHandle buffer = gpu::INVALID_BUFFER;
|
||||
|
@ -142,7 +142,7 @@ struct FrameData {
|
|||
|
||||
Array<MaterialUpdates> material_updates;
|
||||
Array<Renderer::RenderJob*> jobs;
|
||||
MT::CriticalSection shader_mutex;
|
||||
MT::Mutex shader_mutex;
|
||||
Array<ShaderToCompile> to_compile_shaders;
|
||||
RendererImpl& renderer;
|
||||
JobSystem::SignalHandle can_setup = JobSystem::INVALID_HANDLE;
|
||||
|
@ -254,7 +254,7 @@ struct GPUProfiler
|
|||
|
||||
void beginQuery(const char* name, i64 profiler_link)
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
Query& q = m_queries.emplace();
|
||||
q.profiler_link = profiler_link;
|
||||
q.name = name;
|
||||
|
@ -267,7 +267,7 @@ struct GPUProfiler
|
|||
|
||||
void endQuery()
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
Query& q = m_queries.emplace();
|
||||
q.is_end = true;
|
||||
q.is_frame = false;
|
||||
|
@ -279,7 +279,7 @@ struct GPUProfiler
|
|||
void frame()
|
||||
{
|
||||
PROFILE_FUNCTION();
|
||||
MT::CriticalSectionLock lock(m_mutex);
|
||||
MT::MutexGuard lock(m_mutex);
|
||||
Query frame_query;
|
||||
frame_query.is_frame = true;
|
||||
m_queries.push(frame_query);
|
||||
|
@ -309,7 +309,7 @@ struct GPUProfiler
|
|||
|
||||
Array<Query> m_queries;
|
||||
Array<gpu::QueryHandle> m_pool;
|
||||
MT::CriticalSection m_mutex;
|
||||
MT::Mutex m_mutex;
|
||||
i64 m_gpu_to_cpu_offset;
|
||||
};
|
||||
|
||||
|
@ -1032,7 +1032,7 @@ struct RendererImpl final : public Renderer
|
|||
|
||||
gpu::ProgramHandle queueShaderCompile(Shader& shader, gpu::VertexDecl decl, u32 defines) override {
|
||||
ASSERT(shader.isReady());
|
||||
MT::CriticalSectionLock lock(m_cpu_frame->shader_mutex);
|
||||
MT::MutexGuard lock(m_cpu_frame->shader_mutex);
|
||||
|
||||
for (const auto& i : m_cpu_frame->to_compile_shaders) {
|
||||
if (i.shader == &shader && decl.hash == i.decl.hash && defines == i.defines) {
|
||||
|
@ -1049,7 +1049,7 @@ struct RendererImpl final : public Renderer
|
|||
|
||||
u8 getShaderDefineIdx(const char* define) override
|
||||
{
|
||||
MT::CriticalSectionLock lock(m_shader_defines_mutex);
|
||||
MT::MutexGuard lock(m_shader_defines_mutex);
|
||||
for (int i = 0; i < m_shader_defines.size(); ++i)
|
||||
{
|
||||
if (m_shader_defines[i] == define)
|
||||
|
@ -1180,7 +1180,7 @@ struct RendererImpl final : public Renderer
|
|||
Engine& m_engine;
|
||||
IAllocator& m_allocator;
|
||||
Array<StaticString<32>> m_shader_defines;
|
||||
MT::CriticalSection m_shader_defines_mutex;
|
||||
MT::Mutex m_shader_defines_mutex;
|
||||
Array<StaticString<32>> m_layers;
|
||||
FontManager* m_font_manager;
|
||||
MaterialManager m_material_manager;
|
||||
|
|
Loading…
Reference in a new issue