home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************/
- /* TLS SAMPLE: TLS.C */
- /* */
- /* COPYRIGHT: */
- /* ---------- */
- /* Copyright (C) International Business Machines Corp., 1995. */
- /* */
- /******************************************************************************/
- /* */
- /* Sample to demonstrate thread-local storage */
- /* */
- /* This program demonstrates the use of the thread-local storage capability */
- /* of the IBM VisualAge C++ compiler. */
- /* */
- /* This sample program creates two threads. Thread 1 will wait for */
- /* Thread 2 to be created. When Thread 2 starts, it will signal Thread 1 */
- /* to resume execution. When Thread 1 resumes, it will modify the static */
- /* TLS variable "dwGlobalId" to the value of its thread id. Thread 1 then */
- /* suspends itself to wait while Thread 2 queries the value of "dwGlobalId". */
- /* Thread 2 will find that its thread-local copy of "dwGlobalId" has not */
- /* not been changed by Thread 1. */
- /* */
- /* The sample prints the following output to the screen: */
- /* */
- /* Starting main thread: dwMainId = 133 dwGlobalId = 133 */
- /* Starting Thread 1: dwThread1Id = 138 */
- /* Suspending Thread 1 to wait for Thread 2 */
- /* Starting Thread 2: dwThread2Id = 132 dwGlobalId = 132 */
- /* dwGlobalId modified in Thread 1: dwGlobalId = 138 */
- /* Suspending Thread 1 for Thread 2 to check dwGlobalId */
- /* In Thread 2 after resuming Thread 1: dwGlobalId = 132 */
- /* Ending Thread 2: dwThread2Id = 132 dwGlobalId = 132 */
- /* Ending Thread 1: dwThread1Id = 138 dwGlobalId = 138 */
- /* Ending main thread: dwMainId = 133 dwGlobalId = 133 */
- /* */
- /******************************************************************************/
- #include <stdio.h>
- #include <process.h>
- #include <windows.h>
-
-
- void errorExit(LPTSTR);
- DWORD WINAPI threadfunc2(HANDLE);
- DWORD WINAPI threadfunc1(LPVOID);
-
- /*
- * Static TLS variable
- */
- __thread DWORD dwGlobalId;
-
- /*
- * Function executed by Thread 1. Will wait for Thread 2 to begin, then
- * modify the static TLS variable to the value of its thread id. The function
- * will then wait for Thread 2 to check the value of the TLS variable before
- * completing.
- */
- DWORD WINAPI threadfunc1(LPVOID lpvParm)
- {
- DWORD dwThread1Id, dwRc;
- HANDLE hThread1;
-
- dwThread1Id = GetCurrentThreadId();
- printf("Starting Thread 1: dwThread1Id = %u\n", dwThread1Id);
- hThread1 = GetCurrentThread();
-
- /* Wait for Thread 2 to begin */
-
- printf("Suspending Thread 1 to wait for Thread 2\n");
- dwRc = SuspendThread(hThread1);
- if (dwRc != 0)
- errorExit("Error: Suspend thread failed\n");
-
- /* Modify the static TLS variable to the id of Thread 1 */
-
- dwGlobalId = dwThread1Id;
-
- printf("dwGlobalId modified in Thread 1: dwGlobalId = %u\n", dwGlobalId);
- printf("Suspending Thread 1 for Thread 2 to check dwGlobalId\n");
-
- /* Wait for Thread 2 to check the value of the TLS variable */
-
- dwRc = SuspendThread(hThread1);
- if (dwRc != 0)
- errorExit("Error: Suspend thread failed\n");
- printf("Ending Thread 1: dwThread1Id = %u dwGlobalId = %u\n", dwThread1Id, dwGlobalId);
-
- return(0);
- }
-
- /*
- * Function executed by Thread 2. When Thread 2 begins, Thread 1 is suspended
- * waiting for Thread 2. Resume Thread 1. Thread 1 will then modify the TLS
- * variable and suspend itself waiting for Thread 2 to print the value. Once
- * The TLS variable has been printed, resume Thread 1.
- */
-
- DWORD WINAPI threadfunc2(HANDLE hThread1)
- {
- DWORD dwThread2Id, dwRc;
-
- dwThread2Id = dwGlobalId = GetCurrentThreadId();
- printf("Starting Thread 2: dwThread2Id = %u dwGlobalId = %u\n", dwThread2Id, dwGlobalId);
-
- /* Resume Thread 1 */
-
- dwRc = ResumeThread(hThread1);
- if( dwRc != 1)
- errorExit("Error: Thread 1 failed to resume\n");
-
- /* Wait to ensure that Thread 1 is suspended */
- Sleep(5000);
-
- /* Print the value of the TLS variable */
- printf("In Thread 2 after resuming Thread 1: dwGlobalId = %u\n", dwGlobalId);
-
- /* Resume Thread 1 */
- dwRc = ResumeThread(hThread1);
- if( dwRc != 1)
- errorExit("Error: Thread 1 failed to resume\n");
-
- printf("Ending Thread 2: dwThread2Id = %u dwGlobalId = %u\n", dwThread2Id, dwGlobalId);
-
- return(0);
- }
-
- /*
- * main() will create Thread 1 and Thread 2, then wait for both threads to
- * end.
- */
-
- int main(void)
- {
- DWORD dwMainId, dwThreadId, dwRc;
- HANDLE hThread1, hThread2;
-
- dwMainId = dwGlobalId = GetCurrentThreadId();
-
- printf("Starting main thread: dwMainId = %u dwGlobalId = %u\n", dwMainId, dwGlobalId);
-
- /* Create Thread 1 */
-
- hThread1 = CreateThread(NULL, 0, threadfunc1, NULL, 0, &dwThreadId);
-
- if (hThread1 !=NULL)
- {
- /* Create Thread 2 */
-
- hThread2 = CreateThread(NULL, 0, threadfunc2, hThread1, 0, &dwThreadId);
- if (hThread2!=NULL)
- {
- /* Wait for Thread 1 and Thread 2 to end */
-
- dwRc = WaitForSingleObject(hThread2, INFINITE);
- CloseHandle(hThread2);
- if( dwRc != WAIT_OBJECT_0)
- errorExit("Error: Wait for Thread 2 to end failed\n");
-
- dwRc = WaitForSingleObject(hThread1, INFINITE);
- if( dwRc != WAIT_OBJECT_0)
- errorExit("Error: Wait for Thread 1 to end failed\n");
- CloseHandle(hThread1);
-
- printf("Ending main thread: dwMainId = %u dwGlobalId = %u\n", dwMainId, dwGlobalId);
- }
- else
- errorExit("Error: Thread 2 failed to create\n");
- }
- else
- errorExit("Error: Thread 1 failed to create\n");
- return 0;
- }
-
- void errorExit(LPTSTR lpszMessage)
- {
- printf("%s\n", lpszMessage);
- ExitProcess(0);
- }