Or you could use atomic swaps on the initialized bit. That's both cheaper and simpler.
psuedocode:
member atomic32 init
member mutex lock
member obj ptr
membarrier()
if (atomic_load(&init)) {
return ptr
} else {
locked_init()
atomic_save(&init, 1)
membarrier()
}
Not an expert, use this at your own risk.