コード例 #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::Unlock()
{
	//assert((fOwner == (sWORD)VTask::GetCurrentID()) && (fUseCount > 0) && (fUseCount < 32000L));

	assert(fUseCount > 0);
	VSyncEvent*	event = NULL;

	VInterlocked::Increment(&sUnlockCount);

	// Unlock or another successfull lock can only be called from same thead (so no contention can occur on fUseCount)
	if (--fUseCount == 0)
	{
		// capture currently set event
		event = VInterlocked::ExchangePtr(&fEvent);
		VTaskID owner = VInterlocked::Exchange((sLONG*) &fOwner, (sLONG) 0);
		//assert(owner == VTask::GetCurrentID());

		if (event != NULL)
		{
			event->Unlock();
			event->Release();
		}
	}
	return true;
}
コード例 #3
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;
}
コード例 #4
0
Boolean VNonVirtualCriticalSection::Unlock()
{
	assert((fOwner == VTask::GetCurrentID()) && (fUseCount > 0) && (fUseCount < 32000L));

	//assert(fUseCount > 0);
	VSyncEvent*	event = NULL;

	VInterlocked::Increment(&sUnlockCount);

	if (--fUseCount == 0)
	{
		event = VInterlocked::ExchangePtr(&fEvent);
		VTaskID	owner = VInterlocked::Exchange((sLONG*) &fOwner, (sLONG) NULL_TASK_ID);
		//assert(owner == VTask::GetCurrentID());

		if (event != NULL)
		{
			event->Unlock();
			event->Release();
		}
	}
	
	return true;
}