diff options
Diffstat (limited to 'src/pal/tests/palsuite/threading/TLS')
19 files changed, 977 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/threading/TLS/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/CMakeLists.txt new file mode 100644 index 0000000000..bffdf7f714 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +add_subdirectory(test1) +add_subdirectory(test2) +add_subdirectory(test3) +add_subdirectory(test4) +add_subdirectory(test5) + + diff --git a/src/pal/tests/palsuite/threading/TLS/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test1/CMakeLists.txt new file mode 100644 index 0000000000..ff1a866eb9 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test1/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + TLS.c +) + +add_executable(paltest_tls_test1 + ${SOURCES} +) + +add_dependencies(paltest_tls_test1 coreclrpal) + +target_link_libraries(paltest_tls_test1 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/TLS/test1/TLS.c b/src/pal/tests/palsuite/threading/TLS/test1/TLS.c new file mode 100644 index 0000000000..4300c3f98b --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test1/TLS.c @@ -0,0 +1,182 @@ +// 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: tls.c +** +** Purpose: Test to ensure TlsAlloc, TlsGetValue, TlsSetValue +** and TlsFree are working properly together. +** +** Dependencies: PAL_Initialize +** Fail +** Sleep +** LocalAlloc +** LocalFree +** WaitForSingleObject +** CreateThread +** GetLastError +** + +** +**===========================================================================*/ +#include <palsuite.h> + +#define NUM_OF_THREADS 10 + +DWORD dwTlsIndex; /* TLS index */ + +/** + * CommonFunction + * + * Helper function that calls TlsGetValue + */ +VOID CommonFunction(VOID) +{ + LPVOID lpvData; + DWORD dwError; + + /* Retrieve a data pointer for the current thread. */ + lpvData = TlsGetValue(dwTlsIndex); + + if ( (lpvData == 0) && + ((dwError = GetLastError()) != NO_ERROR) ) + {/*ERROR */ + Fail("TlsGetValue(%d) returned 0 with error %d\n", + dwTlsIndex, + dwError); + } + + Sleep(5000); +} + +/** + * ThreadFunc + * + * Thread function that stores a value in the thread's tls slot + * for the predefined tls index + */ +DWORD PALAPI ThreadFunc(LPVOID lpThreadParameter) +{ + LPVOID lpvData; + DWORD dwError; + + /* Initialize the TLS index for this thread.*/ + lpvData = (LPVOID) LocalAlloc(0, 256); + + if( lpvData == NULL ) + {/*ERROR */ + dwError = GetLastError(); + Fail("Unexpected LocalAlloc(0, 256) failure with error %d\n", + dwError); + } + + + if ( TlsSetValue(dwTlsIndex, lpvData) == 0 ) + {/*ERROR */ + dwError = GetLastError(); + Fail("TlsSetValue(%d, %x) returned 0 with error %d\n", + dwTlsIndex, + lpvData, + dwError); + } + + CommonFunction(); + + /* Release the dynamic memory. */ + lpvData = TlsGetValue(dwTlsIndex); + + if ( (lpvData == 0) && + ((dwError = GetLastError()) != NO_ERROR) ) + {/*ERROR */ + Fail("TlsGetValue(%d) returned 0 with error %d\n", + dwTlsIndex, + dwError); + } + else + { + if( LocalFree((HLOCAL) lpvData) != NULL ) + { + dwError = GetLastError(); + Fail("Unexpected LocalFree(%x) failure with error %d\n", + lpvData, + dwError); + } + } + + return PASS; +} + +/** + * main + * + * executable entry point + */ +INT __cdecl main( INT argc, CHAR **argv ) +{ + DWORD IDThread; + HANDLE hThread[NUM_OF_THREADS]; + int i; + + /*PAL initialization */ + if( (PAL_Initialize(argc, argv)) != 0 ) + { + return FAIL; + } + + /*Allocate a TLS index. */ + if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) + {/*RROR*/ + DWORD dwError = GetLastError(); + Fail("TlsAlloc() returned error %d\n", + dwError); + } + + /*Create multiple threads.*/ + + for (i = 0; i < NUM_OF_THREADS; i++) + { + hThread[i] = CreateThread(NULL, /* no security attributes*/ + 0, /* use default stack size */ + ThreadFunc, /* thread function */ + NULL, /* no thread function argument */ + 0, /* use default creation flags */ + &IDThread); /* returns thread identifier */ + + /* Check the return value for success. */ + if (hThread[i] == NULL) + {/* ERROR */ + DWORD dwError = GetLastError(); + Fail("Unexpected CreateThread error %d\n", + dwError); + } + } + + /* Wait for all threads to finish */ + for (i = 0; i < NUM_OF_THREADS; i++) + { + DWORD dwRet; + + dwRet = WaitForSingleObject(hThread[i], INFINITE); + + if( dwRet == WAIT_FAILED ) + {/* ERROR */ + DWORD dwError = GetLastError(); + Fail("Unexpected WaitForSingleObject error %d\n", + dwError); + } + } + + /* Release the TLS index */ + if( TlsFree( dwTlsIndex ) == 0 ) + {/* ERROR */ + DWORD dwError = GetLastError(); + Fail("TlsFree() returned 0 with error %d\n", + dwError); + } + + PAL_Terminate(); + return PASS; +} + diff --git a/src/pal/tests/palsuite/threading/TLS/test1/testinfo.dat b/src/pal/tests/palsuite/threading/TLS/test1/testinfo.dat new file mode 100644 index 0000000000..544e391266 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test1/testinfo.dat @@ -0,0 +1,13 @@ +# 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. + +Version = 1.0 +Section = threading +Function = TLS +Name = Test for TlsAlloc, TlsGetValue, TlsSetValue and TlsFree +TYPE = DEFAULT +EXE1 = tls +Description += Test to ensure TlsAlloc, TlsGetValue, TlsSetValue += and TlsFree are working properly together. diff --git a/src/pal/tests/palsuite/threading/TLS/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test2/CMakeLists.txt new file mode 100644 index 0000000000..5afe82b4a6 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test2/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + TLS.c +) + +add_executable(paltest_tls_test2 + ${SOURCES} +) + +add_dependencies(paltest_tls_test2 coreclrpal) + +target_link_libraries(paltest_tls_test2 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/TLS/test2/TLS.c b/src/pal/tests/palsuite/threading/TLS/test2/TLS.c new file mode 100644 index 0000000000..96a6011f96 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test2/TLS.c @@ -0,0 +1,66 @@ +// 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: tls.c +** +** Purpose: Test to ensure TlsAlloc and TlsFree are working when we try +** to allocate the guaranted minimum number of indicies. +** + +** +**===========================================================================*/ +#include <palsuite.h> + +#define NUM_OF_INDEX 64 +/* Minimum guaranteed is at least 64 for all systems.*/ + +/** + * main + * + * executable entry point + */ +INT __cdecl main( INT argc, CHAR **argv ) +{ + DWORD dwIndexes[NUM_OF_INDEX]; + int i,j; + + /* PAL initialization */ + if( (PAL_Initialize(argc, argv)) != 0 ) + { + return FAIL; + } + + /* Allocate a bunch of TLS indexes. */ + for( i = 0; i < NUM_OF_INDEX; i++ ) + { + if( (dwIndexes[i] = TlsAlloc()) == TLS_OUT_OF_INDEXES ) + {/*ERROR */ + DWORD dwError = GetLastError(); + Fail("TlsAlloc() returned -1 with error %d" + "when trying to allocate %d index\n", + dwError, + i); + } + } + + /* Free the TLS indexes.*/ + for( j = 0; j < NUM_OF_INDEX; j++ ) + { + if( TlsFree(dwIndexes[j]) == 0 ) + {/* ERROR */ + DWORD dwError = GetLastError(); + Fail("TlsFree() returned 0 with error %d" + "when trying to free %d index\n", + dwError, + i); + } + } + + PAL_Terminate(); + + return PASS; +} + diff --git a/src/pal/tests/palsuite/threading/TLS/test2/testinfo.dat b/src/pal/tests/palsuite/threading/TLS/test2/testinfo.dat new file mode 100644 index 0000000000..3a672a5f38 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test2/testinfo.dat @@ -0,0 +1,13 @@ +# 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. + +Version = 1.0 +Section = threading +Function = TLS +Name = Test for TlsAlloc and TlsFree +TYPE = DEFAULT +EXE1 = tls +Description += Test to ensure TlsAlloc and TlsFree are working when we try += to allocate the guaranted minimum number of index. diff --git a/src/pal/tests/palsuite/threading/TLS/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test3/CMakeLists.txt new file mode 100644 index 0000000000..0964d33d2c --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test3/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + TLS.c +) + +add_executable(paltest_tls_test3 + ${SOURCES} +) + +add_dependencies(paltest_tls_test3 coreclrpal) + +target_link_libraries(paltest_tls_test3 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/TLS/test3/TLS.c b/src/pal/tests/palsuite/threading/TLS/test3/TLS.c new file mode 100644 index 0000000000..4acaef5020 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test3/TLS.c @@ -0,0 +1,90 @@ +// 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: tls.c +** +** Purpose: Test to ensure TlsGetValue, TlsSetValue and TlsFree +** are not working with an invalid index +** +** Dependencies: PAL_Initialize +** PAL_Terminate +** LocalAlloc +** LocalFree +** + +** +**===========================================================================*/ +#include <palsuite.h> + +DWORD dwTlsIndex; /* TLS index */ + +/** + * main + * + * executable entry point + */ +INT __cdecl main( INT argc, CHAR **argv ) +{ + CHAR lpstrData[256] = ""; + LPVOID lpvData = NULL; + BOOL bRet; + + /* PAL initialization */ + if( (PAL_Initialize(argc, argv)) != 0 ) + { + return FAIL; + } + + /* Invalid TLS index */ + dwTlsIndex = -1; + + /* + * Set some data in the invalid TLS index + *Should return 0 and an error + */ + bRet = TlsSetValue(dwTlsIndex, (LPVOID)lpstrData); + + if ( bRet != 0) + {/*ERROR */ + Fail("TlsSetValue(%d, %x) returned %d " + "when it should have returned 0 and an error\n", + dwTlsIndex, + lpvData, + bRet); + } + + /* + * Get the data at the invalid index + * Should return 0 and an error + */ + lpvData = TlsGetValue(dwTlsIndex); + + if ( lpvData != 0 ) + {/* ERROR */ + Fail("TlsGetValue(%d) returned %d " + "when it should have returned 0 and an error\n", + dwTlsIndex, + lpvData); + } + + /* + * Release the invalid TLS index + * Should return 0 and an error + */ + bRet = TlsFree( dwTlsIndex ); + + if( bRet != 0 ) + {/* ERROR */ + Fail("TlsFree() returned %d " + "when it should have returned 0 and an error\n", + bRet); + } + + PAL_Terminate(); + return PASS; +} + + diff --git a/src/pal/tests/palsuite/threading/TLS/test3/testinfo.dat b/src/pal/tests/palsuite/threading/TLS/test3/testinfo.dat new file mode 100644 index 0000000000..63ce59f351 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test3/testinfo.dat @@ -0,0 +1,13 @@ +# 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. + +Version = 1.0 +Section = threading +Function = TLS +Name = TlsGetValue, TlsSetValue and TlsFree +TYPE = DEFAULT +EXE1 = tls +Description += Test to ensure TlsGetValue, TlsSetValue and TlsFree += are not working with an invalid index diff --git a/src/pal/tests/palsuite/threading/TLS/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test4/CMakeLists.txt new file mode 100644 index 0000000000..7e7b47786a --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test4/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + test4.c +) + +add_executable(paltest_tls_test4 + ${SOURCES} +) + +add_dependencies(paltest_tls_test4 coreclrpal) + +target_link_libraries(paltest_tls_test4 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/TLS/test4/test4.c b/src/pal/tests/palsuite/threading/TLS/test4/test4.c new file mode 100644 index 0000000000..8c3603cdb0 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test4/test4.c @@ -0,0 +1,137 @@ +// 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: test4.c (threading/tls) +** +** Purpose: Test to ensure that upon key creation, the value NULL +** is associated with the new key in all active threads. +** Upon thread creation, the value NULL is associated +** with all defined keys in the new thread. +** +** Dependencies: PAL_Initialize +** PAL_Terminate +** LocalAlloc +** LocalFree +** + +** +**===========================================================================*/ +#include <palsuite.h> + +#define NUM_OF_THREADS 10 + +DWORD dwTlsIndex; /* TLS index */ + +/** + * ThreadFunc + * + * Thread function that checks that NULL is associated with the tls index + */ +DWORD PALAPI ThreadFunc(VOID) +{ + LPVOID lpvData; + DWORD dwError; + + /* Retrieve a data pointer for the current thread. + The return value should be NULL since no data has been + set in the index */ + lpvData = TlsGetValue(dwTlsIndex); + + if ( (lpvData != NULL) && + ((dwError = GetLastError()) == NO_ERROR) ) + {/*ERROR */ + Fail("TlsGetValue(%d) returned data " + "even if no data was associated with the index\n", + dwTlsIndex); + } + + return PASS; +} + +/** + * main + * + * executable entry point + */ +INT __cdecl main( INT argc, CHAR **argv ) +{ + DWORD IDThread; + LPVOID lpvData; + DWORD dwError; + HANDLE hThread[NUM_OF_THREADS]; + int i; + + /*PAL initialization */ + if( (PAL_Initialize(argc, argv)) != 0 ) + { + return FAIL; + } + + /*Allocate a TLS index. */ + if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) + {/*ERROR*/ + DWORD dwError = GetLastError(); + Fail("TlsAlloc() returned error %d\n", + dwError); + } + + /*Check that the value associated with the tls index is NULL*/ + lpvData = TlsGetValue(dwTlsIndex); + + if ( (lpvData != NULL) && + ((dwError = GetLastError()) == NO_ERROR) ) + {/*ERROR */ + Fail("TlsGetValue(%d) returned non-null data " + "even if no data was associated with the index\n", + dwTlsIndex); + } + + /*Create multiple threads.*/ + for (i = 0; i < NUM_OF_THREADS; i++) + { + hThread[i] = CreateThread(NULL, /* no security attributes*/ + 0, /* use default stack size */ + (LPTHREAD_START_ROUTINE) ThreadFunc, /* thread function */ + NULL, /* no thread function argument */ + 0, /* use default creation flags */ + &IDThread); /* returns thread identifier */ + + /* Check the return value for success. */ + if (hThread[i] == NULL) + {/* ERROR */ + DWORD dwError = GetLastError(); + Fail("Unexpected CreateThread error %d\n", + dwError); + } + } + + /* Wait for all threads to finish */ + for (i = 0; i < NUM_OF_THREADS; i++) + { + DWORD dwRet; + + dwRet = WaitForSingleObject(hThread[i], INFINITE); + + if( dwRet == WAIT_FAILED ) + {/* ERROR */ + DWORD dwError = GetLastError(); + Fail("Unexpected WaitForSingleObject error %d\n", + dwError); + } + } + + /* Release the TLS index */ + if( TlsFree( dwTlsIndex ) == 0 ) + {/* ERROR */ + DWORD dwError = GetLastError(); + Fail("TlsFree() returned 0 with error %d\n", + dwError); + } + + PAL_Terminate(); + return PASS; +} + diff --git a/src/pal/tests/palsuite/threading/TLS/test4/testinfo.dat b/src/pal/tests/palsuite/threading/TLS/test4/testinfo.dat new file mode 100644 index 0000000000..6001770642 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test4/testinfo.dat @@ -0,0 +1,15 @@ +# 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. + +Version = 1.0 +Section = threading +Function = TLS +Name = TlsAlloc, TlsGetValue +TYPE = DEFAULT +EXE1 = test4 +Description +=Test to ensure that upon key creation, the value NULL +=is associated with the new key in all active threads. +=Upon thread creation, the value NULL is associated +=with all defined keys in the new thread. diff --git a/src/pal/tests/palsuite/threading/TLS/test5/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test5/CMakeLists.txt new file mode 100644 index 0000000000..5fb5c9ddfd --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test5/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + test5.c +) + +add_executable(paltest_tls_test5 + ${SOURCES} +) + +add_dependencies(paltest_tls_test5 coreclrpal) + +target_link_libraries(paltest_tls_test5 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/TLS/test5/test5.c b/src/pal/tests/palsuite/threading/TLS/test5/test5.c new file mode 100644 index 0000000000..c1cd132937 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test5/test5.c @@ -0,0 +1,108 @@ +// 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: test5.c (threading/tls) +** +** Purpose: Test that creates a key, sets its value, deletes the key, +** creates a new key, and gets its value to make sure its NULL. +** +** Dependencies: PAL_Initialize +** PAL_Terminate +** LocalAlloc +** LocalFree +** + +** +**===========================================================================*/ +#include <palsuite.h> + +DWORD dwTlsIndex; /* TLS index */ + +/** + * main + * + * executable entry point + */ +INT __cdecl main( INT argc, CHAR **argv ) +{ + LPVOID lpvData; + DWORD dwError; + + /*PAL initialization */ + if( (PAL_Initialize(argc, argv)) != 0 ) + { + return FAIL; + } + + /** + * create a key, set its value, delete the key + */ + + /*Allocate a TLS index. */ + if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) + {/*ERROR*/ + DWORD dwError = GetLastError(); + Fail("TlsAlloc() returned error %d\n", + dwError); + } + + /* Initialize the TLS index for this thread.*/ + lpvData = (LPVOID) LocalAlloc(0, 256); + + if( lpvData == NULL ) + {/*ERROR */ + dwError = GetLastError(); + Fail("Unexpected LocalAlloc(0, 256) failure with error %d\n", + dwError); + } + + if ( TlsSetValue(dwTlsIndex, lpvData) == 0 ) + {/*ERROR */ + dwError = GetLastError(); + Fail("TlsSetValue(%d, %x) returned 0 with error %d\n", + dwTlsIndex, + lpvData, + dwError); + } + + /* Release the TLS index */ + if( TlsFree( dwTlsIndex ) == 0 ) + {/* ERROR */ + DWORD dwError = GetLastError(); + Fail("TlsFree() returned 0 with error %d\n", + dwError); + } + + + /** + * create a new key, and get its value + */ + + /*Allocate a TLS index. */ + if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) + {/*ERROR*/ + DWORD dwError = GetLastError(); + Fail("TlsAlloc() returned error %d\n", + dwError); + } + + /* Retrieve a data pointer for the current thread. + The return value should be NULL since no data has been + set in the index */ + lpvData = TlsGetValue(dwTlsIndex); + + if ( (lpvData != NULL) && + ((dwError = GetLastError()) == NO_ERROR) ) + {/*ERROR */ + Fail("TlsGetValue(%d) returned data " + "even if no data was associated with the index\n", + dwTlsIndex); + } + + PAL_Terminate(); + return PASS; +} + diff --git a/src/pal/tests/palsuite/threading/TLS/test5/testinfo.dat b/src/pal/tests/palsuite/threading/TLS/test5/testinfo.dat new file mode 100644 index 0000000000..4b3e2a64c5 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test5/testinfo.dat @@ -0,0 +1,13 @@ +# 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. + +Version = 1.0 +Section = threading +Function = TLS +Name = TlsAlloc and TlsGetValue +TYPE = DEFAULT +EXE1 = test5 +Description += Test that creates a key, sets its value, deletes the key, += creates a new key, and gets its value to make sure its NULL. diff --git a/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/CMakeLists.txt new file mode 100644 index 0000000000..8b3a4ed64a --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + test.c +) + +add_executable(paltest_tls_test6_optimizedtls + ${SOURCES} +) + +add_dependencies(paltest_tls_test6_optimizedtls coreclrpal) + +target_link_libraries(paltest_tls_test6_optimizedtls + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/test.c b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/test.c new file mode 100644 index 0000000000..02419dc90c --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/test.c @@ -0,0 +1,190 @@ +// 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 to ensure TlsAlloc, PAL_MakeOptimizedTlsGetter, +** PAL_FreeOptimizedTlsGetter and TlsFree are working properly +** on supported platforms +** +** Dependencies: PAL_Initialize +** Fail +** Sleep +** LocalAlloc +** LocalFree +** WaitForSingleObject +** CreateThread +** GetLastError +** + +** +**===========================================================================*/ + + +#include <palsuite.h> +#define THREAD_COUNT 5 +DWORD dwTlsIndex; /* TLS index */ + +void PALAPI Run_Thread(LPVOID lpParam); + +/** + * main + * + * executable entry point + */ +INT __cdecl main( INT argc, CHAR **argv ) +{ + DWORD dwParam; + DWORD dwError; + HANDLE hThread[THREAD_COUNT]; + DWORD threadId[THREAD_COUNT]; + + int i = 0; + int returnCode = 0; + + /*PAL initialization */ + if( (PAL_Initialize(argc, argv)) != 0 ) + { + return FAIL; + } + + /*Allocate a TLS index. */ + if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) + { + /*ERROR*/ + dwError = GetLastError(); + Fail("TlsAlloc() returned error %d\n", + dwError); + } + + + for( i = 0; i < THREAD_COUNT; i++ ) + { + dwParam = (int) i; + //Create thread + hThread[i] = CreateThread( + NULL, /* no security attributes */ + 0, /* use default stack size */ + (LPTHREAD_START_ROUTINE)Run_Thread,/* thread function */ + (LPVOID)dwParam, /* argument to thread function */ + 0, /* use default creation flags */ + &threadId[i] /* returns the thread identifier*/ + ); + + if(hThread[i] == NULL) + { + Fail("Create Thread failed for iteration %d GetLastError value is %d\n", i, GetLastError()); + } + + } + + + returnCode = WaitForMultipleObjects(THREAD_COUNT, hThread, TRUE, INFINITE); + if( WAIT_OBJECT_0 != returnCode ) + { + Trace("Wait for Object(s) returned %d, expected value is %d, and GetLastError value is %d\n", returnCode, WAIT_OBJECT_0, GetLastError()); + } + + /* Release the TLS index */ + if( TlsFree( dwTlsIndex ) == 0 ) + { + /* ERROR */ + dwError = GetLastError(); + Fail("TlsFree() returned 0 with error %d\n", + dwError); + } + + PAL_Terminate(); + return PASS; + +} + +void PALAPI Run_Thread (LPVOID lpParam) +{ + unsigned int i = 0; + + LPVOID lpvData; + DWORD dwError; + PAL_POPTIMIZEDTLSGETTER ptrOptimizedTlsGetter; + + int Id=(int)lpParam; + + + lpvData = TlsGetValue(dwTlsIndex); + if ( (lpvData != NULL) && + ((dwError = GetLastError()) == NO_ERROR) ) + { + /*ERROR */ + Fail("Error:%d:TlsGetValue(%d) returned data " + "even if data was not associated with the index, for thread id [%d]\n", + dwError, dwTlsIndex, Id); + } + + + /* Initialize the TLS index for this thread.*/ + lpvData = (LPVOID) LocalAlloc(0, 256); + + if( lpvData == NULL ) + { + /*ERROR */ + dwError = GetLastError(); + Fail("Unexpected LocalAlloc(0, 256) failure with error %d\n", + dwError); + } + + if ( TlsSetValue(dwTlsIndex, lpvData) == 0 ) + { + /*ERROR */ + dwError = GetLastError(); + Fail("TlsSetValue(%d, %x) returned 0 with error %d\n", + dwTlsIndex, + lpvData, + dwError); + } + + ptrOptimizedTlsGetter = PAL_MakeOptimizedTlsGetter(dwTlsIndex); + if( ptrOptimizedTlsGetter == NULL ) + { + /* Retrieve a data pointer for the current thread. + The return value should be NULL since no data has been + set in the index */ + lpvData = TlsGetValue(dwTlsIndex); + Trace("Not Inside the optimizer loop for thread [%d]\n", Id); + + if ( (lpvData == NULL) && + ((dwError = GetLastError()) == NO_ERROR) ) + { + /*ERROR */ + Fail("Error:%d:TlsGetValue(%d) returned data " + "as NULL even if data was associated with the index, for thread id [%d]\n", + dwError, dwTlsIndex, Id); + } + } + else + { + /* Retrieve a data pointer for the current thread. + The return value should be NULL since no data has been + set in the index */ + lpvData = ptrOptimizedTlsGetter(); + + if ( (lpvData == NULL) && + ((dwError = GetLastError()) == NO_ERROR) ) + { + /*ERROR */ + Fail(" Error:%d: MakeOptimizedTlsGetter for dwTlsIndex (%d) returned data " + "as NULL even if no data was associated with the index, for thread id [%d]\n", + dwError, dwTlsIndex, Id); + } + + Trace("Inside the optimizer loop for thread [%d]\n", Id); + PAL_FreeOptimizedTlsGetter(ptrOptimizedTlsGetter); + } + + + + +} + diff --git a/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/testinfo.dat b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/testinfo.dat new file mode 100644 index 0000000000..2193edcab3 --- /dev/null +++ b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/testinfo.dat @@ -0,0 +1,14 @@ +# 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. + +Version = 1.0 +Section = threading +Function = PAL_MakeOptimizedTlsGetter and PAL_FreeOptimizedTlsGetter +Name = Test for PAL_MakeOptimizedTlsGetterandPAL_FreeOptimizedTlsGetter +TYPE = DEFAULT +EXE1 = test +Description += Purpose: Test to ensure TlsAlloc, PAL_MakeOptimizedTlsGetter, += PAL_FreeOptimizedTlsGetter and TlsFree are working properly += on supported platforms |