faster mutex on windows

This commit is contained in:
Mikulas Florek 2020-02-20 22:04:52 +01:00
parent 190c4a9e5b
commit 07ed4f9d43
18 changed files with 125 additions and 157 deletions

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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;
};

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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;
};

View file

@ -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;

View file

@ -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);
}

View file

@ -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() {

View file

@ -28,7 +28,7 @@ private:
u32 allocated_count = 0;
u32 reserved_count = 0;
void* free_pages = nullptr;
MT::CriticalSection mutex;
MT::Mutex mutex;
};

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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;

View file

@ -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,

View file

@ -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);
}

View file

@ -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];

View file

@ -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;