diff options
Diffstat (limited to 'src/pal/tests/palsuite/threading/CreateThread')
10 files changed, 508 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/threading/CreateThread/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateThread/CMakeLists.txt new file mode 100644 index 0000000000..1962ade358 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +add_subdirectory(test1) +add_subdirectory(test2) +add_subdirectory(test3) + diff --git a/src/pal/tests/palsuite/threading/CreateThread/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateThread/test1/CMakeLists.txt new file mode 100644 index 0000000000..d3921c4409 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/test1/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + test1.c +) + +add_executable(paltest_createthread_test1 + ${SOURCES} +) + +add_dependencies(paltest_createthread_test1 coreclrpal) + +target_link_libraries(paltest_createthread_test1 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/CreateThread/test1/test1.c b/src/pal/tests/palsuite/threading/CreateThread/test1/test1.c new file mode 100644 index 0000000000..2dd2f6acb6 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/test1/test1.c @@ -0,0 +1,119 @@ +// 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: test1.c +** +** Purpose: Test for CreateThread. Call CreateThread and ensure +** that it succeeds. Also check to ensure the paramater is passed +** properly. +** +** +**=========================================================*/ + +#include <palsuite.h> + +#ifndef PLATFORM_UNIX +#define LLFORMAT "%I64u" +#else +#define LLFORMAT "%llu" +#endif + +ULONGLONG dwCreateThreadTestParameter = 0; + +DWORD PALAPI CreateThreadTestThread( LPVOID lpParameter) +{ + DWORD dwRet = 0; + + /* save parameter for test */ + dwCreateThreadTestParameter = (ULONGLONG)lpParameter; + + return dwRet; +} + +BOOL CreateThreadTest() +{ + BOOL bRet = FALSE; + DWORD dwRet = 0; + + LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL; + DWORD dwStackSize = 0; + LPTHREAD_START_ROUTINE lpStartAddress = &CreateThreadTestThread; + LPVOID lpParameter = lpStartAddress; + DWORD dwCreationFlags = 0; /* run immediately */ + DWORD dwThreadId = 0; + + HANDLE hThread = 0; + + dwCreateThreadTestParameter = 0; + + /* Create a thread, passing the appropriate paramaters as declared + above. + */ + + hThread = CreateThread( lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + &dwThreadId ); + + /* Ensure that the HANDLE is not invalid! */ + if (hThread != INVALID_HANDLE_VALUE) + { + dwRet = WaitForSingleObject(hThread,INFINITE); + + if (dwRet != WAIT_OBJECT_0) + { + Trace("CreateThreadTest:WaitForSingleObject " + "failed (%x)\n",GetLastError()); + } + else + { + /* Check to ensure that the parameter passed to the thread + function is the same in the function as what we passed. + */ + + if (dwCreateThreadTestParameter != (ULONGLONG)lpParameter) + { + Trace("CreateThreadTest:parameter error. The " + "parameter passed should have been " LLFORMAT " but when " + "passed to the Thread function it was " LLFORMAT " . GetLastError[%x]\n", + dwCreateThreadTestParameter,lpParameter, GetLastError()); + } + else + { + bRet = TRUE; + } + + } + CloseHandle(hThread); + } + else + { + Trace("CreateThreadTest:CreateThread failed (%x)\n",GetLastError()); + } + + return bRet; +} + + +int __cdecl main(int argc, char **argv) +{ + if(0 != (PAL_Initialize(argc, argv))) + { + return ( FAIL ); + } + + if(!CreateThreadTest()) + { + Fail ("Test failed\n"); + } + + Trace("Test Passed\n"); + PAL_Terminate(); + return ( PASS ); + +} diff --git a/src/pal/tests/palsuite/threading/CreateThread/test1/testinfo.dat b/src/pal/tests/palsuite/threading/CreateThread/test1/testinfo.dat new file mode 100644 index 0000000000..3ae70625c2 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/test1/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 = CreateThread +Name = Positive Test for CreateThread +TYPE = DEFAULT +EXE1 = test1 +Description += Test for CreateThread. Call CreateThread and ensure += that it succeeds. Also check to ensure the paramater is passed += properly. diff --git a/src/pal/tests/palsuite/threading/CreateThread/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateThread/test2/CMakeLists.txt new file mode 100644 index 0000000000..350cf66e9b --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/test2/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + test2.c +) + +add_executable(paltest_createthread_test2 + ${SOURCES} +) + +add_dependencies(paltest_createthread_test2 coreclrpal) + +target_link_libraries(paltest_createthread_test2 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/CreateThread/test2/test2.c b/src/pal/tests/palsuite/threading/CreateThread/test2/test2.c new file mode 100644 index 0000000000..f64c32ea87 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/test2/test2.c @@ -0,0 +1,184 @@ +// 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: test2.c +** +** Purpose: Test that lpThreadId is assigned the correct +** threadId value and that lpThreadId can be NULL. +** +** +**=========================================================*/ + +#include <palsuite.h> + +#define NUM_TESTS 3 + +HANDLE hThread[NUM_TESTS]; +DWORD dwThreadId[NUM_TESTS]; +volatile BOOL bResult[NUM_TESTS]; +volatile DWORD dwThreadId1[NUM_TESTS]; + +DWORD PALAPI Thread( LPVOID lpParameter) +{ + dwThreadId1[(DWORD) lpParameter] = GetCurrentThreadId(); + bResult[(DWORD) lpParameter] = TRUE; + return (DWORD) lpParameter; +} + +struct testCase +{ + LPSECURITY_ATTRIBUTES lpThreadAttributes; + DWORD dwStackSize; + LPTHREAD_START_ROUTINE lpStartAddress; + DWORD dwCreationFlags; + LPVOID lpThreadId; +}; + +struct testCase testCases[]= +{ + {NULL, 0, &Thread, 0, NULL}, + {NULL, 0, &Thread, CREATE_SUSPENDED, NULL}, + {NULL, 0, &Thread, 0, (LPVOID) 1} +}; + +/* + * close handles + */ +BOOL cleanup(int index) +{ + int i; + BOOL bRet = TRUE; + + for (i = 0; i < index; i++) + { + if (!CloseHandle(hThread[i])) + { + bRet = FALSE; + Trace("PALSUITE ERROR: CloseHandle(%p) call failed for index %d\n", + hThread[i], i); + } + } + + return(bRet); +} + +int __cdecl main(int argc, char **argv) +{ + SIZE_T i; + DWORD dwRetWFSO; + DWORD dwRetRT; + BOOL bRet = TRUE; + + if(0 != (PAL_Initialize(argc, argv))) + { + return (FAIL); + } + + /* set results array to FALSE */ + for (i = 0; i < NUM_TESTS; i++) + { + bResult[i]=FALSE; + dwThreadId[i]=0; + } + + for (i = 0; i < NUM_TESTS; i++) + { + if (NULL != testCases[i].lpThreadId) + { + testCases[i].lpThreadId = &dwThreadId[i]; + } + /* pass the index as the thread argument */ + hThread[i] = CreateThread( testCases[i].lpThreadAttributes, + testCases[i].dwStackSize, + testCases[i].lpStartAddress, + (LPVOID) i, + testCases[i].dwCreationFlags, + testCases[i].lpThreadId); + if (hThread[i] == NULL) + { + Trace("PALSUITE ERROR: CreateThread('%p' '%d' '%p' '%p' '%d' " + "'%p') call failed.\nGetLastError returned '%u'.\n", + testCases[i].lpThreadAttributes, testCases[i].dwStackSize, + testCases[i].lpStartAddress, (LPVOID) i, + testCases[i].dwCreationFlags, + testCases[i].lpThreadId, GetLastError()); + cleanup(i - 1); + Fail(""); + } + + /* Resume suspended threads */ + if (testCases[i].dwCreationFlags == CREATE_SUSPENDED) + { + dwRetRT = ResumeThread (hThread[i]); + if (dwRetRT != 1) + { + Trace ("PALSUITE ERROR: ResumeThread(%p) " + "call returned %d it should have returned %d.\n" + "GetLastError returned %u.\n", hThread[i], dwRetRT, + 1, GetLastError()); + cleanup(i); + Fail(""); + } + } + } + + /* cleanup */ + for (i = 0; i < NUM_TESTS; i++) + { + dwRetWFSO = WaitForSingleObject(hThread[i], 10000); + if (dwRetWFSO != WAIT_OBJECT_0) + { + Trace ("PALSUITE ERROR: WaitForSingleObject('%p' '%d') " + "call returned %d instead of WAIT_OBJECT_0 ('%d').\n" + "GetLastError returned %u.\n", hThread[i], 10000, + dwRetWFSO, WAIT_OBJECT_0, GetLastError()); + cleanup(i); + Fail(""); + } + } + if(!cleanup(NUM_TESTS)) + { + Fail(""); + } + + for (i = 0; i < NUM_TESTS; i++) + { + /* + * check to see that all threads were created and were passed + * the array index as an argument. + */ + if (FALSE == bResult[i]) + { + bRet = FALSE; + Trace("PALSUITE ERROR: result[%d]=%d. It should be %d\n", i, + FALSE, TRUE); + } + /* + * check to see that lpThreadId received the correct value. + */ + if (0 != dwThreadId[i]) + { + if (dwThreadId[i] != dwThreadId1[i]) + { + bRet = FALSE; + Trace("PALSUITE ERROR: dwThreadId[%d]=%p and dwThreadId1[%d]" + "=%p\nThese values should be identical.\n", i, + dwThreadId[i], i, dwThreadId1[i]); + } + } + } + if (!bRet) + { + cleanup(NUM_TESTS); + Fail(""); + } + + PAL_Terminate(); + return (PASS); +} + + + diff --git a/src/pal/tests/palsuite/threading/CreateThread/test2/testinfo.dat b/src/pal/tests/palsuite/threading/CreateThread/test2/testinfo.dat new file mode 100644 index 0000000000..0333beb360 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/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 = CreateThread +Name = Positive Test for CreateThread +TYPE = DEFAULT +EXE1 = test2 +Description += Test that lpThreadId is assigned the correct threadId value and += that lpThreadId can be NULL. diff --git a/src/pal/tests/palsuite/threading/CreateThread/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateThread/test3/CMakeLists.txt new file mode 100644 index 0000000000..923d7a72ab --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/test3/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + test3.c +) + +add_executable(paltest_createthread_test3 + ${SOURCES} +) + +add_dependencies(paltest_createthread_test3 coreclrpal) + +target_link_libraries(paltest_createthread_test3 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/CreateThread/test3/test3.c b/src/pal/tests/palsuite/threading/CreateThread/test3/test3.c new file mode 100644 index 0000000000..0c44d1fdd0 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/test3/test3.c @@ -0,0 +1,101 @@ +// 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: test3.c +** +** Purpose: Check to see that the handle CreateThread returns +** can be closed while the thread is still running. +** +** +**=========================================================*/ + +#include <palsuite.h> + +HANDLE hThread; +HANDLE hEvent; + +DWORD PALAPI Thread( LPVOID lpParameter) +{ + DWORD dwRet; + dwRet = WaitForSingleObject(hEvent, INFINITE); + /* if this thread continues beyond here, fail */ + Fail(""); + + return 0; +} + +int __cdecl main(int argc, char **argv) +{ + DWORD dwThreadId; + DWORD dwRet; + + if(0 != (PAL_Initialize(argc, argv))) + { + return (FAIL); + } + + hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (hEvent == NULL) + { + Fail("PALSUITE ERROR: CreateEvent call #0 failed. GetLastError " + "returned %u.\n", GetLastError()); + } + + /* pass the index as the thread argument */ + hThread = CreateThread( NULL, + 0, + &Thread, + (LPVOID) 0, + 0, + &dwThreadId); + if (hThread == NULL) + { + Trace("PALSUITE ERROR: CreateThread('%p' '%d' '%p' '%p' '%d' '%p') " + "call failed.\nGetLastError returned '%u'.\n", NULL, + 0, &Thread, (LPVOID) 0, 0, &dwThreadId, GetLastError()); + if (0 == CloseHandle(hEvent)) + { + Trace("PALSUITE ERROR: Unable to execute CloseHandle(%p) during " + "clean up.\nGetLastError returned '%u'.\n", hEvent); + } + Fail(""); + } + + dwRet = WaitForSingleObject(hThread, 10000); + if (dwRet != WAIT_TIMEOUT) + { + Trace ("PALSUITE ERROR: WaitForSingleObject('%p' '%d') " + "call returned %d instead of WAIT_TIMEOUT ('%d').\n" + "GetLastError returned '%u'.\n", hThread, 10000, + dwRet, WAIT_TIMEOUT, GetLastError()); + Fail(""); + } + + if (0 == CloseHandle(hThread)) + { + Trace("PALSUITE ERROR: Unable to CloseHandle(%p) on a running thread." + "\nGetLastError returned '%u'.\n", hThread, GetLastError()); + if (0 == CloseHandle(hEvent)) + { + Trace("PALSUITE ERROR: Unable to execute CloseHandle(%p) during " + "cleanup.\nGetLastError returned '%u'.\n", hEvent, + GetLastError()); + } + Fail(""); + } + if (0 == CloseHandle(hEvent)) + { + Trace("PALSUITE ERROR: Unable to execute CloseHandle(%p) during " + "cleanup.\nGetLastError returned '%u'.\n", hEvent, + GetLastError()); + Fail(""); + } + + PAL_Terminate(); + return (PASS); +} + diff --git a/src/pal/tests/palsuite/threading/CreateThread/test3/testinfo.dat b/src/pal/tests/palsuite/threading/CreateThread/test3/testinfo.dat new file mode 100644 index 0000000000..712c3a6652 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CreateThread/test3/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 = CreateThread +Name = Positive Test for CreateThread +TYPE = DEFAULT +EXE1 = test3 +Description += Check to see that the handle CreateThread returns can be closed while += the thread is still running. + |