int main(int argc, char *argv[]) { output_init(); scenar_init(); main_loop(); scenar_fini(); #if VERBOSE > 0 output("Test executed successfully.\n"); output(" %d thread detached.\n", count_ope); #ifdef WITH_SYNCHRO output(" %d signals were sent meanwhile.\n", count_sig); #endif #endif PASSED; }
int main(void) { int ret = 0; pthread_t child; struct timespec ts_pre, ts_th, ts_post; output_init(); scenar_init(); for (sc = 0; sc < NSCENAR; sc++) { if (scenarii[sc].detached == 1) continue; #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", sc, scenarii[sc].descr); #endif ret = clock_gettime(CLOCK_REALTIME, &ts_pre); if (ret != 0) UNRESOLVED(errno, "Failed to read clock"); ret = pthread_create(&child, &scenarii[sc].ta, threaded, &ts_th); switch (scenarii[sc].result) { case 0: if (ret != 0) UNRESOLVED(ret, "Failed to create this thread"); break; case 1: if (ret == 0) UNRESOLVED(-1, "An error was expected but the " "thread creation succeeded"); break; case 2: default: #if VERBOSE > 0 if (ret == 0) output("Thread has been created successfully " "for this scenario\n"); else output("Thread creation failed with the error:" " %s\n", strerror(ret)); #endif } if (ret == 0) { ret = pthread_join(child, NULL); if (ret != 0) UNRESOLVED(ret, "Unable to join a thread"); ret = clock_gettime(CLOCK_REALTIME, &ts_post); if (ret != 0) UNRESOLVED(errno, "Failed to read clock"); /* Now check that ts_pre <= ts_th <= ts_post */ if ((ts_th.tv_sec < ts_pre.tv_sec) || ((ts_th.tv_sec == ts_pre.tv_sec) && (ts_th.tv_nsec < ts_pre.tv_nsec))) { output("Pre : %d.%09d\n", ts_pre.tv_sec, ts_pre.tv_nsec); output("child: %d.%09d\n", ts_th.tv_sec, ts_th.tv_nsec); output("Post : %d.%09d\n", ts_post.tv_sec, ts_post.tv_nsec); FAILED("Child returned before its creation ??"); } if ((ts_post.tv_sec < ts_th.tv_sec) || ((ts_post.tv_sec == ts_th.tv_sec) && (ts_post.tv_nsec < ts_th.tv_nsec))) { output("Pre : %d.%09d\n", ts_pre.tv_sec, ts_pre.tv_nsec); output("child: %d.%09d\n", ts_th.tv_sec, ts_th.tv_nsec); output("Post : %d.%09d\n", ts_post.tv_sec, ts_post.tv_nsec); FAILED("pthread_join returned before child " "terminated"); } } } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
/* Main routine */ int main (int argc, char *argv[]) { int ret=0; pthread_t child; mf =sysconf(_SC_MAPPED_FILES); output_init(); scenar_init(); /* We want to share some memory with the child process */ if (mf> 0) { /* We will place the test data in a mmaped file */ char filename[] = "/tmp/pthread_exit_6-1-XXXXXX"; size_t sz; void * mmaped; int fd; char * tmp; /* We now create the temp files */ fd = mkstemp(filename); if (fd == -1) { UNRESOLVED(errno, "Temporary file could not be created"); } /* and make sure the file will be deleted when closed */ unlink(filename); #if VERBOSE > 1 output("Temp file created (%s).\n", filename); #endif sz= (size_t)sysconf(_SC_PAGESIZE); tmp = calloc(1, sz); if (tmp == NULL) { UNRESOLVED(errno, "Memory allocation failed"); } /* Write the data to the file. */ if (write (fd, tmp, sz) != (ssize_t) sz) { UNRESOLVED(sz, "Writting to the file failed"); } free(tmp); /* Now we can map the file in memory */ mmaped = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mmaped == MAP_FAILED) { UNRESOLVED(errno, "mmap failed"); } ctl = (int *) mmaped; /* Our datatest structure is now in shared memory */ #if VERBOSE > 1 output("Testdata allocated in shared memory.\n"); #endif } for (sc=0; sc < NSCENAR; sc++) { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", sc, scenarii[sc].descr); #endif ret = pthread_create(&child, &scenarii[sc].ta, threaded, &ctl); switch (scenarii[sc].result) { case 0: /* Operation was expected to succeed */ if (ret != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (ret == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 0 if (ret == 0) { output("Thread has been created successfully for this scenario\n"); } else { output("Thread creation failed with the error: %s\n", strerror(ret)); } #endif } if (ret == 0) /* The new thread is running */ { if (scenarii[sc].detached == 0) { ret = pthread_join(child, NULL); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } } else { /* Just wait for the thread to terminate */ do { ret = sem_wait(&scenarii[sc].sem); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to wait for the semaphore"); } } } } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
/* Main routine */ int main (int argc, char *argv[]) { int ret=0; int ctl=0; void * rval; pthread_t child; int i,j; output_init(); scenar_init(); for (j=0; j<3; j++) { ret = pthread_key_create(&tld[j], destructor); if (ret != 0) { UNRESOLVED(ret, "Failed to create a TLD key"); } } for (i=0; i < NSCENAR; i++) { if (scenarii[i].detached == 0) { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", i, scenarii[i].descr); #endif ctl=0; ret = pthread_create(&child, &scenarii[i].ta, threaded, &ctl); switch (scenarii[i].result) { case 0: /* Operation was expected to succeed */ if (ret != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (ret == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 0 if (ret == 0) { output("Thread has been created successfully for this scenario\n"); } else { output("Thread creation failed with the error: %s\n", strerror(ret)); } #endif } if (ret == 0) /* The new thread is running */ { ret = pthread_join(child, &rval); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } if (rval != (NULL+1)) { FAILED("pthread_join() did not retrieve the pthread_exit() param"); } if (atctl != 0) { FAILED("The function registered with atexit() executed"); } if (ctl != 3) { FAILED("The TLD destructors were not called"); } } } } for (j=0; j<3; j++) { ret = pthread_key_delete(tld[j]); if (ret != 0) { UNRESOLVED(ret, "Failed to delete a TLD key"); } } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
int main (int argc, char *argv[]) { int ret=0; pthread_t child; struct timespec ts; output_init(); scenar_init(); ret = sem_init(&sem_sync, 0, 0); if (ret != 0) { UNRESOLVED(ret, "Failed to initialize a semaphore"); } for (sc=0; sc < NSCENAR; sc++) { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", sc, scenarii[sc].descr); #endif if (scenarii[sc].detached != 0) /* only joinable threads can be detached */ { ret = pthread_attr_setdetachstate(&scenarii[sc].ta, PTHREAD_CREATE_JOINABLE); if (ret != 0) { UNRESOLVED(ret, "Unable to set detachstate back to joinable"); } } /* for detached scenarii, we will call pthread_detach from inside the thread. for joinable scenarii, we'll call pthread_detach from this thread. */ ret = pthread_create(&child, &scenarii[sc].ta, threaded, (scenarii[sc].detached != 0)?&ret:NULL); switch (scenarii[sc].result) { case 0: /* Operation was expected to succeed */ if (ret != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (ret == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } #if VERBOSE > 0 break; case 2: /* We did not know the expected result */ default: if (ret == 0) { output("Thread has been created successfully for this scenario\n"); } else { output("Thread creation failed with the error: %s\n", strerror(ret)); } #endif } if (ret == 0) /* The new thread is running */ { /* If we must detach from here, we do it now. */ if (scenarii[sc].detached == 0) { ret = pthread_detach(child); if (ret != 0) { UNRESOLVED(ret, "Failed to detach the child thread."); } } /* Now, allow the thread to terminate */ do { ret = sem_post(&sem_sync); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to post the semaphore"); } /* Just wait for the thread to terminate */ ret = clock_gettime(CLOCK_REALTIME, &ts); if (ret != 0) { UNRESOLVED(ret, "Failed to get time"); } ts.tv_sec += TIMEOUT; do { ret = sem_timedwait(&(scenarii[sc].sem), &ts); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { if (errno == ETIMEDOUT) { FAILED("pthread_detach made the thread terminate"); } /* else */ UNRESOLVED(errno, "Failed to wait for the semaphore"); } /* Let the thread an additionnal row to cleanup */ sched_yield(); } } ret = sem_destroy(&sem_sync); if (ret != 0) { UNRESOLVED(ret, "Failed to destroy the semaphore"); } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
int main (int argc, char *argv[]) { int ret=0; void * rval; pthread_t child; int i,j; output_init(); scenar_init(); for (i=0; i < NSCENAR; i++) { if (scenarii[i].detached == 0) { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", i, scenarii[i].descr); #endif for (j=0; j<3; j++) tab[j]=0; global=0; ret = pthread_create(&child, &scenarii[i].ta, threaded, NULL); switch (scenarii[i].result) { case 0: /* Operation was expected to succeed */ if (ret != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (ret == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 0 if (ret == 0) { output("Thread has been created successfully for this scenario\n"); } else { output("Thread creation failed with the error: %s\n", strerror(ret)); } #endif } if (ret == 0) /* The new thread is running */ { ret = pthread_join(child, &rval); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } if (rval != (NULL+1)) { FAILED("pthread_join() did not retrieve the pthread_exit() param"); } for (j=0; j<3; j++) if (tab[j] != j+1) { output("dump:\ntab[0]=%i\ntab[1]=%i\ntab[2]=%i\n", tab[0], tab[1], tab[2]); FAILED("The cleanup handlers were not called as expected"); } } } } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
int main(int argc, char *argv[]) { int ret = 0; int do_stack_tests; int do_sched_tests; /* Initialize output routine */ output_init(); /* Test abilities */ do_sched_tests = (sysconf(_SC_THREAD_PRIORITY_SCHEDULING) > 0 ? 1 : 0); do_stack_tests = (test_stack(NULL, 0) == 0 ? 1 : 0); #if VERBOSE > 0 output ("Test starting\n Stack tests %s be executed.\n Sched tests %s be executed.\n", do_stack_tests ? "will" : "won't", do_sched_tests ? "will" : "won't"); #endif /* Initialize thread attribute objects */ scenar_init(); for (sc = 0; sc < NSCENAR; sc++) { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", sc, scenarii[sc].descr); #endif if (do_stack_tests) { /* stack grow test */ /* We need the thread attribute to specify a minimal stack */ if ((scenarii[sc].altstack == 0) && (scenarii[sc].altsize == 1)) { #if VERBOSE > 2 output("Processing stack grow test\n"); #endif ret = test_stack(&scenarii[sc].ta, 2 * sysconf(_SC_THREAD_STACK_MIN)); if (ret == 0) { if (scenarii[sc].guard == 2) { FAILED ("Changing the stacksize after the thread was created changed the running thread stack size"); } #if VERBOSE > 2 else output ("We were able to overflow the stack, but the guard area is unknow or null\n"); #endif } if ((ret != 2) && (scenarii[sc].result == 1)) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } #if VERBOSE > 2 if ((ret == 1)) { output("Stack grow test passed\n"); } if ((ret == 2) && (scenarii[sc].result == 2)) { output ("Something went wrong -- we don't care in this case\n"); } #endif if ((ret == 2) && (scenarii[sc].result == 0)) { UNRESOLVED(-1, "An unexpected error occured\n"); } /* Ok, set back the thread attribute object to a correct value */ ret = pthread_attr_setstacksize(&scenarii[sc].ta, sysconf (_SC_THREAD_STACK_MIN)); if (ret != 0) { UNRESOLVED(ret, "Failed to set stacksize back"); } } /* stack decrease test */ if ((scenarii[sc].altstack == 0) && (scenarii[sc].altsize == 0)) { #if VERBOSE > 2 output("Processing stack decrease test\n"); #endif ret = test_stack(&scenarii[sc].ta, sysconf(_SC_THREAD_STACK_MIN)); if (ret == 1) { FAILED ("Decreasing the stack size after thread is created had an influence on the thread"); } if ((ret == 0) && (scenarii[sc].result == 1)) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } if ((ret == 2) && (scenarii[sc].result == 0)) { UNRESOLVED(-1, "An unexpected error occured\n"); } #if VERBOSE > 2 if (ret == 0) output("Stack decrease test passed.\n"); else output ("Something failed but we don't care here.\n"); #endif } } /* if do_stack_tests */ if (do_sched_tests) { /* Sched policy/param change test */ if (scenarii[sc].explicitsched != 0) { /* We need a specified policy */ pthread_t child; int policy_ori, newpol_max; struct sched_param param_ori, tmp; testdata_t td; #if VERBOSE > 2 output ("Processing sched policy/param change test\n"); #endif /* Backup the scenario object */ ret = pthread_attr_getschedpolicy(& (scenarii [sc].ta), &policy_ori); if (ret != 0) { UNRESOLVED(ret, "Unable to read sched policy from thread attribute"); } ret = pthread_attr_getschedparam(& (scenarii [sc].ta), ¶m_ori); if (ret != 0) { UNRESOLVED(ret, "Unable to read sched param from thread attribute"); } /* Initialize the barrier */ ret = pthread_barrier_init(&(td.bar), NULL, 2); if (ret != 0) { UNRESOLVED(ret, "Unable to initialize the barrier"); } /* Create a new thread with this scenario attribute */ ret = pthread_create(&child, &(scenarii[sc].ta), schedtest, &td); if (ret != 0) { if (scenarii[sc].result == 0) { UNRESOLVED(ret, "Failed to create a thread"); } #if VERBOSE > 2 if (scenarii[sc].result == 2) { output ("The thread creation failed -- we don't care\n"); } if (scenarii[sc].result == 1) { output ("The thread creation failed as expected\n"); } #endif } else { /* Thread created */ if (scenarii[sc].result == 1) { UNRESOLVED(-1, "The thread was created where an error was expected"); } #if VERBOSE > 2 if (scenarii[sc].result == 2) output("Thread is created\n"); #endif /* sync 1 */ ret = pthread_barrier_wait(&(td.bar)); if ((ret != 0) && (ret != PTHREAD_BARRIER_SERIAL_THREAD)) { UNRESOLVED(ret, "Failed to synchronize on the barrier"); } /* Check the new thread reports the attributes */ if (td.policy != policy_ori) { FAILED ("The new thread does not report the scheluling policy that was specified"); } if (td.param.sched_priority != param_ori.sched_priority) { FAILED ("The new thread does not report the scheduling priority that was specified at creation"); } /* Change the thread attribute object policy & param */ if (policy_ori == SCHED_RR) { ret = pthread_attr_setschedpolicy (&(scenarii[sc].ta), SCHED_FIFO); newpol_max = sched_get_priority_max (SCHED_FIFO); } else { ret = pthread_attr_setschedpolicy (&(scenarii[sc].ta), SCHED_RR); newpol_max = sched_get_priority_max (SCHED_RR); } if (ret != 0) { UNRESOLVED(ret, "Failed to change the attribute object"); } if (newpol_max == param_ori.sched_priority) newpol_max--; tmp.sched_priority = newpol_max; ret = pthread_attr_setschedparam(& (scenarii [sc].ta), &tmp); if (ret != 0) { UNRESOLVED(ret, "Failed to set the attribute sched param"); } /* sync 2 */ ret = pthread_barrier_wait(&(td.bar)); if ((ret != 0) && (ret != PTHREAD_BARRIER_SERIAL_THREAD)) { UNRESOLVED(ret, "Failed to synchronize on the barrier"); } /* sync 3 */ ret = pthread_barrier_wait(&(td.bar)); if ((ret != 0) && (ret != PTHREAD_BARRIER_SERIAL_THREAD)) { UNRESOLVED(ret, "Failed to synchronize on the barrier"); } /* Check if the thread saw the change (should not) */ if (td.policy != policy_ori) { FAILED ("The new thread does not report the scheluling policy that was specified"); } if (td.param.sched_priority != param_ori.sched_priority) { FAILED ("The new thread does not report the scheduling priority that was specified at creation"); } /* Check what we can see for the child thread from here */ ret = pthread_getschedparam(child, &(td.policy), &(td.param)); if (ret != 0) { UNRESOLVED(ret, "Failed to read child thread policy / param"); } if (td.policy != policy_ori) { FAILED ("The child thread does not report the scheduling policy that was specified at creation"); } if (td.param.sched_priority != param_ori.sched_priority) { FAILED ("The child thread does not report the scheduling priority that was specified at creation"); } /* Restore the thread attribute */ ret = pthread_attr_setschedpolicy(& (scenarii [sc].ta), policy_ori); if (ret != 0) { UNRESOLVED(ret, "Unable to read sched policy from thread attribute"); } ret = pthread_attr_setschedparam(& (scenarii [sc].ta), ¶m_ori); if (ret != 0) { UNRESOLVED(ret, "Unable to read sched param from thread attribute"); } /* sync 4 */ ret = pthread_barrier_wait(&(td.bar)); if ((ret != 0) && (ret != PTHREAD_BARRIER_SERIAL_THREAD)) { UNRESOLVED(ret, "Failed to synchronize on the barrier"); } /* sync 5 */ ret = pthread_barrier_wait(&(td.bar)); if ((ret != 0) && (ret != PTHREAD_BARRIER_SERIAL_THREAD)) { UNRESOLVED(ret, "Failed to synchronize on the barrier"); } /* check if the thread attribute reports a change (should not) */ ret = pthread_attr_getschedpolicy(& (scenarii [sc].ta), & (td.policy)); if (ret != 0) { UNRESOLVED(ret, "Unable to read sched policy from thread attribute"); } ret = pthread_attr_getschedparam(& (scenarii [sc].ta), & (td.param)); if (ret != 0) { UNRESOLVED(ret, "Unable to read sched param from thread attribute"); } if (td.policy != policy_ori) { FAILED ("The child thread does not report the scheduling policy that was specified at creation"); } if (td.param.sched_priority != param_ori.sched_priority) { FAILED ("The child thread does not report the scheduling priority that was specified at creation"); } /* Wait for the sem and join eventually the thread */ do { ret = sem_wait(&scenarii[sc].sem); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to wait for the semaphore"); } if (scenarii[sc].detached == 0) { ret = pthread_join(child, NULL); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } } #if VERBOSE > 2 output ("Sched policy/param change test passed\n"); #endif } /* thread created */ } /* We could also test if the inheritsched does not influence the new thread */ } /* if do_sched_tests */ } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
/* Main function */ int main (int argc, char *argv[]) { int ret=0; struct sigaction sa; pthread_t creation[NSCENAR]; /* Thread ID returned in pthread_create */ int status[NSCENAR]; /* Status of thread creation */ int ids[NSCENAR]; int i; for (sc=0; sc<NSCENAR; sc++) ids[sc]=sc; /* Initialize output routine */ output_init(); /* Initialize thread attribute objects */ scenar_init(); /* Register the signal handler for SIGUSR1 */ sigemptyset (&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = sighdl; if ((ret = sigaction (SIGUSR1, &sa, NULL))) { UNRESOLVED(ret, "Unable to register signal handler"); } if ((ret = sigaction (SIGALRM, &sa, NULL))) { UNRESOLVED(ret, "Unable to register signal handler"); } #if VERBOSE > 1 output("[parent] Signal handler registered\n"); #endif while (do_it) { /* Initialize the shared data */ c_boolean = 0; /* Create all the threads */ for (sc=0; sc < NSCENAR; sc++) { /* Create the thread */ status[sc] = pthread_create(&creation[sc], &scenarii[sc].ta, threaded, &ids[sc]); /* Check creation status */ switch (scenarii[sc].result) { case 0: /* Operation was expected to succeed */ if (status[sc] != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (status[sc] == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: /* Nothing */ ; } } #if VERBOSE > 6 output("[parent] threads created\n"); #endif /* Now wait that all threads are running */ for (sc=0; sc < NSCENAR; sc++) { if (status[sc] == 0) /* The new thread is running */ { #if VERBOSE > 6 output("[parent] Waiting for thread %d: %p\n", sc, &scenarii[sc].sem); #endif do { ret = sem_wait(&scenarii[sc].sem); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to wait for the semaphore"); } } } #if VERBOSE > 6 output("[parent] Locking the mutex\n"); #endif ret = pthread_mutex_lock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex lock failed"); } /* Now, we've got all shared data set, so we can seek for duplicates */ for (sc=0; sc < NSCENAR; sc++) { if (status[sc] != 0) /* The new thread is running */ continue; if (pthread_equal(creation[sc], running[sc]) == 0) { output("pthread_create returned an ID of %p\n", creation[sc]); output("pthread_self in the thread returned %p\n", running[sc]); FAILED("Error: Values mismatch"); } for (i=sc+1; i<NSCENAR; i++) { if (status[i] != 0) continue; if (pthread_equal(creation[sc], creation[i])) { FAILED("Two different running threads have the same ID"); } } } #if VERBOSE > 6 output("[parent] No duplicate found\n"); #endif /* We're done, we can terminate the threads */ c_boolean = 1; ret = pthread_mutex_unlock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex unlock failed"); } ret = pthread_cond_broadcast(&c_synchro); if (ret != 0) { UNRESOLVED(ret, "Failed to broadcast the cond"); } #if VERBOSE > 6 output("[parent] Cond broadcasted\n"); #endif /* Join the joinable threads */ for (sc=0; sc < NSCENAR; sc++) { if (status[sc] != 0) /* The new thread is running */ continue; if (scenarii[sc].detached == 0) { #if VERBOSE > 6 output("[parent] Joining %d\n", sc); #endif ret = pthread_join(creation[sc], NULL); if (ret != 0) { UNRESOLVED(ret, "Unalbe to join a thread"); } #if VERBOSE > 6 output("[parent] Joined %d\n", sc); #endif } } iterations++; } /* We've been asked to stop */ scenar_fini(); output("pthread_exit stress test PASSED -- %llu iterations\n",iterations); PASSED; }
/* main routine */ int main(int argc, char * argv[]) { int ret, i; void * rval; struct sigaction sa; pthread_t threads[NSCENAR * SCALABILITY_FACTOR * FACTOR]; int rets[NSCENAR * SCALABILITY_FACTOR * FACTOR]; /* Initialize output */ output_init(); /* Initialize scenarii table */ scenar_init(); /* Register the signal handler for SIGUSR1 */ sigemptyset (&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = sighdl; if ((ret = sigaction (SIGUSR1, &sa, NULL))) { UNRESOLVED(ret, "Unable to register signal handler"); } if ((ret = sigaction (SIGALRM, &sa, NULL))) { UNRESOLVED(ret, "Unable to register signal handler"); } #if VERBOSE > 1 output("[parent] Signal handler registered\n"); #endif while (do_it) { /* Create all the threads */ for (i=0; i<SCALABILITY_FACTOR * FACTOR; i++) { for (sc=0; sc<NSCENAR; sc++) { /* Skip the alternative stack threads */ if (scenarii[sc].altstack != 0) continue; rets[i*NSCENAR + sc] = pthread_create(&threads[i*NSCENAR + sc], &scenarii[sc].ta, threaded, &threads[i*NSCENAR + sc]); switch (scenarii[sc].result) { case 0: /* Operation was expected to succeed */ if (rets[i*NSCENAR + sc] != 0) { UNRESOLVED(rets[i*NSCENAR + sc], "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (rets[i*NSCENAR + sc] == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 5 if (rets[i*NSCENAR + sc] == 0) { output("Thread has been created successfully for this scenario\n"); } else { output("Thread creation failed with the error: %s\n", strerror(rets[i*NSCENAR + sc])); } #endif ; } if (rets[i*NSCENAR + sc] == 0) { /* Just wait for the thread to terminate */ do { ret = sem_wait(&scenarii[sc].sem); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to wait for the semaphore"); } } } } /* Join all the joinable threads and check the value */ for (i=0; i<SCALABILITY_FACTOR * FACTOR; i++) { for (sc=0; sc<NSCENAR; sc++) { if ((scenarii[sc].altstack == 0) && (scenarii[sc].detached == 0) && (rets[i*NSCENAR + sc] == 0)) { ret = pthread_join(threads[i*NSCENAR + sc], &rval); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } if (rval != (void *)&threads[i*NSCENAR + sc]) { output("arg: %p -- got %p -- NULL=%p\n", &threads[i*NSCENAR + sc], rval, NULL); FAILED("The retrieved error value is corrupted"); } } } } iterations++; } /* Destroy scenarii attributes */ scenar_fini(); /* Test passed */ output("pthread_exit stress test PASSED -- %llu iterations\n",iterations); PASSED; }
/* The main test function. */ int main(int argc, char *argv[]) { int ret = 0; pthread_t child; pthread_t joiner; /* Initialize output routine */ output_init(); /* Initialize thread attribute objects */ scenar_init(); for (sc = 0; sc < NSCENAR; sc++) { if (scenarii[sc].detached == 1) continue; #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", sc, scenarii[sc].descr); #endif /* Lock the mutex */ ret = pthread_mutex_lock(&mtx); if (ret != 0) UNRESOLVED(ret, "failed to lock the mutex"); ret = pthread_create(&child, &scenarii[sc].ta, threaded, NULL); switch (scenarii[sc].result) { /* Operation was expected to succeed */ case 0: if (ret != 0) UNRESOLVED(ret, "Failed to create this thread"); break; /* Operation was expected to fail */ case 1: if (ret == 0) UNRESOLVED(-1, "An error was expected " "but the thread creation succeeded"); break; /* We did not know the expected result */ case 2: default: #if VERBOSE > 0 if (ret == 0) output("Thread has been created " "successfully for this scenario\n"); else output("Thread creation failed with the error: " "%s\n", strerror(ret)); #endif } /* The new thread is running */ if (ret == 0) { /* Now create the joiner thread */ ret = pthread_create(&joiner, NULL, joiner_func, &child); if (ret != 0) UNRESOLVED(ret, "Failed to create the " "joiner thread"); /* Let it enter pthread_join */ sched_yield(); /* Cancel the joiner thread */ ret = pthread_cancel(joiner); if (ret != 0) UNRESOLVED(ret, "Failed to cancel the thread"); /* Join the canceled thread */ ret = pthread_join(joiner, NULL); if (ret != 0) UNRESOLVED(ret, "Failed to join the " "canceled thread"); /* Unblock the child thread */ ret = pthread_mutex_unlock(&mtx); if (ret != 0) UNRESOLVED(ret, "Failed to unlock the mutex"); /* Check the first thread is still joinable */ ret = pthread_join(child, NULL); if (ret != 0) { output("Error returned: %d\n"); FAILED("The thread is no more joinable"); } } else { ret = pthread_mutex_unlock(&mtx); if (ret != 0) UNRESOLVED(ret, "Failed to unlock the mutex"); } } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
int main(int argc, char *argv[]) { int ret; pthread_t th_work, th_sig1, th_sig2; struct thestruct arg1, arg2; struct sigaction sa; output_init(); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = sighdl1; ret = sigaction(SIGUSR1, &sa, NULL); if (ret == -1) UNRESOLVED(ret, "Unable to register signal handler1"); sa.sa_handler = sighdl2; ret = sigaction(SIGUSR2, &sa, NULL); if (ret == -1) UNRESOLVED(ret, "Unable to register signal handler2"); /* We prepare a signal set which includes SIGUSR1 and SIGUSR2 */ sigemptyset(&usersigs); ret = sigaddset(&usersigs, SIGUSR1); ret |= sigaddset(&usersigs, SIGUSR2); if (ret != 0) UNRESOLVED(ret, "Unable to add SIGUSR1 or 2 to a signal set"); /* We now block the signals SIGUSR1 and SIGUSR2 for this THREAD */ ret = pthread_sigmask(SIG_BLOCK, &usersigs, NULL); if (ret != 0) UNRESOLVED(ret, "Unable to block SIGUSR1 and SIGUSR2 " "in main thread"); #ifdef WITH_SYNCHRO if (sem_init(&semsig1, 0, 1)) UNRESOLVED(errno, "Semsig1 init"); if (sem_init(&semsig2, 0, 1)) UNRESOLVED(errno, "Semsig2 init"); #endif /* Initialize thread attribute objects */ scenar_init(); ret = pthread_create(&th_work, NULL, test, NULL); if (ret) UNRESOLVED(ret, "Worker thread creation failed"); arg1.sig = SIGUSR1; arg2.sig = SIGUSR2; #ifdef WITH_SYNCHRO arg1.sem = &semsig1; arg2.sem = &semsig2; #endif ret = pthread_create(&th_sig1, NULL, sendsig, (void *) &arg1); if (ret) UNRESOLVED(ret, "Signal 1 sender thread creation failed"); ret = pthread_create(&th_sig2, NULL, sendsig, (void *) &arg2); if (ret) UNRESOLVED(ret, "Signal 2 sender thread creation failed"); /* Now stop the threads and join them */ do { do_it1 = 0; } while (do_it1); sleep(1); do { do_it2 = 0; } while (do_it2); ret = pthread_join(th_sig1, NULL); if (ret) UNRESOLVED(ret, "Signal 1 sender thread join failed"); ret = pthread_join(th_sig2, NULL); if (ret) UNRESOLVED(ret, "Signal 2 sender thread join failed"); ret = pthread_join(th_work, NULL); if (ret) UNRESOLVED(ret, "Worker thread join failed"); scenar_fini(); #if VERBOSE > 0 output("Test executed successfully.\n"); output(" %d pthread_join calls.\n", count_ope); #ifdef WITH_SYNCHRO output(" %d signals were sent meanwhile.\n", count_sig); #endif #endif PASSED; }
int main (int argc, char *argv[]) { int ret=0; pthread_t child; pthread_t *th; int nthreads, ctl, i, tmp; struct timespec ts_ref, ts_fin; mes_t sentinel; mes_t *m_cur, *m_tmp; long PTHREAD_THREADS_MAX = sysconf(_SC_THREAD_THREADS_MAX); long my_max = 1000 * SCALABILITY_FACTOR ; /* Initialize the measure list */ m_cur = &sentinel; m_cur->next = NULL; /* Initialize output routine */ output_init(); if (PTHREAD_THREADS_MAX > 0) my_max = PTHREAD_THREADS_MAX; th = (pthread_t *)calloc(1 + my_max, sizeof(pthread_t)); if (th == NULL) { UNRESOLVED(errno, "Not enough memory for thread storage"); } /* Initialize thread attribute objects */ scenar_init(); #ifdef PLOT_OUTPUT printf("# COLUMNS %d #threads", NSCENAR + 1); for (sc=0; sc<NSCENAR; sc++) printf(" %i", sc); printf("\n"); #endif for (sc=0; sc < NSCENAR; sc++) { if (scenarii[sc].bottom == NULL) /* skip the alternate stacks as we could create only 1 */ { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", sc, scenarii[sc].descr); #endif /* Block every (about to be) created threads */ ret = pthread_mutex_lock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex lock failed"); } ctl=0; nthreads=0; m_cur = &sentinel; /* Create 1 thread for testing purpose */ ret = pthread_create(&child, &scenarii[sc].ta, threaded, &ctl); switch (scenarii[sc].result) { case 0: /* Operation was expected to succeed */ if (ret != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (ret == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 0 if (ret == 0) { output("Thread has been created successfully for this scenario\n"); } else { output("Thread creation failed with the error: %s\n", strerror(ret)); } #endif ; } if (ret == 0) /* The new thread is running */ { while (1) /* we will break */ { /* read clock */ ret = clock_gettime(CLOCK_REALTIME, &ts_ref); if (ret != 0) { UNRESOLVED(errno, "Unable to read clock"); } /* create a new thread */ ret = pthread_create(&th[nthreads], &scenarii[sc].ta, threaded, &ctl); /* stop here if we've got EAGAIN */ if (ret == EAGAIN) break; // temporary hack if (ret == ENOMEM) break; nthreads++; /* FAILED if error is != EAGAIN or nthreads > PTHREAD_THREADS_MAX */ if (ret != 0) { output("pthread_create returned: %i (%s)\n", ret, strerror(ret)); FAILED("pthread_create did not return EAGAIN on a lack of resource"); } if (nthreads > my_max) { if (PTHREAD_THREADS_MAX > 0) { FAILED("We were able to create more than PTHREAD_THREADS_MAX threads"); } else { break; } } /* wait for the semaphore */ do { ret = sem_wait(&scenarii[sc].sem); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to wait for the semaphore"); } /* read clock */ ret = clock_gettime(CLOCK_REALTIME, &ts_fin); if (ret != 0) { UNRESOLVED(errno, "Unable to read clock"); } /* add to the measure list if nthreads % resolution == 0 */ if ((nthreads % RESOLUTION) == 0) { if (m_cur->next == NULL) { /* Create an empty new element */ m_tmp = (mes_t *) malloc(sizeof(mes_t)); if (m_tmp == NULL) { UNRESOLVED(errno, "Unable to alloc memory for measure saving"); } m_tmp->nthreads = nthreads; m_tmp->next = NULL; for (tmp=0; tmp<NSCENAR; tmp++) m_tmp->_data[tmp]= 0; m_cur->next = m_tmp; } /* Add this measure to the next element */ m_cur = m_cur->next; m_cur->_data[sc] = ((ts_fin.tv_sec - ts_ref.tv_sec) * 1000000) + ((ts_fin.tv_nsec - ts_ref.tv_nsec) / 1000) ; #if VERBOSE > 5 output("Added the following measure: sc=%i, n=%i, v=%li\n", sc, nthreads, m_cur->_data[sc]); #endif } } #if VERBOSE > 3 output("Could not create anymore thread. Current count is %i\n", nthreads); #endif /* Unblock every created threads */ ret = pthread_mutex_unlock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex unlock failed"); } if (scenarii[sc].detached == 0) { #if VERBOSE > 3 output("Joining the threads\n"); #endif for (i = 0; i < nthreads; i++) { ret = pthread_join(th[i], NULL); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } } ret = pthread_join(child, NULL); if (ret != 0) { UNRESOLVED(ret, "Unalbe to join a thread"); } } #if VERBOSE > 3 output("Waiting for threads (almost) termination\n"); #endif do { ret = pthread_mutex_lock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex lock failed"); } tmp = ctl; ret = pthread_mutex_unlock(&m_synchro); if (ret != 0) { UNRESOLVED(ret, "Mutex unlock failed"); } } while (tmp != nthreads + 1); } /* The thread was created */ } } /* next scenario */ /* Free some memory before result parsing */ free(th); /* Compute the results */ ret = parse_measure(&sentinel); /* Free the resources and output the results */ #if VERBOSE > 5 printf("Dump : \n"); printf("%8.8s", "nth"); for (i = 0; i<NSCENAR; i++) printf("| %2.2i ", i); printf("\n"); #endif while (sentinel.next != NULL) { m_cur = sentinel.next; #if (VERBOSE > 5) || defined(PLOT_OUTPUT) printf("%8.8i", m_cur->nthreads); for (i=0; i<NSCENAR; i++) printf(" %1.1li.%6.6li", m_cur->_data[i] / 1000000, m_cur->_data[i] % 1000000); printf("\n"); #endif sentinel.next = m_cur->next; free(m_cur); } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
int main (int argc, char *argv[]) { int ret=0; pthread_t child; /* Initialize output routine */ output_init(); /* Initialize thread attribute objects */ scenar_init(); for (sc=0; sc < NSCENAR; sc++) { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", sc, scenarii[sc].descr); #endif ret = pthread_create(&child, &scenarii[sc].ta, threaded, NULL); switch (scenarii[sc].result) { case 0: /* Operation was expected to succeed */ if (ret != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (ret == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 0 if (ret == 0) { output("Thread has been created successfully for this scenario\n"); } else { output("Thread creation failed with the error: %s\n", strerror(ret)); } #endif } if (ret == 0) /* The new thread is running */ { if (scenarii[sc].detached == 0) { ret = pthread_join(child, NULL); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } } else { /* Just wait for the thread to terminate */ do { ret = sem_wait(&scenarii[sc].sem); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to wait for the semaphore"); } } } } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
int main(int argc, char *argv[]) { int ret = 0; pthread_t child; testdata_t td_parent, td_thread; /* Initialize output routine */ output_init(); /* Initialize thread attribute objects */ scenar_init(); /* Initialize the signal state */ ret = sigemptyset(&(td_parent.mask)); if (ret != 0) { UNRESOLVED(ret, "Failed to initialize a signal set"); } ret = sigemptyset(&(td_parent.pending)); if (ret != 0) { UNRESOLVED(ret, "Failed to initialize a signal set"); } /* Add SIGCONT, SIGUSR1 and SIGUSR2 to the set of blocked signals */ ret = sigaddset(&(td_parent.mask), SIGUSR1); if (ret != 0) { UNRESOLVED(ret, "Failed to add SIGUSR1 to the signal set"); } ret = sigaddset(&(td_parent.mask), SIGUSR2); if (ret != 0) { UNRESOLVED(ret, "Failed to add SIGUSR2 to the signal set"); } /* Block those signals. */ ret = pthread_sigmask(SIG_SETMASK, &(td_parent.mask), NULL); if (ret != 0) { UNRESOLVED(ret, "Failed to mask the singals in main"); } /* Raise those signals so they are now pending. */ ret = raise(SIGUSR1); if (ret != 0) { UNRESOLVED(errno, "Failed to raise SIGUSR1"); } ret = raise(SIGUSR2); if (ret != 0) { UNRESOLVED(errno, "Failed to raise SIGUSR2"); } /* Do the testing for each thread */ for (sc = 0; sc < NSCENAR; sc++) { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", sc, scenarii[sc].descr); #endif /* (re)initialize thread signal sets */ ret = sigemptyset(&(td_thread.mask)); if (ret != 0) { UNRESOLVED(ret, "Failed to initialize a signal set"); } ret = sigemptyset(&(td_thread.pending)); if (ret != 0) { UNRESOLVED(ret, "Failed to initialize a signal set"); } ret = pthread_create(&child, &scenarii[sc].ta, threaded, &td_thread); switch (scenarii[sc].result) { case 0: /* Operation was expected to succeed */ if (ret != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (ret == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 0 if (ret == 0) { output ("Thread has been created successfully for this scenario\n"); } else { output ("Thread creation failed with the error: %s\n", strerror(ret)); } #endif } if (ret == 0) { /* The new thread is running */ if (scenarii[sc].detached == 0) { ret = pthread_join(child, NULL); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } } else { /* Just wait for the thread to terminate */ do { ret = sem_wait(&scenarii[sc].sem); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to wait for the semaphore"); } } /* The thread has terminated its work, so we can now control */ ret = sigismember(&(td_thread.mask), SIGUSR1); if (ret != 1) { if (ret == 0) { FAILED ("The thread did not inherit the signal mask"); } /* else */ UNRESOLVED(ret, "sigismember() failed"); } ret = sigismember(&(td_thread.mask), SIGUSR2); if (ret != 1) { if (ret == 0) { FAILED ("The thread did not inherit the signal mask"); } /* else */ UNRESOLVED(ret, "sigismember() failed"); } ret = sigismember(&(td_thread.pending), SIGUSR1); if (ret != 0) { if (ret == 1) { FAILED ("The thread inherited the pending signal SIGUSR1"); } /* else */ UNRESOLVED(ret, "sigismember() failed"); } ret = sigismember(&(td_thread.pending), SIGUSR2); if (ret != 0) { if (ret == 1) { FAILED ("The thread inherited the pending signal SIGUSR2"); } /* else */ UNRESOLVED(ret, "sigismember() failed"); } } } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
int main (int argc, char *argv[]) { int ret=0; struct testdata td; void * rval; pthread_t child; int i; output_init(); td.tid=pthread_self(); td.pid=getpid(); scenar_init(); for (i=0; i < NSCENAR; i++) { #if VERBOSE > 0 output("-----\n"); output("Starting test with scenario (%i): %s\n", i, scenarii[i].descr); #endif td.sem = &scenarii[i].sem; global = 2*i; ret = pthread_create(&child, &scenarii[i].ta, threaded, &td); switch (scenarii[i].result) { case 0: /* Operation was expected to succeed */ if (ret != 0) { UNRESOLVED(ret, "Failed to create this thread"); } break; case 1: /* Operation was expected to fail */ if (ret == 0) { UNRESOLVED(-1, "An error was expected but the thread creation succeeded"); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 0 if (ret == 0) { output("Thread has been created successfully for this scenario\n"); } else { output("Thread creation failed with the error: %s\n", strerror(ret)); } #endif } if (ret == 0) /* The new thread is running */ { if (scenarii[i].detached == 0) { ret = pthread_join(child, &rval); if (ret != 0) { UNRESOLVED(ret, "Unable to join a thread"); } if (rval != &td) { FAILED("Could not get the thread return value. Did it execute?"); } } else { /* Just wait for the thread terminate */ do { ret = sem_wait(td.sem); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { UNRESOLVED(errno, "Failed to post the semaphore"); } } if (global != (2*i + 1)) { /* Maybe a possible issue with CPU memory-caching here? */ FAILED("The threads do not share the same process memory."); } } } scenar_fini(); #if VERBOSE > 0 output("-----\n"); output("All test data destroyed\n"); output("Test PASSED\n"); #endif PASSED; }
/* The main test function. */ int main( int argc, char *argv[] ) { int ret = 0; pthread_t child; struct timespec ts_pre, ts_th, ts_post; /* Initialize output routine */ output_init(); /* Initialize thread attribute objects */ scenar_init(); for ( sc = 0; sc < NSCENAR; sc++ ) { #if VERBOSE > 0 output( "-----\n" ); output( "Starting test with scenario (%i): %s\n", sc, scenarii[ sc ].descr ); #endif ret = clock_gettime( CLOCK_REALTIME, &ts_pre ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to read clock" ); } ret = pthread_create( &child, &scenarii[ sc ].ta, threaded, &ts_th ); switch ( scenarii[ sc ].result ) { case 0: /* Operation was expected to succeed */ if ( ret != 0 ) { UNRESOLVED( ret, "Failed to create this thread" ); } break; case 1: /* Operation was expected to fail */ if ( ret == 0 ) { UNRESOLVED( -1, "An error was expected but the thread creation succeeded" ); } break; case 2: /* We did not know the expected result */ default: #if VERBOSE > 0 if ( ret == 0 ) { output( "Thread has been created successfully for this scenario\n" ); } else { output( "Thread creation failed with the error: %s\n", strerror( ret ) ); } #endif } if ( ret == 0 ) /* The new thread is running */ { ret = pthread_join( child, NULL ); if ( ret != 0 ) { UNRESOLVED( ret, "Unable to join a thread" ); } ret = clock_gettime( CLOCK_REALTIME, &ts_post ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to read clock" ); } /* Now check that ts_pre <= ts_th <= ts_post */ if ( ( ts_th.tv_sec < ts_pre.tv_sec ) || ( ( ts_th.tv_sec == ts_pre.tv_sec ) && ( ts_th.tv_nsec < ts_pre.tv_nsec ) ) ) { output( "Pre : %d.%09d\n", ts_pre.tv_sec, ts_pre.tv_nsec ); output( "child: %d.%09d\n", ts_th.tv_sec, ts_th.tv_nsec ); output( "Post : %d.%09d\n", ts_post.tv_sec, ts_post.tv_nsec ); FAILED( "Child returned before its creation ???" ); } if ( ( ts_post.tv_sec < ts_th.tv_sec ) || ( ( ts_post.tv_sec == ts_th.tv_sec ) && ( ts_post.tv_nsec < ts_th.tv_nsec ) ) ) { output( "Pre : %d.%09d\n", ts_pre.tv_sec, ts_pre.tv_nsec ); output( "child: %d.%09d\n", ts_th.tv_sec, ts_th.tv_nsec ); output( "Post : %d.%09d\n", ts_post.tv_sec, ts_post.tv_nsec ); FAILED( "pthread_join returned before child terminated" ); } } } scenar_fini(); #if VERBOSE > 0 output( "-----\n" ); output( "All test data destroyed\n" ); output( "Test PASSED\n" ); #endif PASSED; }