common: Defer spin-lock initialization.

This commit is contained in:
Steveice10 2023-04-20 19:02:44 -07:00 committed by merry
parent 494fbee05b
commit 39c59b6c46
2 changed files with 27 additions and 3 deletions

View file

@ -38,8 +38,12 @@ namespace {
struct SpinLockImpl {
SpinLockImpl();
void Initialize();
oaknut::CodeBlock mem;
oaknut::CodeGenerator code;
bool initialized = false;
void (*lock)(volatile int*);
void (*unlock)(volatile int*);
};
@ -48,7 +52,9 @@ SpinLockImpl impl;
SpinLockImpl::SpinLockImpl()
: mem{4096}
, code{mem.ptr()} {
, code{mem.ptr()} {}
void SpinLockImpl::Initialize() {
mem.unprotect();
lock = code.ptr<void (*)(volatile int*)>();
@ -60,15 +66,23 @@ SpinLockImpl::SpinLockImpl()
code.RET();
mem.protect();
initialized = true;
}
} // namespace
void SpinLock::Lock() {
if (!impl.initialized) [[unlikely]] {
impl.Initialize();
}
impl.lock(&storage);
}
void SpinLock::Unlock() {
if (!impl.initialized) [[unlikely]] {
impl.Initialize();
}
impl.unlock(&storage);
}

View file

@ -34,16 +34,18 @@ void EmitSpinLockUnlock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg
namespace {
struct SpinLockImpl {
SpinLockImpl();
void Initialize();
Xbyak::CodeGenerator code;
bool initialized = false;
void (*lock)(volatile int*);
void (*unlock)(volatile int*);
};
SpinLockImpl impl;
SpinLockImpl::SpinLockImpl() {
void SpinLockImpl::Initialize() {
const Xbyak::Reg64 ABI_PARAM1 = Backend::X64::HostLocToReg64(Backend::X64::ABI_PARAM1);
code.align();
@ -55,15 +57,23 @@ SpinLockImpl::SpinLockImpl() {
unlock = code.getCurr<void (*)(volatile int*)>();
EmitSpinLockUnlock(code, ABI_PARAM1, code.eax);
code.ret();
initialized = true;
}
} // namespace
void SpinLock::Lock() {
if (!impl.initialized) [[unlikely]] {
impl.Initialize();
}
impl.lock(&storage);
}
void SpinLock::Unlock() {
if (!impl.initialized) [[unlikely]] {
impl.Initialize();
}
impl.unlock(&storage);
}