diff options
Diffstat (limited to 'src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange/test2')
-rw-r--r-- | src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange/test2/CMakeLists.txt | 19 | ||||
-rw-r--r-- | src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange/test2/test.cpp | 168 |
2 files changed, 187 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange/test2/CMakeLists.txt new file mode 100644 index 0000000000..038d375273 --- /dev/null +++ b/src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange/test2/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + test.cpp +) + +add_executable(paltest_interlockedcompareexchange_test2 + ${SOURCES} +) + +add_dependencies(paltest_interlockedcompareexchange_test2 coreclrpal) + +target_link_libraries(paltest_interlockedcompareexchange_test2 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange/test2/test.cpp b/src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange/test2/test.cpp new file mode 100644 index 0000000000..902f626d47 --- /dev/null +++ b/src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange/test2/test.cpp @@ -0,0 +1,168 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** Source : test.c +** +** Purpose: Test for InterlockedCompareExchange() function using multiple threads +** +** +**=========================================================*/ + + + +#include <palsuite.h> + +#define MAX_THREADS 10 +#define REPEAT_COUNT 10 + +//Global Variable Declaration +LONG g_Total = 0; +LONG Lock=0; + + +void ModifyGlobalResource(void); +void AcquireLock(PLONG pLock); +void ReleaseLock(PLONG pLock); + + + +//Main entry point of the program +int __cdecl main(int argc, char *argv[]) { + + int i = 0; + DWORD dwThreadID=0; + LONG totalOperations = 0; + + HANDLE hThread[MAX_THREADS]; + + /* + * Initialize the PAL and return FAILURE if this fails + */ + + if(0 != (PAL_Initialize(argc, argv))) + { + return FAIL; + } + + + totalOperations = MAX_THREADS * REPEAT_COUNT; + + + //Create MAX_THREADS threads that will operate on the global counter + for (i=0;i<MAX_THREADS;i++) + { + hThread[i] = CreateThread( + NULL, // default security attributes + 0, // use default stack size + (LPTHREAD_START_ROUTINE) ModifyGlobalResource, // thread function + NULL, // argument to thread function + 0, // use default creation flags + &dwThreadID); // returns the thread identifier + + // Check the return value for success. + + if (hThread[i] == NULL) + { + Fail("ERROR: Was not able to create thread\n" + "GetLastError returned %d\n", GetLastError()); + } + + } + + + //Wait for all threads to finish + for (i=0;i<MAX_THREADS;i++) + { + + if (WAIT_OBJECT_0 != WaitForSingleObject (hThread[i], INFINITE)) + { + Fail ("Main: Wait for Single Object failed. Failing test.\n" + "GetLastError returned %d\n", GetLastError()); + } + + } + + + if (0!= g_Total) + { + Fail("Test Failed \n"); + } + + Trace("Global Counter Value at the end of the test %d \n", g_Total); + + /* + * Terminate PAL + */ + + PAL_Terminate(); + return PASS; +} + + +void ModifyGlobalResource(void) +{ + + int i =0; + + for (i=0;i<REPEAT_COUNT;i++) + { + + /* + Acquire Lock Provides Synchronization Around g_Total global variable + */ + + AcquireLock(&Lock); + + /* + The following set of operations is gauranteed to be atomic by virtue of the fact + that InterLockedCompareExchange was able to gaurantee that the compare + and exchange operation on pLock was thread safe. If the same set of code was + executed without using InterlockedCompareExchange the code would fail most of + time. + + */ + g_Total++; + Sleep(100); + g_Total--; + if (0!=g_Total) + { + Fail("Test Failed beacuse g_Total was not protected \n"); + } + + + /* + Acquire Lock releases the lock around g_Total Global variable + */ + + ReleaseLock(&Lock); + } + + +} + + +void AcquireLock(PLONG pLock) +{ + //Spin Lock implemented with the help of InterlockedCompareExchange + + + while(1) + { + if (InterlockedCompareExchange(pLock,1,0)==0) + break; + } + +} + + +void ReleaseLock(PLONG pLock) +{ + + + MemoryBarrier(); + *pLock = 0; +} + |