common: Defer spin-lock initialization.
This commit is contained in:
parent
494fbee05b
commit
39c59b6c46
2 changed files with 27 additions and 3 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue