コード例 #1
0
Boolean VNonVirtualCriticalSection::Lock()
{

	VTaskID currentTaskID = VTask::GetCurrentID();
	do {

		VTaskID owner = (VTaskID) VInterlocked::CompareExchange((sLONG*) &fOwner, (sLONG) NULL_TASK_ID, (sLONG) currentTaskID);
		if (owner == NULL_TASK_ID)
		{
			assert(fUseCount == 0);
			fUseCount = 1;
		}
		else if (fOwner == currentTaskID)
		{
			++fUseCount;
		}
		else
		{
			sLONG	unlockCount = sUnlockCount;

			VSyncEvent*	event = VInterlocked::ExchangePtr( &fEvent);
			if (event != NULL)
			{
				event->Retain();
				if (VInterlocked::CompareExchangePtr((void **)&fEvent, NULL, event) != NULL)
				{
					event->Unlock();
					event->Release();
					VTask::YieldNow();
				}
				else
				{
					while (VInterlocked::CompareExchange(&sUnlockCount, sUnlockCount, sUnlockCount) != sUnlockCount)
						VTask::YieldNow();

					if (sUnlockCount == unlockCount)
						event->Lock( 100);
					else
						VTask::YieldNow();
				}
				event->Release();
			}
			else
			{
				event = new VSyncEvent;

				if (VInterlocked::CompareExchangePtr((void **)&fEvent, NULL, event) != NULL)
				{
					event->Unlock();
					event->Release();
					VTask::YieldNow();
				}
			}
		}

	} while(fOwner != currentTaskID);
	
	return true;
}
コード例 #2
0
Boolean VSmallCriticalSection::Lock()
{
	sWORD	currentTaskID = (sWORD)VTask::GetCurrentID();
	LongAsDoubleWord	doubleWord;

	doubleWord.first = (sWORD)currentTaskID;
	doubleWord.second = 0;

	do {

		sLONG owner = VInterlocked::CompareExchange((sLONG*) &fOwner, (sLONG) 0, *((sLONG*) &doubleWord));
		if (owner == 0)
		{
			assert(fUseCount == 0);
			fUseCount = 1;
		}
		else if (fOwner == currentTaskID)
		{
			++fUseCount;
		}
		else
		{
			sLONG	unlockCount = sUnlockCount;
			VSyncEvent* event = VInterlocked::ExchangePtr(&fEvent);
			if (event != NULL)
			{
				event->Retain();

				if (VInterlocked::CompareExchangePtr((void**)&fEvent, NULL, event) != NULL)
				{
					event->Unlock();
					VTask::YieldNow();
				}
				else
				{
					if (sUnlockCount == unlockCount)
						event->Lock(100);
					else
						VTask::YieldNow();
				}
				
				event->Release();
			}
			else
			{
				event = new VSyncEvent;

				if (VInterlocked::CompareExchangePtr((void**)&fEvent, NULL, event) != NULL)
				{
					event->Release();
					VTask::YieldNow();
				}
			}
		}
	} while (fOwner != currentTaskID);
	
	return true;
}