Ejemplo n.º 1
0
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;
	}
}
Ejemplo n.º 2
0
// 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;
}
Ejemplo n.º 3
0
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;
	}
}