spin_lock: Use std::call_once

This commit is contained in:
Merry 2023-05-07 15:12:05 +01:00
parent f9e6a3df5c
commit d5c2b473a8
2 changed files with 10 additions and 18 deletions

View file

@ -3,6 +3,8 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include <mutex>
#include <oaknut/code_block.hpp> #include <oaknut/code_block.hpp>
#include <oaknut/oaknut.hpp> #include <oaknut/oaknut.hpp>
@ -43,11 +45,11 @@ struct SpinLockImpl {
oaknut::CodeBlock mem; oaknut::CodeBlock mem;
oaknut::CodeGenerator code; oaknut::CodeGenerator code;
bool initialized = false;
void (*lock)(volatile int*); void (*lock)(volatile int*);
void (*unlock)(volatile int*); void (*unlock)(volatile int*);
}; };
std::once_flag flag;
SpinLockImpl impl; SpinLockImpl impl;
SpinLockImpl::SpinLockImpl() SpinLockImpl::SpinLockImpl()
@ -66,23 +68,17 @@ void SpinLockImpl::Initialize() {
code.RET(); code.RET();
mem.protect(); mem.protect();
initialized = true;
} }
} // namespace } // namespace
void SpinLock::Lock() { void SpinLock::Lock() {
if (!impl.initialized) [[unlikely]] { std::call_once(flag, &SpinLockImpl::Initialize, impl);
impl.Initialize();
}
impl.lock(&storage); impl.lock(&storage);
} }
void SpinLock::Unlock() { void SpinLock::Unlock() {
if (!impl.initialized) [[unlikely]] { std::call_once(flag, &SpinLockImpl::Initialize, impl);
impl.Initialize();
}
impl.unlock(&storage); impl.unlock(&storage);
} }

View file

@ -3,6 +3,8 @@
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
*/ */
#include <mutex>
#include <xbyak/xbyak.h> #include <xbyak/xbyak.h>
#include "dynarmic/backend/x64/abi.h" #include "dynarmic/backend/x64/abi.h"
@ -38,11 +40,11 @@ struct SpinLockImpl {
Xbyak::CodeGenerator code; Xbyak::CodeGenerator code;
bool initialized = false;
void (*lock)(volatile int*); void (*lock)(volatile int*);
void (*unlock)(volatile int*); void (*unlock)(volatile int*);
}; };
std::once_flag flag;
SpinLockImpl impl; SpinLockImpl impl;
void SpinLockImpl::Initialize() { void SpinLockImpl::Initialize() {
@ -57,23 +59,17 @@ void SpinLockImpl::Initialize() {
unlock = code.getCurr<void (*)(volatile int*)>(); unlock = code.getCurr<void (*)(volatile int*)>();
EmitSpinLockUnlock(code, ABI_PARAM1, code.eax); EmitSpinLockUnlock(code, ABI_PARAM1, code.eax);
code.ret(); code.ret();
initialized = true;
} }
} // namespace } // namespace
void SpinLock::Lock() { void SpinLock::Lock() {
if (!impl.initialized) [[unlikely]] { std::call_once(flag, &SpinLockImpl::Initialize, impl);
impl.Initialize();
}
impl.lock(&storage); impl.lock(&storage);
} }
void SpinLock::Unlock() { void SpinLock::Unlock() {
if (!impl.initialized) [[unlikely]] { std::call_once(flag, &SpinLockImpl::Initialize, impl);
impl.Initialize();
}
impl.unlock(&storage); impl.unlock(&storage);
} }