* winsup.api/pthread/: New directory. Ports of pthread functionality
tests ported from pthreads-win32 project. * winsup.api/pthread/test.h: Commmon declaraions for pthread tests. * winsup.api/pthread/cleanup2.c: New test. * winsup.api/pthread/cleanup3.c: Ditto. * winsup.api/pthread/condvar1.c: Ditto. * winsup.api/pthread/condvar2.c: Ditto. * winsup.api/pthread/condvar2_1.c: Ditto. * winsup.api/pthread/condvar3.c: Ditto. * winsup.api/pthread/condvar3_1.c: Ditto. * winsup.api/pthread/condvar3_2.c: Ditto. * winsup.api/pthread/condvar3_3.c: Ditto. * winsup.api/pthread/condvar4.c: Ditto. * winsup.api/pthread/condvar5.c: Ditto. * winsup.api/pthread/condvar6.c: Ditto. * winsup.api/pthread/condvar8.c: Ditto. * winsup.api/pthread/count1.c: Ditto. * winsup.api/pthread/create1.c: Ditto. * winsup.api/pthread/create2.c: Ditto. * winsup.api/pthread/equal1.c: Ditto. * winsup.api/pthread/exit1.c: Ditto. * winsup.api/pthread/exit2.c: Ditto. * winsup.api/pthread/exit3.c: Ditto. * winsup.api/pthread/inherit1.c: Ditto. * winsup.api/pthread/join0.c: Ditto. * winsup.api/pthread/join1.c: Ditto. * winsup.api/pthread/join2.c: Ditto. * winsup.api/pthread/mutex1.c: Ditto. * winsup.api/pthread/mutex1r.c: Ditto. * winsup.api/pthread/mutex2.c: Ditto. * winsup.api/pthread/mutex3.c: Ditto. * winsup.api/pthread/mutex6r.c: Ditto. * winsup.api/pthread/once1.c: Ditto. * winsup.api/pthread/priority1.c: Ditto. * winsup.api/pthread/priority2.c: Ditto. * winsup.api/pthread/self1.c: Ditto. * winsup.api/pthread/self2.c: Ditto. * winsup.api/pthread/tsd1.c: Ditto.
This commit is contained in:
		| @@ -1,3 +1,44 @@ | ||||
| 2001-11-15  Egor Duda  <deo@logos-m.ru> | ||||
|  | ||||
| 	* winsup.api/pthread/: New directory. Ports of pthread functionality | ||||
| 	tests ported from pthreads-win32 project. | ||||
| 	* winsup.api/pthread/test.h: Commmon declaraions for pthread tests. | ||||
| 	* winsup.api/pthread/cleanup2.c: New test. | ||||
| 	* winsup.api/pthread/cleanup3.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar1.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar2.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar2_1.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar3.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar3_1.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar3_2.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar3_3.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar4.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar5.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar6.c: Ditto. | ||||
| 	* winsup.api/pthread/condvar8.c: Ditto. | ||||
| 	* winsup.api/pthread/count1.c: Ditto. | ||||
| 	* winsup.api/pthread/create1.c: Ditto. | ||||
| 	* winsup.api/pthread/create2.c: Ditto. | ||||
| 	* winsup.api/pthread/equal1.c: Ditto. | ||||
| 	* winsup.api/pthread/exit1.c: Ditto. | ||||
| 	* winsup.api/pthread/exit2.c: Ditto. | ||||
| 	* winsup.api/pthread/exit3.c: Ditto. | ||||
| 	* winsup.api/pthread/inherit1.c: Ditto. | ||||
| 	* winsup.api/pthread/join0.c: Ditto. | ||||
| 	* winsup.api/pthread/join1.c: Ditto. | ||||
| 	* winsup.api/pthread/join2.c: Ditto. | ||||
| 	* winsup.api/pthread/mutex1.c: Ditto. | ||||
| 	* winsup.api/pthread/mutex1r.c: Ditto. | ||||
| 	* winsup.api/pthread/mutex2.c: Ditto. | ||||
| 	* winsup.api/pthread/mutex3.c: Ditto. | ||||
| 	* winsup.api/pthread/mutex6r.c: Ditto. | ||||
| 	* winsup.api/pthread/once1.c: Ditto. | ||||
| 	* winsup.api/pthread/priority1.c: Ditto. | ||||
| 	* winsup.api/pthread/priority2.c: Ditto. | ||||
| 	* winsup.api/pthread/self1.c: Ditto. | ||||
| 	* winsup.api/pthread/self2.c: Ditto. | ||||
| 	* winsup.api/pthread/tsd1.c: Ditto. | ||||
|  | ||||
| 2001-11-08  Corinna Vinschen <corinna@vinschen.de> | ||||
|  | ||||
| 	* checksignal.c: New testcase. | ||||
|   | ||||
							
								
								
									
										157
									
								
								winsup/testsuite/winsup.api/pthread/cleanup2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								winsup/testsuite/winsup.api/pthread/cleanup2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | ||||
| /* | ||||
|  * File: cleanup2.c | ||||
|  * | ||||
|  * Test Synopsis: Test cleanup handler executes (when thread is not canceled). | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * -  | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * -  | ||||
|  * | ||||
|  * Environment: | ||||
|  * -  | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock | ||||
|  *   pthread_testcancel, pthread_cancel, pthread_join | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| /* | ||||
|  * Create NUMTHREADS threads in addition to the Main thread. | ||||
|  */ | ||||
| enum { | ||||
|   NUMTHREADS = 10 | ||||
| }; | ||||
|  | ||||
| typedef struct bag_t_ bag_t; | ||||
| struct bag_t_ { | ||||
|   int threadnum; | ||||
|   int started; | ||||
|   /* Add more per-thread state variables here */ | ||||
|   int count; | ||||
| }; | ||||
|  | ||||
| static bag_t threadbag[NUMTHREADS + 1]; | ||||
|  | ||||
| static int pop_count = 0; | ||||
|  | ||||
| static void | ||||
| increment_pop_count(void * arg) | ||||
| { | ||||
|   int * c = (int *) arg; | ||||
|  | ||||
|   (*c)++; | ||||
| } | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   int result = 0; | ||||
|   bag_t * bag = (bag_t *) arg; | ||||
|  | ||||
|   assert(bag == &threadbag[bag->threadnum]); | ||||
|   assert(bag->started == 0); | ||||
|   bag->started = 1; | ||||
|  | ||||
|   pthread_cleanup_push(increment_pop_count, (void *) &pop_count); | ||||
|  | ||||
|   sched_yield(); | ||||
|  | ||||
|   pthread_cleanup_pop(1); | ||||
|  | ||||
|   return (void *) result; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   int failed = 0; | ||||
|   int i; | ||||
|   pthread_t t[NUMTHREADS + 1]; | ||||
|  | ||||
|   assert((t[0] = pthread_self()) != NULL); | ||||
|  | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       threadbag[i].started = 0; | ||||
|       threadbag[i].threadnum = i; | ||||
|       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); | ||||
|     } | ||||
|  | ||||
|   /* | ||||
|    * Code to control or munipulate child threads should probably go here. | ||||
|    */ | ||||
|   Sleep(1000); | ||||
|  | ||||
|   /* | ||||
|    * Standard check that all threads started. | ||||
|    */ | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     {  | ||||
|       if (!threadbag[i].started) | ||||
| 	{ | ||||
| 	  failed |= !threadbag[i].started; | ||||
| 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   assert(!failed); | ||||
|  | ||||
|   /* | ||||
|    * Check any results here. Set "failed" and only print output on failure. | ||||
|    */ | ||||
|   failed = 0; | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       int fail = 0; | ||||
|       int result = 0; | ||||
|  | ||||
|       assert(pthread_join(t[i], (void **) &result) == 0); | ||||
|  | ||||
|       fail = (result != 0); | ||||
|  | ||||
|       if (fail) | ||||
| 	{ | ||||
| 	  fprintf(stderr, "Thread %d: started %d: result: %d\n", | ||||
| 		  i, | ||||
| 		  threadbag[i].started, | ||||
| 		  result); | ||||
| 	} | ||||
|       failed = (failed || fail); | ||||
|     } | ||||
|  | ||||
|   assert(!failed); | ||||
|  | ||||
|   assert(pop_count == NUMTHREADS); | ||||
|  | ||||
|   /* | ||||
|    * Success. | ||||
|    */ | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										160
									
								
								winsup/testsuite/winsup.api/pthread/cleanup3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								winsup/testsuite/winsup.api/pthread/cleanup3.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,160 @@ | ||||
| /* | ||||
|  * File: cleanup3.c | ||||
|  * | ||||
|  * Test Synopsis: Test cleanup handler does not execute (when thread is | ||||
|  * not canceled). | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * -  | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * -  | ||||
|  * | ||||
|  * Environment: | ||||
|  * -  | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock | ||||
|  *   pthread_testcancel, pthread_cancel, pthread_join | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| /* | ||||
|  * Create NUMTHREADS threads in addition to the Main thread. | ||||
|  */ | ||||
| enum { | ||||
|   NUMTHREADS = 10 | ||||
| }; | ||||
|  | ||||
| typedef struct bag_t_ bag_t; | ||||
| struct bag_t_ { | ||||
|   int threadnum; | ||||
|   int started; | ||||
|   /* Add more per-thread state variables here */ | ||||
|   int count; | ||||
| }; | ||||
|  | ||||
| static bag_t threadbag[NUMTHREADS + 1]; | ||||
|  | ||||
| static int pop_count = 0; | ||||
|  | ||||
| static void | ||||
| increment_pop_count(void * arg) | ||||
| { | ||||
|   int * c = (int *) arg; | ||||
|  | ||||
|   (*c)++; | ||||
| } | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   int result = 0; | ||||
|   bag_t * bag = (bag_t *) arg; | ||||
|  | ||||
|   assert(bag == &threadbag[bag->threadnum]); | ||||
|   assert(bag->started == 0); | ||||
|   bag->started = 1; | ||||
|  | ||||
|   pthread_cleanup_push(increment_pop_count, (void *) &pop_count); | ||||
|  | ||||
|   sched_yield(); | ||||
|  | ||||
|   pop_count--; | ||||
|  | ||||
|   pthread_cleanup_pop(0); | ||||
|  | ||||
|   return (void *) result; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   int failed = 0; | ||||
|   int i; | ||||
|   pthread_t t[NUMTHREADS + 1]; | ||||
|  | ||||
|   assert((t[0] = pthread_self()) != NULL); | ||||
|  | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       threadbag[i].started = 0; | ||||
|       threadbag[i].threadnum = i; | ||||
|       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); | ||||
|     } | ||||
|  | ||||
|   /* | ||||
|    * Code to control or munipulate child threads should probably go here. | ||||
|    */ | ||||
|   Sleep(1000); | ||||
|  | ||||
|   /* | ||||
|    * Standard check that all threads started. | ||||
|    */ | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     {  | ||||
|       if (!threadbag[i].started) | ||||
| 	{ | ||||
| 	  failed |= !threadbag[i].started; | ||||
| 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   assert(!failed); | ||||
|  | ||||
|   /* | ||||
|    * Check any results here. Set "failed" and only print output on failure. | ||||
|    */ | ||||
|   failed = 0; | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       int fail = 0; | ||||
|       int result = 0; | ||||
|  | ||||
|       assert(pthread_join(t[i], (void **) &result) == 0); | ||||
|  | ||||
|       fail = (result != 0); | ||||
|  | ||||
|       if (fail) | ||||
| 	{ | ||||
| 	  fprintf(stderr, "Thread %d: started %d: result: %d\n", | ||||
| 		  i, | ||||
| 		  threadbag[i].started, | ||||
| 		  result); | ||||
| 	} | ||||
|       failed = (failed || fail); | ||||
|     } | ||||
|  | ||||
|   assert(!failed); | ||||
|  | ||||
|   assert(pop_count == -(NUMTHREADS)); | ||||
|  | ||||
|   /* | ||||
|    * Success. | ||||
|    */ | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										65
									
								
								winsup/testsuite/winsup.api/pthread/condvar1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								winsup/testsuite/winsup.api/pthread/condvar1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /* | ||||
|  * File: condvar1.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test initialisation and destruction of a CV. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - Creates and then imediately destroys a CV. Does not | ||||
|  *   test the CV. | ||||
|  * | ||||
|  * Environment: | ||||
|  * -  | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - pthread_cond_init returns 0, and | ||||
|  * - pthread_cond_destroy returns 0. | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - pthread_cond_init returns non-zero, or | ||||
|  * - pthread_cond_destroy returns non-zero. | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| static pthread_cond_t cv = NULL; | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   assert(cv == NULL); | ||||
|  | ||||
|   assert(pthread_cond_init(&cv, NULL) == 0); | ||||
|  | ||||
|   assert(cv != NULL); | ||||
|  | ||||
|   assert(pthread_cond_destroy(&cv) == 0); | ||||
|  | ||||
|   assert(cv == NULL); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										80
									
								
								winsup/testsuite/winsup.api/pthread/condvar2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								winsup/testsuite/winsup.api/pthread/condvar2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /* | ||||
|  * File: condvar2.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test timed wait on a CV. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - Because the CV is never signaled, we expect the wait to time out. | ||||
|  * | ||||
|  * Environment: | ||||
|  * - | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - pthread_cond_timedwait returns ETIMEDOUT. | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - pthread_cond_timedwait does not return ETIMEDOUT. | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| pthread_cond_t cv; | ||||
| pthread_mutex_t mutex; | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   struct timespec abstime = { 0, 0 }; | ||||
|   struct timeb currSysTime; | ||||
|   const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|   int result; | ||||
|  | ||||
|   assert(pthread_cond_init(&cv, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_init(&mutex, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   /* get current system time */ | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   abstime.tv_sec += 5; | ||||
|  | ||||
|   assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT); | ||||
|    | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   result = pthread_cond_destroy(&cv); | ||||
|   assert(result == 0); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										107
									
								
								winsup/testsuite/winsup.api/pthread/condvar2_1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								winsup/testsuite/winsup.api/pthread/condvar2_1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| /* | ||||
|  * File: condvar2_1.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test timeout of multiple waits on a CV with no signal/broadcast. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - Because the CV is never signaled, we expect the waits to time out. | ||||
|  * | ||||
|  * Environment: | ||||
|  * - | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - pthread_cond_timedwait returns ETIMEDOUT. | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - pthread_cond_timedwait does not return ETIMEDOUT. | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| static pthread_cond_t cv; | ||||
| static pthread_mutex_t mutex; | ||||
| static struct timespec abstime = { 0, 0 }; | ||||
|  | ||||
| enum { | ||||
|   NUMTHREADS = 60 | ||||
| }; | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT); | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   return arg; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   int i; | ||||
|   pthread_t t[NUMTHREADS + 1]; | ||||
|   int result = 0; | ||||
|   struct timeb currSysTime; | ||||
|   const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|  | ||||
|   assert(pthread_cond_init(&cv, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_init(&mutex, NULL) == 0); | ||||
|  | ||||
|   /* get current system time */ | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   abstime.tv_sec += 5; | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); | ||||
|     } | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       assert(pthread_join(t[i], (void **) &result) == 0); | ||||
|       assert(result == i); | ||||
|     } | ||||
|  | ||||
|   result = pthread_cond_destroy(&cv); | ||||
|   assert(result == 0); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										115
									
								
								winsup/testsuite/winsup.api/pthread/condvar3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								winsup/testsuite/winsup.api/pthread/condvar3.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| /* | ||||
|  * File: condvar3.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test basic function of a CV | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - The primary thread takes the lock before creating any threads. | ||||
|  *   The secondary thread blocks on the lock allowing the primary | ||||
|  *   thread to enter the cv wait state which releases the lock. | ||||
|  *   The secondary thread then takes the lock and signals the waiting | ||||
|  *   primary thread. | ||||
|  * | ||||
|  * Environment: | ||||
|  * -  | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - pthread_cond_timedwait returns 0. | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - pthread_cond_timedwait returns ETIMEDOUT. | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| static pthread_cond_t cv; | ||||
| static pthread_mutex_t mutex; | ||||
| static int shared = 0; | ||||
|  | ||||
| enum { | ||||
|   NUMTHREADS = 2         /* Including the primary thread. */ | ||||
| }; | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   int result = 0; | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   shared++; | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   if ((result = pthread_cond_signal(&cv)) != 0) | ||||
|     { | ||||
|       printf("Error = %s\n", error_string[result]); | ||||
|     } | ||||
|   assert(result == 0); | ||||
|  | ||||
|   return (void *) 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t[NUMTHREADS]; | ||||
|   struct timespec abstime = { 0, 0 }; | ||||
|   struct timeb currSysTime; | ||||
|   const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|  | ||||
|   assert((t[0] = pthread_self()) != NULL); | ||||
|  | ||||
|   assert(pthread_cond_init(&cv, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_init(&mutex, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   /* get current system time */ | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); | ||||
|  | ||||
|   abstime.tv_sec += 5; | ||||
|  | ||||
|   while (! (shared > 0)) | ||||
|     assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == 0); | ||||
|  | ||||
|   assert(shared > 0); | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   assert(pthread_cond_destroy(&cv) == 0); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										148
									
								
								winsup/testsuite/winsup.api/pthread/condvar3_1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								winsup/testsuite/winsup.api/pthread/condvar3_1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| /* | ||||
|  * File: condvar3_1.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test timeout of multiple waits on a CV with some signaled. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - Because some CVs are never signaled, we expect their waits to time out. | ||||
|  *   Some are signaled, the rest time out. Pthread_cond_destroy() will fail | ||||
|  *   unless all are accounted for, either signaled or timedout. | ||||
|  * | ||||
|  * Environment: | ||||
|  * - | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - pthread_cond_timedwait returns ETIMEDOUT. | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - pthread_cond_timedwait does not return ETIMEDOUT. | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| static pthread_cond_t cv; | ||||
| static pthread_cond_t cv1; | ||||
| static pthread_mutex_t mutex; | ||||
| static struct timespec abstime = { 0, 0 }; | ||||
| static int timedout = 0; | ||||
| static int signaled = 0; | ||||
| static int awoken = 0; | ||||
| static int waiting = 0; | ||||
|  | ||||
| enum { | ||||
|   NUMTHREADS = 60 | ||||
| }; | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   int result; | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   if ( ++waiting == NUMTHREADS) | ||||
|     assert(pthread_cond_signal(&cv1) == 0); | ||||
|  | ||||
|   result = pthread_cond_timedwait(&cv, &mutex, &abstime); | ||||
|   if (result == ETIMEDOUT) | ||||
|     { | ||||
|       printf ("thread N %d has timed out\n", (int)arg); | ||||
|       timedout++; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       printf ("thread N %d has waken up\n", (int)arg); | ||||
|       awoken++; | ||||
|     } | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   return arg; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   int i; | ||||
|   pthread_t t[NUMTHREADS + 1]; | ||||
|   int result = 0; | ||||
|   struct timeb currSysTime; | ||||
|   const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|  | ||||
|   assert(pthread_cond_init(&cv, NULL) == 0); | ||||
|   assert(pthread_cond_init(&cv1, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_init(&mutex, NULL) == 0); | ||||
|  | ||||
|   /* get current system time */ | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   abstime.tv_sec += 5; | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); | ||||
|     } | ||||
|  | ||||
|   do { | ||||
|     assert(pthread_cond_wait(&cv1,&mutex) == 0); | ||||
|   } while ( NUMTHREADS != waiting ); | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   for (i = NUMTHREADS/3; i <= 2*NUMTHREADS/3; i++) | ||||
|     { | ||||
|       printf ("sending signal N %d\n", signaled + 1); | ||||
|       assert(pthread_cond_signal(&cv) == 0); | ||||
|       signaled++; | ||||
|     } | ||||
|  | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       assert(pthread_join(t[i], (void **) &result) == 0); | ||||
|         assert(result == i); | ||||
|     } | ||||
|  | ||||
|   fprintf(stderr, "awk = %d\n", awoken); | ||||
|   fprintf(stderr, "sig = %d\n", signaled); | ||||
|   fprintf(stderr, "tot = %d\n", timedout); | ||||
|  | ||||
|   assert(signaled == awoken); | ||||
|   assert(timedout == NUMTHREADS - signaled); | ||||
|  | ||||
|   result = pthread_cond_destroy(&cv); | ||||
|   assert(result == 0); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										139
									
								
								winsup/testsuite/winsup.api/pthread/condvar3_2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								winsup/testsuite/winsup.api/pthread/condvar3_2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | ||||
| /* | ||||
|  * File: condvar3_2.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test timeout of multiple waits on a CV with remainder broadcast awoken. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - Because some CVs are never signaled, we expect their waits to time out. | ||||
|  *   Some time out, the rest are broadcast signaled. Pthread_cond_destroy() will fail | ||||
|  *   unless all are accounted for, either signaled or timedout. | ||||
|  * | ||||
|  * Environment: | ||||
|  * - | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - pthread_cond_timedwait returns ETIMEDOUT. | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - pthread_cond_timedwait does not return ETIMEDOUT. | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| static pthread_cond_t cv; | ||||
| static pthread_mutex_t mutex; | ||||
| static struct timespec abstime = { 0, 0 }; | ||||
| static struct timespec abstime2 = { 0, 0 }; | ||||
| static int timedout = 0; | ||||
| static int awoken = 0; | ||||
|  | ||||
| enum { | ||||
|   NUMTHREADS = 60 | ||||
| }; | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   int result; | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   abstime2.tv_sec = abstime.tv_sec; | ||||
|  | ||||
|   if ((int) arg % 3 == 0) | ||||
|     { | ||||
|       abstime2.tv_sec += 2; | ||||
|     } | ||||
|  | ||||
|   result = pthread_cond_timedwait(&cv, &mutex, &abstime2); | ||||
|   if (result == ETIMEDOUT) | ||||
|     { | ||||
|       timedout++; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       awoken++; | ||||
|     } | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   return arg; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   int i; | ||||
|   pthread_t t[NUMTHREADS + 1]; | ||||
|   int result = 0; | ||||
|   struct timeb currSysTime; | ||||
|   const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|  | ||||
|   assert(pthread_cond_init(&cv, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_init(&mutex, NULL) == 0); | ||||
|  | ||||
|   /* get current system time */ | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = abstime.tv_sec = currSysTime.time + 5; | ||||
|   abstime.tv_nsec = abstime2.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); | ||||
|     } | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       assert(pthread_join(t[i], (void **) &result) == 0); | ||||
| 	assert(result == i); | ||||
|       /* | ||||
|        * Approximately 2/3rds of the threads are expected to time out. | ||||
|        * Signal the remainder after some threads have woken up and exited | ||||
|        * and while some are still waking up after timeout. | ||||
|        * Also tests that redundant broadcasts don't return errors. | ||||
|        */ | ||||
|       if (awoken > NUMTHREADS/3) | ||||
|         { | ||||
|           assert(pthread_cond_broadcast(&cv) == 0); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   assert(awoken == NUMTHREADS - timedout); | ||||
|  | ||||
|   result = pthread_cond_destroy(&cv); | ||||
|   assert(result == 0); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										100
									
								
								winsup/testsuite/winsup.api/pthread/condvar3_3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								winsup/testsuite/winsup.api/pthread/condvar3_3.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| /* | ||||
|  * File: condvar3_3.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test timeouts and lost signals on a CV. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - | ||||
|  * | ||||
|  * Environment: | ||||
|  * - | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - pthread_cond_timedwait returns ETIMEDOUT. | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - pthread_cond_timedwait does not return ETIMEDOUT. | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| /* Timur Aydin (taydin@snet.net) */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| pthread_cond_t cnd; | ||||
| pthread_mutex_t mtx; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|    int rc; | ||||
|  | ||||
|    struct timespec abstime = { 0, 0 }; | ||||
|    struct timeb currSysTime; | ||||
|    const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|  | ||||
|    assert(pthread_cond_init(&cnd, 0) == 0); | ||||
|    assert(pthread_mutex_init(&mtx, 0) == 0); | ||||
|  | ||||
|    /* get current system time */ | ||||
|    ftime(&currSysTime); | ||||
|  | ||||
|    abstime.tv_sec = currSysTime.time; | ||||
|    abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|    abstime.tv_sec += 1; | ||||
|  | ||||
|    /* Here pthread_cond_timedwait should time out after one second. */ | ||||
|  | ||||
|    assert(pthread_mutex_lock(&mtx) == 0); | ||||
|  | ||||
|    assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); | ||||
|  | ||||
|    assert(pthread_mutex_unlock(&mtx) == 0); | ||||
|  | ||||
|    /* Here, the condition variable is signaled, but there are no | ||||
|       threads waiting on it. The signal should be lost and | ||||
|       the next pthread_cond_timedwait should time out too. */ | ||||
|  | ||||
|    assert(pthread_mutex_lock(&mtx) == 0); | ||||
|  | ||||
|    assert((rc = pthread_cond_signal(&cnd)) == 0); | ||||
|  | ||||
|    assert(pthread_mutex_unlock(&mtx) == 0); | ||||
|  | ||||
|    assert(pthread_mutex_lock(&mtx) == 0); | ||||
|  | ||||
|    abstime.tv_sec = currSysTime.time; | ||||
|    abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|    abstime.tv_sec += 1; | ||||
|  | ||||
|    assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); | ||||
|  | ||||
|    assert(pthread_mutex_unlock(&mtx) == 0); | ||||
|  | ||||
|    return 0; | ||||
| } | ||||
							
								
								
									
										137
									
								
								winsup/testsuite/winsup.api/pthread/condvar4.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								winsup/testsuite/winsup.api/pthread/condvar4.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| /* | ||||
|  * File: condvar4.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test PTHREAD_COND_INITIALIZER. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - Test basic CV function but starting with a static initialised | ||||
|  *   CV. | ||||
|  * | ||||
|  * Environment: | ||||
|  * -  | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - pthread_cond_timedwait returns 0. | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - pthread_cond_timedwait returns ETIMEDOUT. | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| typedef struct cvthing_t_ cvthing_t; | ||||
|  | ||||
| struct cvthing_t_ { | ||||
|   pthread_cond_t notbusy; | ||||
|   pthread_mutex_t lock; | ||||
|   int shared; | ||||
| }; | ||||
|  | ||||
| static cvthing_t cvthing = { | ||||
|   PTHREAD_COND_INITIALIZER, | ||||
|   PTHREAD_MUTEX_INITIALIZER, | ||||
|   0 | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|   NUMTHREADS = 2 | ||||
| }; | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   assert(pthread_mutex_lock(&cvthing.lock) == 0); | ||||
|  | ||||
|   cvthing.shared++; | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(pthread_cond_signal(&cvthing.notbusy) == 0); | ||||
|  | ||||
|   return (void *) 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t[NUMTHREADS]; | ||||
|   struct timespec abstime = { 0, 0 }; | ||||
|   struct timeb currSysTime; | ||||
|   const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|  | ||||
|   cvthing.shared = 0; | ||||
|  | ||||
|   assert((t[0] = pthread_self()) != NULL); | ||||
|  | ||||
|   assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); | ||||
|  | ||||
|   assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); | ||||
|  | ||||
|   /* get current system time */ | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   abstime.tv_sec += 5; | ||||
|  | ||||
|   assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT); | ||||
|    | ||||
|   assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER); | ||||
|  | ||||
|   assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); | ||||
|  | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   abstime.tv_sec += 5; | ||||
|  | ||||
|   while (! (cvthing.shared > 0)) | ||||
|     assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); | ||||
|  | ||||
|   assert(cvthing.shared > 0); | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_destroy(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(cvthing.lock == NULL); | ||||
|  | ||||
|   assert(pthread_cond_destroy(&cvthing.notbusy) == 0); | ||||
|  | ||||
|   assert(cvthing.notbusy == NULL); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										136
									
								
								winsup/testsuite/winsup.api/pthread/condvar5.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								winsup/testsuite/winsup.api/pthread/condvar5.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| /* | ||||
|  * File: condvar5.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test pthread_cond_broadcast. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - Test broadcast with one waiting CV. | ||||
|  * | ||||
|  * Environment: | ||||
|  * -  | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - pthread_cond_timedwait returns 0. | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - pthread_cond_timedwait returns ETIMEDOUT. | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| typedef struct cvthing_t_ cvthing_t; | ||||
|  | ||||
| struct cvthing_t_ { | ||||
|   pthread_cond_t notbusy; | ||||
|   pthread_mutex_t lock; | ||||
|   int shared; | ||||
| }; | ||||
|  | ||||
| static cvthing_t cvthing = { | ||||
|   PTHREAD_COND_INITIALIZER, | ||||
|   PTHREAD_MUTEX_INITIALIZER, | ||||
|   0 | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|   NUMTHREADS = 2 | ||||
| }; | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   assert(pthread_mutex_lock(&cvthing.lock) == 0); | ||||
|  | ||||
|   cvthing.shared++; | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); | ||||
|  | ||||
|   return (void *) 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t[NUMTHREADS]; | ||||
|   struct timespec abstime = { 0, 0 }; | ||||
|   struct timeb currSysTime; | ||||
|   const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|  | ||||
|   cvthing.shared = 0; | ||||
|  | ||||
|   assert((t[0] = pthread_self()) != NULL); | ||||
|  | ||||
|   assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); | ||||
|  | ||||
|   assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); | ||||
|  | ||||
|   /* get current system time */ | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   abstime.tv_sec += 5; | ||||
|  | ||||
|   assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT); | ||||
|    | ||||
|   assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER); | ||||
|  | ||||
|   assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); | ||||
|  | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   abstime.tv_sec += 5; | ||||
|  | ||||
|   while (! (cvthing.shared > 0)) | ||||
|     assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); | ||||
|  | ||||
|   assert(cvthing.shared > 0); | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_destroy(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(cvthing.lock == NULL); | ||||
|  | ||||
|   assert(pthread_cond_destroy(&cvthing.notbusy) == 0); | ||||
|  | ||||
|   assert(cvthing.notbusy == NULL); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										209
									
								
								winsup/testsuite/winsup.api/pthread/condvar6.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								winsup/testsuite/winsup.api/pthread/condvar6.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,209 @@ | ||||
| /* | ||||
|  * File:  | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test pthread_cond_broadcast. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - Test broadcast with NUMTHREADS (=5) waiting CVs. | ||||
|  * | ||||
|  * Environment: | ||||
|  * -  | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| /* | ||||
|  * Create NUMTHREADS threads in addition to the Main thread. | ||||
|  */ | ||||
| enum { | ||||
|   NUMTHREADS = 5 | ||||
| }; | ||||
|  | ||||
| typedef struct bag_t_ bag_t; | ||||
| struct bag_t_ { | ||||
|   int threadnum; | ||||
|   int started; | ||||
|   /* Add more per-thread state variables here */ | ||||
| }; | ||||
|  | ||||
| static bag_t threadbag[NUMTHREADS + 1]; | ||||
|  | ||||
| typedef struct cvthing_t_ cvthing_t; | ||||
|  | ||||
| struct cvthing_t_ { | ||||
|   pthread_cond_t notbusy; | ||||
|   pthread_mutex_t lock; | ||||
|   int shared; | ||||
| }; | ||||
|  | ||||
| static cvthing_t cvthing = { | ||||
|   PTHREAD_COND_INITIALIZER, | ||||
|   PTHREAD_MUTEX_INITIALIZER, | ||||
|   0 | ||||
| }; | ||||
|  | ||||
| static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; | ||||
|  | ||||
| static struct timespec abstime = { 0, 0 }; | ||||
|  | ||||
| static int awoken; | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   bag_t * bag = (bag_t *) arg; | ||||
|  | ||||
|   assert(bag == &threadbag[bag->threadnum]); | ||||
|   assert(bag->started == 0); | ||||
|   bag->started = 1; | ||||
|  | ||||
|   /* Wait for the start gun */ | ||||
|   assert(pthread_mutex_lock(&start_flag) == 0); | ||||
|   assert(pthread_mutex_unlock(&start_flag) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&cvthing.lock) == 0); | ||||
|  | ||||
|   while (! (cvthing.shared > 0)) | ||||
|     assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); | ||||
|  | ||||
|   assert(cvthing.shared > 0); | ||||
|  | ||||
|   awoken++; | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&cvthing.lock) == 0); | ||||
|  | ||||
|   return (void *) 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   int failed = 0; | ||||
|   int i; | ||||
|   pthread_t t[NUMTHREADS + 1]; | ||||
|  | ||||
|   struct timeb currSysTime; | ||||
|   const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|  | ||||
|   cvthing.shared = 0; | ||||
|  | ||||
|   assert((t[0] = pthread_self()) != NULL); | ||||
|  | ||||
|   assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); | ||||
|  | ||||
|   assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&start_flag) == 0); | ||||
|  | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   abstime.tv_sec += 5; | ||||
|  | ||||
|   assert((t[0] = pthread_self()) != NULL); | ||||
|  | ||||
|   awoken = 0; | ||||
|  | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     { | ||||
|       threadbag[i].started = 0; | ||||
|       threadbag[i].threadnum = i; | ||||
|       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); | ||||
|     } | ||||
|  | ||||
|   /* | ||||
|    * Code to control or munipulate child threads should probably go here. | ||||
|    */ | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&start_flag) == 0); | ||||
|  | ||||
|   /* | ||||
|    * Give threads time to start. | ||||
|    */ | ||||
|   Sleep(2000); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&cvthing.lock) == 0); | ||||
|  | ||||
|   cvthing.shared++; | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); | ||||
|  | ||||
|   /* | ||||
|    * Give threads time to complete. | ||||
|    */ | ||||
|   Sleep(2000); | ||||
|  | ||||
|   /*  | ||||
|    * Cleanup the CV. | ||||
|    */ | ||||
|    | ||||
|   assert(pthread_mutex_destroy(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(cvthing.lock == NULL); | ||||
|  | ||||
|   assert(pthread_cond_destroy(&cvthing.notbusy) == 0); | ||||
|  | ||||
|   assert(cvthing.notbusy == NULL); | ||||
|  | ||||
|   /* | ||||
|    * Standard check that all threads started. | ||||
|    */ | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     {  | ||||
|       failed = !threadbag[i].started; | ||||
|  | ||||
|       if (failed) | ||||
| 	{ | ||||
| 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   assert(!failed); | ||||
|  | ||||
|   /* | ||||
|    * Check any results here. | ||||
|    */ | ||||
|  | ||||
|   assert(awoken == NUMTHREADS); | ||||
|  | ||||
|   /* | ||||
|    * Success. | ||||
|    */ | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										221
									
								
								winsup/testsuite/winsup.api/pthread/condvar8.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								winsup/testsuite/winsup.api/pthread/condvar8.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,221 @@ | ||||
| /* | ||||
|  * File: condvar8.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test multiple pthread_cond_broadcasts. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Description: | ||||
|  * - Make NUMTHREADS threads wait on CV, broadcast signal them, and then repeat. | ||||
|  * | ||||
|  * Environment: | ||||
|  * -  | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * -  | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <sys/timeb.h> | ||||
|  | ||||
| /* | ||||
|  * Create NUMTHREADS threads in addition to the Main thread. | ||||
|  */ | ||||
| enum { | ||||
|   NUMTHREADS = 5 | ||||
| }; | ||||
|  | ||||
| typedef struct bag_t_ bag_t; | ||||
| struct bag_t_ { | ||||
|   int threadnum; | ||||
|   int started; | ||||
|   /* Add more per-thread state variables here */ | ||||
| }; | ||||
|  | ||||
| static bag_t threadbag[NUMTHREADS + 1]; | ||||
|  | ||||
| typedef struct cvthing_t_ cvthing_t; | ||||
|  | ||||
| struct cvthing_t_ { | ||||
|   pthread_cond_t notbusy; | ||||
|   pthread_mutex_t lock; | ||||
|   int shared; | ||||
| }; | ||||
|  | ||||
| static cvthing_t cvthing = { | ||||
|   PTHREAD_COND_INITIALIZER, | ||||
|   PTHREAD_MUTEX_INITIALIZER, | ||||
|   0 | ||||
| }; | ||||
|  | ||||
| static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; | ||||
|  | ||||
| static struct timespec abstime = { 0, 0 }; | ||||
|  | ||||
| static int awoken; | ||||
|  | ||||
| static void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   bag_t * bag = (bag_t *) arg; | ||||
|  | ||||
|   assert(bag == &threadbag[bag->threadnum]); | ||||
|   assert(bag->started == 0); | ||||
|   bag->started = 1; | ||||
|  | ||||
|   /* Wait for the start gun */ | ||||
|   assert(pthread_mutex_lock(&start_flag) == 0); | ||||
|   assert(pthread_mutex_unlock(&start_flag) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&cvthing.lock) == 0); | ||||
|  | ||||
|   pthread_cleanup_push((__cleanup_routine_type)pthread_mutex_unlock, | ||||
| 		       (void *) &cvthing.lock); | ||||
|  | ||||
|   while (! (cvthing.shared > 0)) | ||||
|     assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); | ||||
|  | ||||
|   pthread_cleanup_pop(0); | ||||
|  | ||||
|   assert(cvthing.shared > 0); | ||||
|  | ||||
|   awoken++; | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&cvthing.lock) == 0); | ||||
|  | ||||
|   return (void *) 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   int failed = 0; | ||||
|   int i; | ||||
|   int first, last; | ||||
|   pthread_t t[NUMTHREADS + 1]; | ||||
|  | ||||
|   struct timeb currSysTime; | ||||
|   const DWORD NANOSEC_PER_MILLISEC = 1000000; | ||||
|  | ||||
|   assert((t[0] = pthread_self()) != NULL); | ||||
|  | ||||
|   assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); | ||||
|  | ||||
|   assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); | ||||
|  | ||||
|   ftime(&currSysTime); | ||||
|  | ||||
|   abstime.tv_sec = currSysTime.time; | ||||
|   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; | ||||
|  | ||||
|   abstime.tv_sec += 10; | ||||
|  | ||||
|   assert((t[0] = pthread_self()) != NULL); | ||||
|  | ||||
|   awoken = 0; | ||||
|  | ||||
|   for (first = 1, last = NUMTHREADS / 2; | ||||
|        first < NUMTHREADS; | ||||
|        first = last + 1, last = NUMTHREADS) | ||||
|     { | ||||
|       assert(pthread_mutex_lock(&start_flag) == 0); | ||||
|  | ||||
|       for (i = first; i <= last; i++) | ||||
| 	{ | ||||
| 	  threadbag[i].started = 0; | ||||
| 	  threadbag[i].threadnum = i; | ||||
| 	  assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); | ||||
| 	  assert(pthread_detach(t[i]) == 0); | ||||
| 	} | ||||
|  | ||||
|       /* | ||||
|        * Code to control or munipulate child threads should probably go here. | ||||
|        */ | ||||
|       cvthing.shared = 0; | ||||
|  | ||||
|       assert(pthread_mutex_unlock(&start_flag) == 0); | ||||
|  | ||||
|       /* | ||||
|        * Give threads time to start. | ||||
|        */ | ||||
|       Sleep(1000); | ||||
|  | ||||
|       assert(pthread_mutex_lock(&cvthing.lock) == 0); | ||||
|  | ||||
|       cvthing.shared++; | ||||
|  | ||||
|       assert(pthread_mutex_unlock(&cvthing.lock) == 0); | ||||
|  | ||||
|       assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); | ||||
|  | ||||
|       /* | ||||
|        * Give threads time to complete. | ||||
|        */ | ||||
|       Sleep(1000); | ||||
|  | ||||
|       assert(awoken == (i - 1)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|   /* | ||||
|    * Standard check that all threads started. | ||||
|    */ | ||||
|   for (i = 1; i <= NUMTHREADS; i++) | ||||
|     {  | ||||
|       failed = !threadbag[i].started; | ||||
|  | ||||
|       if (failed) | ||||
|         { | ||||
|           fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   /*  | ||||
|    * Cleanup the CV. | ||||
|    */ | ||||
|    | ||||
|   assert(pthread_mutex_destroy(&cvthing.lock) == 0); | ||||
|  | ||||
|   assert(cvthing.lock == NULL); | ||||
|  | ||||
|   assert(pthread_cond_destroy(&cvthing.notbusy) == 0); | ||||
|  | ||||
|   assert(cvthing.notbusy == NULL); | ||||
|  | ||||
|   assert(!failed); | ||||
|  | ||||
|   /* | ||||
|    * Check any results here. | ||||
|    */ | ||||
|  | ||||
|   assert(awoken == NUMTHREADS); | ||||
|  | ||||
|   /* | ||||
|    * Success. | ||||
|    */ | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										62
									
								
								winsup/testsuite/winsup.api/pthread/count1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								winsup/testsuite/winsup.api/pthread/count1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| /* | ||||
|  * count1.c | ||||
|  * | ||||
|  * Description: | ||||
|  * Test some basic assertions about the number of threads at runtime. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| #if ! defined (__MINGW32__) || defined (__MSVCRT__) | ||||
| #define NUMTHREADS (60) | ||||
| #else | ||||
| #define NUMTHREADS (59) | ||||
| #endif | ||||
|  | ||||
| static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; | ||||
| static pthread_t threads[NUMTHREADS]; | ||||
| static unsigned numThreads = 0; | ||||
|  | ||||
| void * | ||||
| myfunc(void *arg) | ||||
| { | ||||
|   pthread_mutex_lock(&lock); | ||||
|   numThreads++; | ||||
|   pthread_mutex_unlock(&lock); | ||||
|  | ||||
|   Sleep(1000); | ||||
|   return 0; | ||||
| } | ||||
| int | ||||
| main() | ||||
| { | ||||
|   int i; | ||||
|   int maxThreads = sizeof(threads) / sizeof(pthread_t); | ||||
|  | ||||
|   /* | ||||
|    * Spawn NUMTHREADS threads. Each thread should increment the | ||||
|    * numThreads variable, sleep for one second. | ||||
|    */ | ||||
|   for (i = 0; i < maxThreads; i++) | ||||
|     { | ||||
|       assert(pthread_create(&threads[i], NULL, myfunc, 0) == 0); | ||||
|     } | ||||
|    | ||||
|   /* | ||||
|    * Wait for all the threads to exit. | ||||
|    */ | ||||
|   for (i = 0; i < maxThreads; i++) | ||||
|     { | ||||
|       assert(pthread_join(threads[i], NULL) == 0); | ||||
|     } | ||||
|  | ||||
|   /*  | ||||
|    * Check the number of threads created. | ||||
|    */ | ||||
|   assert((int) numThreads == maxThreads); | ||||
|    | ||||
|   /* | ||||
|    * Success. | ||||
|    */ | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										34
									
								
								winsup/testsuite/winsup.api/pthread/create1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								winsup/testsuite/winsup.api/pthread/create1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * create1.c | ||||
|  * | ||||
|  * Description: | ||||
|  * Create a thread and check that it ran. | ||||
|  * | ||||
|  * Depends on API functions: None. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| static int washere = 0; | ||||
|  | ||||
| void * func(void * arg) | ||||
| { | ||||
|   washere = 1; | ||||
|   return 0;  | ||||
| } | ||||
|   | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t; | ||||
|  | ||||
|   assert(pthread_create(&t, NULL, func, NULL) == 0); | ||||
|  | ||||
|   /* A dirty hack, but we cannot rely on pthread_join in this | ||||
|      primitive test. */ | ||||
|   Sleep(2000); | ||||
|  | ||||
|   assert(washere == 1); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										74
									
								
								winsup/testsuite/winsup.api/pthread/create2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								winsup/testsuite/winsup.api/pthread/create2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| /* | ||||
|  * File: create2.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test that threads have a Win32 handle when started. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * - Statistical, not absolute (depends on sample size). | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Description: | ||||
|  * - | ||||
|  * | ||||
|  * Environment: | ||||
|  * - | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * - | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| const int NUMTHREADS = 10000; | ||||
|  | ||||
| static int washere = 0; | ||||
|  | ||||
| void * func(void * arg) | ||||
| { | ||||
|   washere = 1; | ||||
|   return (void *) 0;  | ||||
| } | ||||
|   | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t; | ||||
|   pthread_attr_t attr; | ||||
|   void * result = NULL; | ||||
|   int i; | ||||
|  | ||||
|   pthread_attr_init(&attr); | ||||
|   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); | ||||
|  | ||||
|   for (i = 0; i < NUMTHREADS; i++) | ||||
|     { | ||||
|       washere = 0; | ||||
|       assert(pthread_create(&t, &attr, func, NULL) == 0); | ||||
|       pthread_join(t, &result); | ||||
|       assert(washere == 1); | ||||
|     } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										34
									
								
								winsup/testsuite/winsup.api/pthread/equal1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								winsup/testsuite/winsup.api/pthread/equal1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * Test for pthread_equal. | ||||
|  * | ||||
|  * Depends on functions: pthread_create(). | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| void * func(void * arg) | ||||
| { | ||||
|   Sleep(2000); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int  | ||||
| main() | ||||
| { | ||||
|   pthread_t t1, t2; | ||||
|  | ||||
|   assert(pthread_create(&t1, NULL, func, (void *) 1) == 0); | ||||
|  | ||||
|   assert(pthread_create(&t2, NULL, func, (void *) 2) == 0); | ||||
|  | ||||
|   assert(pthread_equal(t1, t2) == 0); | ||||
|  | ||||
|   assert(pthread_equal(t1,t1) != 0); | ||||
|  | ||||
|   /* This is a hack. We don't want to rely on pthread_join | ||||
|      yet if we can help it. */ | ||||
|    Sleep(4000); | ||||
|  | ||||
|   /* Success. */ | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										18
									
								
								winsup/testsuite/winsup.api/pthread/exit1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								winsup/testsuite/winsup.api/pthread/exit1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| /* | ||||
|  * Test for pthread_exit(). | ||||
|  * | ||||
|  * Depends on API functions: None. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| int | ||||
| main(int argc, char * argv[]) | ||||
| { | ||||
| 	/* A simple test first. */ | ||||
| 	pthread_exit((void *) 0); | ||||
|  | ||||
| 	/* Not reached */ | ||||
| 	assert(0); | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										30
									
								
								winsup/testsuite/winsup.api/pthread/exit2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								winsup/testsuite/winsup.api/pthread/exit2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| /* | ||||
|  * Test for pthread_exit(). | ||||
|  * | ||||
|  * Depends on API functions: | ||||
|  *	pthread_create() | ||||
|  *	pthread_exit() | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| void * | ||||
| func(void * arg) | ||||
| { | ||||
| 	pthread_exit(arg); | ||||
|  | ||||
| 	/* Never reached. */ | ||||
| 	assert(0); | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char * argv[]) | ||||
| { | ||||
|   pthread_t t; | ||||
|  | ||||
|   assert(pthread_create(&t, NULL, func, (void *) NULL) == 0); | ||||
|  | ||||
|   Sleep(1000); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										34
									
								
								winsup/testsuite/winsup.api/pthread/exit3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								winsup/testsuite/winsup.api/pthread/exit3.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * Test for pthread_exit(). | ||||
|  * | ||||
|  * Depends on API functions: pthread_create(). | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| void * | ||||
| func(void * arg) | ||||
| { | ||||
| 	pthread_exit(arg); | ||||
|  | ||||
| 	/* Never reached. */ | ||||
| 	assert(0); | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char * argv[]) | ||||
| { | ||||
| 	pthread_t id[4]; | ||||
| 	int i; | ||||
|  | ||||
| 	/* Create a few threads and then exit. */ | ||||
| 	for (i = 0; i < 4; i++) | ||||
| 	  { | ||||
| 	    assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); | ||||
| 	  } | ||||
|  | ||||
| 	Sleep(1000); | ||||
|  | ||||
| 	/* Success. */ | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										99
									
								
								winsup/testsuite/winsup.api/pthread/inherit1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								winsup/testsuite/winsup.api/pthread/inherit1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| /* | ||||
|  * File: inherit1.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test thread priority inheritance. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * -  | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Description: | ||||
|  * - | ||||
|  * | ||||
|  * Environment: | ||||
|  * - | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * - | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| void * func(void * arg) | ||||
| { | ||||
|   int policy; | ||||
|   struct sched_param param; | ||||
|  | ||||
|   assert(pthread_getschedparam(pthread_self(), &policy, ¶m) == 0); | ||||
|   return (void *) param.sched_priority; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t; | ||||
|   pthread_t mainThread = pthread_self(); | ||||
|   pthread_attr_t attr; | ||||
|   void * result = NULL; | ||||
|   struct sched_param param; | ||||
|   struct sched_param mainParam; | ||||
|   int maxPrio; | ||||
|   int minPrio; | ||||
|   int prio; | ||||
|   int policy; | ||||
|   int inheritsched = -1; | ||||
|  | ||||
|   assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1); | ||||
|   assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1); | ||||
|  | ||||
|   assert(pthread_attr_init(&attr) == 0); | ||||
|   assert(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) == 0); | ||||
|   assert(pthread_attr_getinheritsched(&attr, &inheritsched) == 0); | ||||
|   assert(inheritsched == PTHREAD_INHERIT_SCHED); | ||||
|  | ||||
|   for (prio = minPrio; prio < maxPrio; prio++) | ||||
|     { | ||||
|       mainParam.sched_priority = prio; | ||||
|  | ||||
|       /* Change the main thread priority */ | ||||
|       assert(pthread_setschedparam(mainThread, SCHED_OTHER, &mainParam) == 0); | ||||
|       assert(pthread_getschedparam(mainThread, &policy, &mainParam) == 0); | ||||
|       assert(policy == SCHED_OTHER); | ||||
|       assert(mainParam.sched_priority == prio); | ||||
|  | ||||
|       for (param.sched_priority = prio; | ||||
|            param.sched_priority <= maxPrio; | ||||
|            param.sched_priority++) | ||||
|         { | ||||
|           /* The new thread create should ignore this new priority */ | ||||
|           assert(pthread_attr_setschedparam(&attr, ¶m) == 0); | ||||
|           assert(pthread_create(&t, &attr, func, NULL) == 0); | ||||
|           pthread_join(t, &result); | ||||
|           assert((int) result == mainParam.sched_priority); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										40
									
								
								winsup/testsuite/winsup.api/pthread/join0.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								winsup/testsuite/winsup.api/pthread/join0.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * Test for pthread_join(). | ||||
|  * | ||||
|  * Depends on API functions: pthread_create(), pthread_exit(). | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| void * | ||||
| func(void * arg) | ||||
| { | ||||
|   Sleep(2000); | ||||
|  | ||||
|   pthread_exit(arg); | ||||
|  | ||||
|   /* Never reached. */ | ||||
|   exit(1); | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char * argv[]) | ||||
| { | ||||
|   pthread_t id; | ||||
|   int result; | ||||
|  | ||||
|   /* Create a single thread and wait for it to exit. */ | ||||
|   assert(pthread_create(&id, NULL, func, (void *) 123) == 0); | ||||
|  | ||||
|   assert(pthread_join(id, (void **) &result) == 0); | ||||
|  | ||||
| #if ! defined (__MINGW32__) || defined (__MSVCRT__) | ||||
|   assert(result == 123); | ||||
| #else | ||||
| # warning pthread_join not fully supported in this configuration. | ||||
|   assert(result == 0); | ||||
| #endif | ||||
|  | ||||
|   /* Success. */ | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										51
									
								
								winsup/testsuite/winsup.api/pthread/join1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								winsup/testsuite/winsup.api/pthread/join1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| /* | ||||
|  * Test for pthread_join(). | ||||
|  * | ||||
|  * Depends on API functions: pthread_create(), pthread_join(), pthread_exit(). | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| void * | ||||
| func(void * arg) | ||||
| { | ||||
|     int i = (int) arg; | ||||
|  | ||||
|     Sleep(i * 500); | ||||
|  | ||||
|     pthread_exit(arg); | ||||
|  | ||||
|     /* Never reached. */ | ||||
|     exit(1); | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char * argv[]) | ||||
| { | ||||
| 	pthread_t id[4]; | ||||
| 	int i; | ||||
| 	int result; | ||||
|  | ||||
| 	/* Create a few threads and then exit. */ | ||||
| 	for (i = 0; i < 4; i++) | ||||
| 	  { | ||||
| 	    assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); | ||||
| 	  } | ||||
|  | ||||
| 	/* Some threads will finish before they are joined, some after. */ | ||||
| 	Sleep(1000); | ||||
|  | ||||
| 	for (i = 0; i < 4; i++) | ||||
| 	  { | ||||
| 	    assert(pthread_join(id[i], (void **) &result) == 0); | ||||
| #if ! defined (__MINGW32__) || defined (__MSVCRT__) | ||||
| 	    assert(result == i); | ||||
| #else | ||||
| # warning pthread_join not fully supported in this configuration. | ||||
| 	    assert(result == 0); | ||||
| #endif | ||||
| 	  } | ||||
|  | ||||
| 	/* Success. */ | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										41
									
								
								winsup/testsuite/winsup.api/pthread/join2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								winsup/testsuite/winsup.api/pthread/join2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| /* | ||||
|  * Test for pthread_join() returning return value from threads. | ||||
|  * | ||||
|  * Depends on API functions: pthread_create(). | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| void * | ||||
| func(void * arg) | ||||
| { | ||||
| 	Sleep(1000); | ||||
| 	return arg; | ||||
| } | ||||
|  | ||||
| int | ||||
| main(int argc, char * argv[]) | ||||
| { | ||||
| 	pthread_t id[4]; | ||||
| 	int i; | ||||
| 	int result; | ||||
|  | ||||
| 	/* Create a few threads and then exit. */ | ||||
| 	for (i = 0; i < 4; i++) | ||||
| 	  { | ||||
| 	    assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); | ||||
| 	  } | ||||
|  | ||||
| 	for (i = 0; i < 4; i++) | ||||
| 	  { | ||||
| 	    assert(pthread_join(id[i], (void **) &result) == 0); | ||||
| #if ! defined (__MINGW32__) || defined (__MSVCRT__) | ||||
| 	    /* CRTDLL _beginthread doesn't support return value, so | ||||
| 	       the assertion is guaranteed to fail. */ | ||||
| 	    assert(result == i); | ||||
| #endif | ||||
| 	  } | ||||
|  | ||||
| 	/* Success. */ | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										36
									
								
								winsup/testsuite/winsup.api/pthread/mutex1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								winsup/testsuite/winsup.api/pthread/mutex1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| /*  | ||||
|  * mutex1.c | ||||
|  * | ||||
|  * Create a simple mutex object, lock it, and then unlock it again. | ||||
|  * This is the simplest test of the pthread mutex family that we can do. | ||||
|  * | ||||
|  * Depends on API functions: | ||||
|  * 	pthread_mutex_init() | ||||
|  *	pthread_mutex_lock() | ||||
|  *	pthread_mutex_unlock() | ||||
|  *	pthread_mutex_destroy() | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| pthread_mutex_t mutex = NULL; | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   assert(mutex == NULL); | ||||
|  | ||||
|   assert(pthread_mutex_init(&mutex, NULL) == 0); | ||||
|  | ||||
|   assert(mutex != NULL); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_destroy(&mutex) == 0); | ||||
|  | ||||
|   assert(mutex == NULL); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										42
									
								
								winsup/testsuite/winsup.api/pthread/mutex1r.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								winsup/testsuite/winsup.api/pthread/mutex1r.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| /*  | ||||
|  * mutex1r.c | ||||
|  * | ||||
|  * As for mutex1.c but with type set to PTHREAD_MUTEX_RECURSIVE. | ||||
|  * | ||||
|  * Create a simple mutex object, lock it, unlock it, then destroy it. | ||||
|  * This is the simplest test of the pthread mutex family that we can do. | ||||
|  * | ||||
|  * Depends on API functions: | ||||
|  *	pthread_mutexattr_settype() | ||||
|  * 	pthread_mutex_init() | ||||
|  *	pthread_mutex_destroy() | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| pthread_mutex_t mutex = NULL; | ||||
| pthread_mutexattr_t mxAttr; | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   assert(pthread_mutexattr_init(&mxAttr) == 0); | ||||
|  | ||||
|   assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); | ||||
|  | ||||
|   assert(mutex == NULL); | ||||
|  | ||||
|   assert(pthread_mutex_init(&mutex, &mxAttr) == 0); | ||||
|  | ||||
|   assert(mutex != NULL); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_destroy(&mutex) == 0); | ||||
|  | ||||
|   assert(mutex == NULL); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										34
									
								
								winsup/testsuite/winsup.api/pthread/mutex2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								winsup/testsuite/winsup.api/pthread/mutex2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /*  | ||||
|  * mutex2.c | ||||
|  * | ||||
|  * Declare a static mutex object, lock it,  | ||||
|  * and then unlock it again. | ||||
|  * | ||||
|  * Depends on API functions:  | ||||
|  *	pthread_mutex_lock() | ||||
|  *	pthread_mutex_unlock() | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|   | ||||
| pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   assert(mutex == PTHREAD_MUTEX_INITIALIZER); | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|  | ||||
|   assert(mutex != PTHREAD_MUTEX_INITIALIZER); | ||||
|  | ||||
|   assert(mutex != NULL); | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_destroy(&mutex) == 0); | ||||
|  | ||||
|   assert(mutex == NULL); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										43
									
								
								winsup/testsuite/winsup.api/pthread/mutex3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								winsup/testsuite/winsup.api/pthread/mutex3.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /*  | ||||
|  * mutex3.c | ||||
|  * | ||||
|  * Declare a static mutex object, lock it, trylock it,  | ||||
|  * and then unlock it again. | ||||
|  * | ||||
|  * Depends on API functions:  | ||||
|  *	pthread_mutex_lock() | ||||
|  *	pthread_mutex_trylock() | ||||
|  *	pthread_mutex_unlock() | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|   | ||||
| pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; | ||||
|  | ||||
| static int washere = 0; | ||||
|  | ||||
| void * func(void * arg) | ||||
| { | ||||
|   assert(pthread_mutex_trylock(&mutex1) == EBUSY); | ||||
|  | ||||
|   washere = 1; | ||||
|  | ||||
|   return 0;  | ||||
| } | ||||
|   | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t; | ||||
|  | ||||
|   assert(pthread_mutex_lock(&mutex1) == 0); | ||||
|  | ||||
|   assert(pthread_create(&t, NULL, func, NULL) == 0); | ||||
|   assert(pthread_join(t, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_mutex_unlock(&mutex1) == 0); | ||||
|  | ||||
|   assert(washere == 1); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										68
									
								
								winsup/testsuite/winsup.api/pthread/mutex6r.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								winsup/testsuite/winsup.api/pthread/mutex6r.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| /*  | ||||
|  * mutex6r.c | ||||
|  * | ||||
|  * Tests PTHREAD_MUTEX_RECURSIVE mutex type. | ||||
|  * Thread locks mutex twice (recursive lock). | ||||
|  * Both locks and unlocks should succeed. | ||||
|  * | ||||
|  * Depends on API functions:  | ||||
|  *      pthread_create() | ||||
|  *      pthread_join() | ||||
|  *      pthread_mutexattr_init() | ||||
|  *      pthread_mutexattr_destroy() | ||||
|  *      pthread_mutexattr_settype() | ||||
|  *      pthread_mutexattr_gettype() | ||||
|  *      pthread_mutex_init() | ||||
|  *      pthread_mutex_destroy() | ||||
|  *	pthread_mutex_lock() | ||||
|  *	pthread_mutex_unlock() | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| static int lockCount = 0; | ||||
|  | ||||
| static pthread_mutex_t mutex; | ||||
| static pthread_mutexattr_t mxAttr; | ||||
|  | ||||
| void * locker(void * arg) | ||||
| { | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|   lockCount++; | ||||
|   assert(pthread_mutex_lock(&mutex) == 0); | ||||
|   lockCount++; | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|   assert(pthread_mutex_unlock(&mutex) == 0); | ||||
|  | ||||
|   return (void *) 555; | ||||
| } | ||||
|   | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t; | ||||
|   int result = 0; | ||||
|   int mxType = -1; | ||||
|  | ||||
|   assert(pthread_mutexattr_init(&mxAttr) == 0); | ||||
|   assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); | ||||
|   assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); | ||||
|   assert(mxType == PTHREAD_MUTEX_RECURSIVE); | ||||
|  | ||||
|   assert(pthread_mutex_init(&mutex, &mxAttr) == 0); | ||||
|  | ||||
|   assert(pthread_create(&t, NULL, locker, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_join(t, (void **) &result) == 0); | ||||
|   assert(result == 555); | ||||
|  | ||||
|   assert(lockCount == 2); | ||||
|  | ||||
|   assert(pthread_mutex_destroy(&mutex) == 0); | ||||
|   assert(pthread_mutexattr_destroy(&mxAttr) == 0); | ||||
|  | ||||
|   exit(0); | ||||
|  | ||||
|   /* Never reached */ | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										45
									
								
								winsup/testsuite/winsup.api/pthread/once1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								winsup/testsuite/winsup.api/pthread/once1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /* | ||||
|  * once1.c | ||||
|  * | ||||
|  * Create a static pthread_once and test that it calls myfunc once. | ||||
|  * | ||||
|  * Depends on API functions: | ||||
|  *	pthread_once() | ||||
|  *	pthread_create() | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| pthread_once_t once = PTHREAD_ONCE_INIT; | ||||
|  | ||||
| static int washere = 0; | ||||
|  | ||||
| void | ||||
| myfunc(void) | ||||
| { | ||||
|   washere++; | ||||
| } | ||||
|  | ||||
| void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|    assert(pthread_once(&once, myfunc) == 0); | ||||
|  | ||||
|    return 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t1, t2; | ||||
|    | ||||
|   assert(pthread_create(&t1, NULL, mythread, NULL) == 0); | ||||
|  | ||||
|   assert(pthread_create(&t2, NULL, mythread, NULL) == 0); | ||||
|  | ||||
|   Sleep(2000); | ||||
|  | ||||
|   assert(washere == 1); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										78
									
								
								winsup/testsuite/winsup.api/pthread/priority1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								winsup/testsuite/winsup.api/pthread/priority1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| /* | ||||
|  * File: priority1.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test thread priority explicit setting using thread attribute. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * -  | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Description: | ||||
|  * - | ||||
|  * | ||||
|  * Environment: | ||||
|  * - | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * - | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| void * func(void * arg) | ||||
| { | ||||
|   int policy; | ||||
|   struct sched_param param; | ||||
|  | ||||
|   assert(pthread_getschedparam(pthread_self(), &policy, ¶m) == 0); | ||||
|   assert(policy == SCHED_OTHER); | ||||
|   return (void *) param.sched_priority; | ||||
| } | ||||
|   | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t; | ||||
|   pthread_attr_t attr; | ||||
|   void * result = NULL; | ||||
|   struct sched_param param; | ||||
|   int maxPrio = sched_get_priority_max(SCHED_OTHER); | ||||
|   int minPrio = sched_get_priority_min(SCHED_OTHER); | ||||
|  | ||||
|   assert(pthread_attr_init(&attr) == 0); | ||||
|   assert(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0); | ||||
|  | ||||
|   for (param.sched_priority = minPrio; | ||||
|        param.sched_priority <= maxPrio; | ||||
|        param.sched_priority++) | ||||
|     { | ||||
|       assert(pthread_attr_setschedparam(&attr, ¶m) == 0); | ||||
|       assert(pthread_create(&t, &attr, func, NULL) == 0); | ||||
|       pthread_join(t, &result); | ||||
|       assert((int) result == param.sched_priority); | ||||
|     } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										80
									
								
								winsup/testsuite/winsup.api/pthread/priority2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								winsup/testsuite/winsup.api/pthread/priority2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /* | ||||
|  * File: priority2.c | ||||
|  * | ||||
|  * Test Synopsis: | ||||
|  * - Test thread priority setting after creation. | ||||
|  * | ||||
|  * Test Method (Validation or Falsification): | ||||
|  * -  | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * - | ||||
|  * | ||||
|  * Description: | ||||
|  * - | ||||
|  * | ||||
|  * Environment: | ||||
|  * - | ||||
|  * | ||||
|  * Input: | ||||
|  * - None. | ||||
|  * | ||||
|  * Output: | ||||
|  * - File name, Line number, and failed expression on failure. | ||||
|  * - No output on success. | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * - | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - Process returns zero exit status. | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - Process returns non-zero exit status. | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| pthread_mutex_t startMx = PTHREAD_MUTEX_INITIALIZER; | ||||
|  | ||||
| void * func(void * arg) | ||||
| { | ||||
|   int policy; | ||||
|   struct sched_param param; | ||||
|  | ||||
|   assert(pthread_mutex_lock(&startMx) == 0); | ||||
|   assert(pthread_getschedparam(pthread_self(), &policy, ¶m) == 0); | ||||
|   assert(pthread_mutex_unlock(&startMx) == 0); | ||||
|   assert(policy == SCHED_OTHER); | ||||
|   return (void *) param.sched_priority; | ||||
| } | ||||
|   | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t; | ||||
|   void * result = NULL; | ||||
|   struct sched_param param; | ||||
|   int maxPrio = sched_get_priority_max(SCHED_OTHER); | ||||
|   int minPrio = sched_get_priority_min(SCHED_OTHER); | ||||
|  | ||||
|   for (param.sched_priority = minPrio; | ||||
|        param.sched_priority <= maxPrio; | ||||
|        param.sched_priority++) | ||||
|     { | ||||
|       assert(pthread_mutex_lock(&startMx) == 0); | ||||
|       assert(pthread_create(&t, NULL, func, NULL) == 0); | ||||
|       assert(pthread_setschedparam(t, SCHED_OTHER, ¶m) == 0); | ||||
|       assert(pthread_mutex_unlock(&startMx) == 0); | ||||
|       pthread_join(t, &result); | ||||
|       assert((int) result == param.sched_priority); | ||||
|     } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										26
									
								
								winsup/testsuite/winsup.api/pthread/self1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								winsup/testsuite/winsup.api/pthread/self1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| /* | ||||
|  * self1.c | ||||
|  * | ||||
|  * Test for pthread_self(). | ||||
|  * | ||||
|  * Depends on API functions: | ||||
|  *	pthread_self() | ||||
|  * | ||||
|  * Implicitly depends on: | ||||
|  *	pthread_getspecific() | ||||
|  *	pthread_setspecific() | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
|  | ||||
| int | ||||
| main(int argc, char * argv[]) | ||||
| { | ||||
| 	/* | ||||
| 	 * This should always succeed unless the system has no | ||||
| 	 * resources (memory) left. | ||||
| 	 */ | ||||
| 	assert(pthread_self() != NULL); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										46
									
								
								winsup/testsuite/winsup.api/pthread/self2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								winsup/testsuite/winsup.api/pthread/self2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /* | ||||
|  * self2.c | ||||
|  * | ||||
|  * Test for pthread_self(). | ||||
|  * | ||||
|  * Depends on API functions: | ||||
|  *	pthread_create() | ||||
|  *	pthread_self() | ||||
|  * | ||||
|  * Implicitly depends on: | ||||
|  *	pthread_getspecific() | ||||
|  *	pthread_setspecific() | ||||
|  */ | ||||
|  | ||||
| #include "test.h" | ||||
| #include <string.h> | ||||
|  | ||||
| static pthread_t me; | ||||
|  | ||||
| void * | ||||
| entry(void * arg) | ||||
| { | ||||
|   me = pthread_self(); | ||||
|  | ||||
|   return arg; | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   pthread_t t; | ||||
|  | ||||
|   assert(pthread_create(&t, NULL, entry, NULL) == 0); | ||||
|  | ||||
|   Sleep(2000); | ||||
|  | ||||
|   /* | ||||
|    * Not much more we can do here but bytewise compare t with | ||||
|    * what pthread_self returned. | ||||
|    */ | ||||
|   assert(t == me); | ||||
|   assert(memcmp((const void *) t, (const void *) me, sizeof t) == 0); | ||||
|  | ||||
|   /* Success. */ | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										99
									
								
								winsup/testsuite/winsup.api/pthread/test.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								winsup/testsuite/winsup.api/pthread/test.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| /*  | ||||
|  * test.h | ||||
|  * | ||||
|  * Useful definitions and declarations for tests. | ||||
|  */ | ||||
|  | ||||
| #ifndef _PTHREAD_TEST_H_ | ||||
| #define _PTHREAD_TEST_H_ | ||||
|  | ||||
| #include "pthread.h" | ||||
| #include "sched.h" | ||||
| #include "semaphore.h" | ||||
| #include <stdio.h> | ||||
| #include <windows.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| /* #define assert(x) do { fprint (stderr, "assertion failed\n"); exit(1) } while (0) */ | ||||
|  | ||||
| char * error_string[] = { | ||||
|   "ZERO_or_EOK", | ||||
|   "EPERM", | ||||
|   "ENOFILE_or_ENOENT", | ||||
|   "ESRCH", | ||||
|   "EINTR", | ||||
|   "EIO", | ||||
|   "ENXIO", | ||||
|   "E2BIG", | ||||
|   "ENOEXEC", | ||||
|   "EBADF", | ||||
|   "ECHILD", | ||||
|   "EAGAIN", | ||||
|   "ENOMEM", | ||||
|   "EACCES", | ||||
|   "EFAULT", | ||||
|   "UNKNOWN_15", | ||||
|   "EBUSY", | ||||
|   "EEXIST", | ||||
|   "EXDEV", | ||||
|   "ENODEV", | ||||
|   "ENOTDIR", | ||||
|   "EISDIR", | ||||
|   "EINVAL", | ||||
|   "ENFILE", | ||||
|   "EMFILE", | ||||
|   "ENOTTY", | ||||
|   "UNKNOWN_26", | ||||
|   "EFBIG", | ||||
|   "ENOSPC", | ||||
|   "ESPIPE", | ||||
|   "EROFS", | ||||
|   "EMLINK", | ||||
|   "EPIPE", | ||||
|   "EDOM", | ||||
|   "ERANGE", | ||||
|   "UNKNOWN_35", | ||||
|   "EDEADLOCK_or_EDEADLK", | ||||
|   "UNKNOWN_37", | ||||
|   "ENAMETOOLONG", | ||||
|   "ENOLCK", | ||||
|   "ENOSYS", | ||||
|   "ENOTEMPTY", | ||||
|   "EILSEQ", | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * The Mingw32 assert macro calls the CRTDLL _assert function | ||||
|  * which pops up a dialog. We want to run in batch mode so | ||||
|  * we define our own assert macro. | ||||
|  */ | ||||
| #ifdef assert | ||||
| # undef assert | ||||
| #endif | ||||
|  | ||||
| #ifdef NDEBUG | ||||
|  | ||||
| # define assert(e) ((void)0) | ||||
|  | ||||
| #else /* NDEBUG */ | ||||
|  | ||||
| #ifndef ASSERT_TRACE | ||||
| # define ASSERT_TRACE 0 | ||||
| #else | ||||
| # undef ASSERT_TRACE | ||||
| # define ASSERT_TRACE 1 | ||||
| #endif | ||||
|  | ||||
| # define assert(e) \ | ||||
|    ((e) ? ((ASSERT_TRACE) ? fprintf(stderr, \ | ||||
|                                     "Assertion succeeded: (%s), file %s, line %d\n", \ | ||||
| 			            #e, __FILE__, (int) __LINE__), \ | ||||
| 	                            fflush(stderr) : \ | ||||
|                              0) : \ | ||||
|           (fprintf(stderr, "Assertion failed: (%s), file %s, line %d\n", \ | ||||
|                    #e, __FILE__, (int) __LINE__), exit(1), 0)) | ||||
|  | ||||
| #endif /* NDEBUG */ | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										170
									
								
								winsup/testsuite/winsup.api/pthread/tsd1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								winsup/testsuite/winsup.api/pthread/tsd1.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,170 @@ | ||||
| /* | ||||
|  * tsd1.c | ||||
|  * | ||||
|  * Test Thread Specific Data (TSD) key creation and destruction. | ||||
|  * | ||||
|  * Description: | ||||
|  * -  | ||||
|  * | ||||
|  * Test Method (validation or falsification): | ||||
|  * - validation | ||||
|  * | ||||
|  * Requirements Tested: | ||||
|  * - keys are created for each existing thread including the main thread | ||||
|  * - keys are created for newly created threads | ||||
|  * - keys are thread specific | ||||
|  * - destroy routine is called on each thread exit including the main thread | ||||
|  * | ||||
|  * Features Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Cases Tested: | ||||
|  * -  | ||||
|  * | ||||
|  * Environment: | ||||
|  * -  | ||||
|  * | ||||
|  * Input: | ||||
|  * - none | ||||
|  * | ||||
|  * Output: | ||||
|  * - text to stdout | ||||
|  * | ||||
|  * Assumptions: | ||||
|  * - already validated:     pthread_create() | ||||
|  *                          pthread_once() | ||||
|  * - main thread also has a POSIX thread identity | ||||
|  * | ||||
|  * Pass Criteria: | ||||
|  * - stdout matches file reference/tsd1.out | ||||
|  * | ||||
|  * Fail Criteria: | ||||
|  * - fails to match file reference/tsd1.out | ||||
|  * - output identifies failed component | ||||
|  */ | ||||
|  | ||||
| #include <sched.h> | ||||
| #include "test.h" | ||||
|  | ||||
| static pthread_key_t key = NULL; | ||||
| static int accesscount[10]; | ||||
| static int thread_set[10]; | ||||
| static int thread_destroyed[10]; | ||||
|  | ||||
| static void | ||||
| destroy_key(void * arg) | ||||
| { | ||||
|   int * j = (int *) arg; | ||||
|  | ||||
|   (*j)++; | ||||
|  | ||||
|   assert(*j == 2); | ||||
|  | ||||
|   thread_destroyed[j - accesscount] = 1; | ||||
| } | ||||
|  | ||||
| static void | ||||
| setkey(void * arg) | ||||
| { | ||||
|   int * j = (int *) arg; | ||||
|  | ||||
|   thread_set[j - accesscount] = 1; | ||||
|  | ||||
|   assert(*j == 0); | ||||
|  | ||||
|   assert(pthread_getspecific(key) == NULL); | ||||
|  | ||||
|   assert(pthread_setspecific(key, arg) == 0); | ||||
|  | ||||
|   assert(pthread_getspecific(key) == arg); | ||||
|  | ||||
|   (*j)++; | ||||
|  | ||||
|   assert(*j == 1); | ||||
| } | ||||
|  | ||||
| static void * | ||||
| mythread(void * arg) | ||||
| { | ||||
|   while (key == NULL) | ||||
|     { | ||||
| 	sched_yield(); | ||||
|     } | ||||
|  | ||||
|   setkey(arg); | ||||
|  | ||||
|   return 0; | ||||
|  | ||||
|   /* Exiting the thread will call the key destructor. */ | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   int i; | ||||
|   int fail = 0; | ||||
|   pthread_t thread[10]; | ||||
|  | ||||
|   for (i = 1; i < 5; i++) | ||||
|     { | ||||
| 	accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; | ||||
|       assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); | ||||
|     } | ||||
|  | ||||
|   Sleep(2000); | ||||
|  | ||||
|   /* | ||||
|    * Here we test that existing threads will get a key created | ||||
|    * for them. | ||||
|    */ | ||||
|   assert(pthread_key_create(&key, destroy_key) == 0); | ||||
|  | ||||
|   /* | ||||
|    * Test main thread key. | ||||
|    */ | ||||
|   accesscount[0] = 0; | ||||
|   setkey((void *) &accesscount[0]); | ||||
|  | ||||
|   /* | ||||
|    * Here we test that new threads will get a key created | ||||
|    * for them. | ||||
|    */ | ||||
|   for (i = 5; i < 10; i++) | ||||
|     { | ||||
| 	accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; | ||||
|       assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); | ||||
|     } | ||||
|  | ||||
|   /* | ||||
|    * Wait for all threads to complete. | ||||
|    */ | ||||
|   for (i = 1; i < 10; i++) | ||||
|     { | ||||
| 	int result = 0; | ||||
|  | ||||
| 	assert(pthread_join(thread[i], (void **) &result) == 0); | ||||
|     } | ||||
|  | ||||
|   assert(pthread_key_delete(key) == 0); | ||||
|  | ||||
|   for (i = 1; i < 10; i++) | ||||
|     { | ||||
| 	/* | ||||
| 	 * The counter is incremented once when the key is set to | ||||
| 	 * a value, and again when the key is destroyed. If the key | ||||
| 	 * doesn't get set for some reason then it will still be | ||||
| 	 * NULL and the destroy function will not be called, and | ||||
| 	 * hence accesscount will not equal 2. | ||||
| 	 */ | ||||
| 	if (accesscount[i] != 2) | ||||
| 	  { | ||||
| 	    fail++; | ||||
| 	    fprintf(stderr, "Thread %d key, set = %d, destroyed = %d\n", | ||||
| 			i, thread_set[i], thread_destroyed[i]); | ||||
| 	  } | ||||
|     } | ||||
|  | ||||
|   fflush(stderr); | ||||
|  | ||||
|   return (fail); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user