Example #1
0
BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags)
{
	/**
	 * See http://msdn.microsoft.com/en-us/library/ff541979(v=vs.85).aspx
	 * - The LockCount field indicates the number of times that any thread has
	 *   called the EnterCriticalSection routine for this critical section,
	 *   minus one. This field starts at -1 for an unlocked critical section.
	 *   Each call of EnterCriticalSection increments this value; each call of
	 *   LeaveCriticalSection decrements it.
	 * - The RecursionCount field indicates the number of times that the owning
	 *   thread has called EnterCriticalSection for this critical section.
	 */
	if (Flags != 0)
	{
		WLog_WARN(TAG, "Flags unimplemented");
	}

	lpCriticalSection->DebugInfo = NULL;
	lpCriticalSection->LockCount = -1;
	lpCriticalSection->SpinCount = 0;
	lpCriticalSection->RecursionCount = 0;
	lpCriticalSection->OwningThread = NULL;
	lpCriticalSection->LockSemaphore = (winpr_sem_t*) malloc(sizeof(winpr_sem_t));
#if defined(__APPLE__)
	semaphore_create(mach_task_self(), lpCriticalSection->LockSemaphore, SYNC_POLICY_FIFO, 0);
#else
	sem_init(lpCriticalSection->LockSemaphore, 0, 0);
#endif
	SetCriticalSectionSpinCount(lpCriticalSection, dwSpinCount);
	return TRUE;
}
Example #2
0
    void mutex::set_spin_count(unsigned int count)
    {
        void *p = m_buf;
        CRITICAL_SECTION &m_cs = *static_cast<CRITICAL_SECTION *>(p);

        SetCriticalSectionSpinCount(&m_cs, count);
    }
Example #3
0
STDMETHODIMP DHCrst::SetSpinCount(DWORD dwSpinCount)
{
    _ASSERTE(m_pCrst && "Expected a non-null critical section here");

    SetCriticalSectionSpinCount(m_pCrst, dwSpinCount);
    // TODO: retval transformation

    return S_OK;
}
Example #4
0
	void set_spin_count(DWORD dwSpinCount)
	{
		SetCriticalSectionSpinCount(&cs, dwSpinCount);
	}
Example #5
0
static PVOID TestSynchCritical_Main(PVOID arg)
{
	int i, j;
	SYSTEM_INFO sysinfo;
	DWORD dwPreviousSpinCount;
	DWORD dwSpinCount;
	DWORD dwSpinCountExpected;
	HANDLE hMainThread;
	HANDLE* hThreads;
	HANDLE hThread;
	DWORD dwThreadCount;
	DWORD dwThreadExitCode;
	BOOL bTest1Running;

	PBOOL pbThreadTerminated = (PBOOL)arg;

	GetNativeSystemInfo(&sysinfo);

	hMainThread = (HANDLE) (ULONG_PTR) GetCurrentThreadId();

	/**
	 * Test SpinCount in SetCriticalSectionSpinCount, InitializeCriticalSectionEx and InitializeCriticalSectionAndSpinCount
	 * SpinCount must be forced to be zero on on uniprocessor systems and on systems
	 * where WINPR_CRITICAL_SECTION_DISABLE_SPINCOUNT is defined
	 */

	dwSpinCount = 100;
	InitializeCriticalSectionEx(&critical, dwSpinCount, 0);
	while(--dwSpinCount)
	{
		dwPreviousSpinCount = SetCriticalSectionSpinCount(&critical, dwSpinCount);
		dwSpinCountExpected = 0;
#if !defined(WINPR_CRITICAL_SECTION_DISABLE_SPINCOUNT)
		if (sysinfo.dwNumberOfProcessors > 1)
			dwSpinCountExpected = dwSpinCount+1;
#endif
		if (dwPreviousSpinCount != dwSpinCountExpected)
		{
			printf("CriticalSection failure: SetCriticalSectionSpinCount returned %u (expected: %u)\n", dwPreviousSpinCount, dwSpinCountExpected);
			goto fail;
		}

		DeleteCriticalSection(&critical);

		if (dwSpinCount%2==0)
			InitializeCriticalSectionAndSpinCount(&critical, dwSpinCount);
		else
			InitializeCriticalSectionEx(&critical, dwSpinCount, 0);
	}
	DeleteCriticalSection(&critical);


	/**
	 * Test single-threaded recursive TryEnterCriticalSection/EnterCriticalSection/LeaveCriticalSection
	 *
	 */

	InitializeCriticalSection(&critical);

	for (i = 0; i < 1000; i++)
	{
		if (critical.RecursionCount != i)
		{
			printf("CriticalSection failure: RecursionCount field is %d instead of %d.\n", critical.RecursionCount, i);
			goto fail;
		}
		if (i%2==0)
		{
			EnterCriticalSection(&critical);
		}
		else
		{
			if (TryEnterCriticalSection(&critical) == FALSE)
			{
				printf("CriticalSection failure: TryEnterCriticalSection failed where it should not.\n");
				goto fail;
			}
		}
		if (critical.OwningThread != hMainThread)
		{
			printf("CriticalSection failure: Could not verify section ownership (loop index=%d).\n", i);
			goto fail;
		}
	}
	while (--i >= 0)
	{
		LeaveCriticalSection(&critical);
		if (critical.RecursionCount != i)
		{
			printf("CriticalSection failure: RecursionCount field is %d instead of %d.\n", critical.RecursionCount, i);
			goto fail;
		}
		if (critical.OwningThread != (HANDLE)(i ? hMainThread : NULL))
		{
			printf("CriticalSection failure: Could not verify section ownership (loop index=%d).\n", i);
			goto fail;
		}
	}
	DeleteCriticalSection(&critical);


	/**
	 * Test using multiple threads modifying the same value
	 */

	dwThreadCount = sysinfo.dwNumberOfProcessors > 1 ? sysinfo.dwNumberOfProcessors : 2;

	hThreads = (HANDLE*) calloc(dwThreadCount, sizeof(HANDLE));
	if (!hThreads)
	{
		printf("Problem allocating memory\n");
		goto fail;
	}

	for (j = 0; j < TEST_SYNC_CRITICAL_TEST1_RUNS; j++)
	{
		dwSpinCount = j * 1000;
		InitializeCriticalSectionAndSpinCount(&critical, dwSpinCount);

		gTestValueVulnerable = 0;
		gTestValueSerialized = 0;

		/* the TestSynchCritical_Test1 threads shall run until bTest1Running is FALSE */
		bTest1Running = TRUE;
		for (i = 0; i < (int) dwThreadCount; i++) {
			hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TestSynchCritical_Test1, &bTest1Running, 0, NULL);
		}

		/* let it run for TEST_SYNC_CRITICAL_TEST1_RUNTIME_MS ... */
		Sleep(TEST_SYNC_CRITICAL_TEST1_RUNTIME_MS);
		bTest1Running = FALSE;

		for (i = 0; i < (int) dwThreadCount; i++)
		{
			if (WaitForSingleObject(hThreads[i], INFINITE) != WAIT_OBJECT_0)
			{
				printf("CriticalSection failure: Failed to wait for thread #%d\n", i);
				goto fail;
			}
			GetExitCodeThread(hThreads[i], &dwThreadExitCode);
			if(dwThreadExitCode != 0)
			{
				printf("CriticalSection failure: Thread #%d returned error code %u\n", i, dwThreadExitCode);
				goto fail;
			}
			CloseHandle(hThreads[i]);
		}

		if (gTestValueVulnerable != gTestValueSerialized)
		{
			printf("CriticalSection failure: unexpected test value %d (expected %d)\n", gTestValueVulnerable, gTestValueSerialized);
			goto fail;
		}

		DeleteCriticalSection(&critical);
	}

	free(hThreads);


	/**
	 * TryEnterCriticalSection in thread must fail if we hold the lock in the main thread
	 */

	InitializeCriticalSection(&critical);

	if (TryEnterCriticalSection(&critical) == FALSE)
	{
		printf("CriticalSection failure: TryEnterCriticalSection unexpectedly failed.\n");
		goto fail;
	}
	/* This thread tries to call TryEnterCriticalSection which must fail */
	hThread = CreateThread(NULL, 0,  (LPTHREAD_START_ROUTINE) TestSynchCritical_Test2, NULL, 0, NULL);
	if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0)
	{
		printf("CriticalSection failure: Failed to wait for thread\n");
		goto fail;
	}
	GetExitCodeThread(hThread, &dwThreadExitCode);
	if(dwThreadExitCode != 0)
	{
		printf("CriticalSection failure: Thread returned error code %u\n", dwThreadExitCode);
		goto fail;
	}
	CloseHandle(hThread);

	*pbThreadTerminated = TRUE; /* requ. for winpr issue, see below */
	return (PVOID)0;

fail:
	*pbThreadTerminated = TRUE; /* requ. for winpr issue, see below */
	return (PVOID)1;
}
Example #6
0
PLuint SyncObject::SetSpinCount(PLuint spin_count)
{
	return SetCriticalSectionSpinCount(&csCriticalSection, spin_count);
}
Example #7
0
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
	switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:

#if _M_X64
			gDebugLog = GlobalAllocator.New<CDebugLog>("AeonProfiler64.log");
#else
			gDebugLog = GlobalAllocator.New<CDebugLog>("AeonProfiler32.log");
#endif

			DebugLog("***** DLL_PROCESS_ATTACH *****");

			ModuleHandle = hModule;
			ApplicationProcessId = GetCurrentProcessId();
			ApplicationThreadId = GetCurrentThreadId();

			InitializeCriticalSection(&gCriticalSection);
			SetCriticalSectionSpinCount(&gCriticalSection, 4000);  // 4000 is what the Windows heap manager uses (https://msdn.microsoft.com/en-us/library/windows/desktop/ms686197%28v=vs.85%29.aspx)

			DWORD64 Counter_Freq, Counter_Before, Counter_After;
			DWORD64 RDTSC_Before, RDTSC_After;

			QueryPerformanceFrequency((LARGE_INTEGER*)&Counter_Freq);
			QueryPerformanceCounter((LARGE_INTEGER*)&Counter_Before);
			RDTSC_Before = __rdtsc();
			Sleep(1000);
			RDTSC_After = __rdtsc();
			QueryPerformanceCounter((LARGE_INTEGER*)&Counter_After);

			ClockFreq = Counter_Freq * (RDTSC_After - RDTSC_Before) / (Counter_After - Counter_Before);
			TicksPerHundredNanoseconds = (int)(ClockFreq / 10000000);

			DialogCallTreeThreadId = ApplicationThreadId;  // get the current thread id (this should be "main()" or "WinMain()")

			// Get the process name that's loading us
			GetModuleFileName( GetModuleHandle( NULL ), app_filename, _countof(app_filename) );

			DebugLog("Application: %s", app_filename);

			DialogThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DialogThread, NULL, 0, &DialogThreadID);

			bTrackCallerData = true;

			break;

		case DLL_PROCESS_DETACH:

			bTrackCallerData = false;

			DebugLog("***** DLL_PROCESS_DETACH *****");

			HandleExit();

			if( DialogThreadHandle )
			{
				if (WaitForSingleObject(DialogThreadHandle, INFINITE) == WAIT_TIMEOUT)
				{
					TerminateThread(DialogThreadHandle, 0);
				}

				CloseHandle(DialogThreadHandle);
			}

			DeleteCriticalSection(&gCriticalSection);

			if( gDebugLog )
			{
				gDebugLog->~CDebugLog();
				gDebugLog = nullptr;
			}

			break;
	}

	return TRUE;
}