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

View file

@ -34,16 +34,18 @@ void EmitSpinLockUnlock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg
namespace { namespace {
struct SpinLockImpl { struct SpinLockImpl {
SpinLockImpl(); void Initialize();
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*);
}; };
SpinLockImpl impl; SpinLockImpl impl;
SpinLockImpl::SpinLockImpl() { void SpinLockImpl::Initialize() {
const Xbyak::Reg64 ABI_PARAM1 = Backend::X64::HostLocToReg64(Backend::X64::ABI_PARAM1); const Xbyak::Reg64 ABI_PARAM1 = Backend::X64::HostLocToReg64(Backend::X64::ABI_PARAM1);
code.align(); code.align();
@ -55,15 +57,23 @@ SpinLockImpl::SpinLockImpl() {
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]] {
impl.Initialize();
}
impl.lock(&storage); impl.lock(&storage);
} }
void SpinLock::Unlock() { void SpinLock::Unlock() {
if (!impl.initialized) [[unlikely]] {
impl.Initialize();
}
impl.unlock(&storage); impl.unlock(&storage);
} }