Status ModuleShutdown(volatile ModuleInitState* initState, void (*shutdown)()) { for(;;) { if(cpu_CAS(initState, INITIALIZED, BUSY)) { shutdown(); *initState = UNINITIALIZED; COMPILER_FENCE; return INFO::OK; } const ModuleInitState latchedInitState = *initState; if(latchedInitState == INITIALIZED || latchedInitState == BUSY) { cpu_Pause(); continue; } if(latchedInitState == UNINITIALIZED) return INFO::SKIPPED; ENSURE(latchedInitState < 0); return (Status)latchedInitState; } }
// NB: callers should skip this if *idxDeleterOut != 0 (avoids the overhead // of an unnecessary indirect function call) void RegisterUniqueRangeDeleter(UniqueRangeDeleter deleter, volatile IdxDeleter* idxDeleterOut) { ENSURE(deleter); if(!cpu_CAS(idxDeleterOut, idxDeleterNone, -1)) // not the first call for this deleter { // wait until an index has been assigned while(*idxDeleterOut <= 0) cpu_Pause(); return; } const IdxDeleter idxDeleter = cpu_AtomicAdd(&numDeleters, 1); ENSURE(idxDeleter < (IdxDeleter)ARRAY_SIZE(deleters)); deleters[idxDeleter] = deleter; COMPILER_FENCE; *idxDeleterOut = idxDeleter; }
Status ModuleInit(volatile ModuleInitState* initState, Status (*init)()) { for(;;) { if(cpu_CAS(initState, UNINITIALIZED, BUSY)) { Status ret = init(); *initState = (ret == INFO::OK)? INITIALIZED : ret; COMPILER_FENCE; return ret; } const ModuleInitState latchedInitState = *initState; if(latchedInitState == UNINITIALIZED || latchedInitState == BUSY) { cpu_Pause(); continue; } ENSURE(latchedInitState == INITIALIZED || latchedInitState < 0); return (Status)latchedInitState; } }