| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 | #include <pthread.h>#include <stdio.h>#include <stdlib.h>static pthread_barrier_t b;static pthread_cond_t c = PTHREAD_COND_INITIALIZER;static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;static voidcl (void *arg){  pthread_mutex_unlock (&m);}static void *tf (void *arg){  if (pthread_mutex_lock (&m) != 0)    {      printf ("%s: mutex_lock failed\n", __func__);      exit (1);    }  int e = pthread_barrier_wait (&b);  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)    {      printf ("%s: barrier_wait failed\n", __func__);      exit (1);    }  pthread_cleanup_push (cl, NULL);  /* We have to loop here because the cancellation might come after     the cond_wait call left the cancelable area and is then waiting     on the mutex.  In this case the beginning of the second cond_wait     call will cause the cancellation to happen.  */  do    if (pthread_cond_wait (&c, &m) != 0)      {	printf ("%s: cond_wait failed\n", __func__);	exit (1);      }  while (arg == NULL);  pthread_cleanup_pop (0);  if (pthread_mutex_unlock (&m) != 0)    {      printf ("%s: mutex_unlock failed\n", __func__);      exit (1);    }  return NULL;}static intdo_test (void){  int status = 0;  if (pthread_barrier_init (&b, NULL, 2) != 0)    {      puts ("barrier_init failed");      return 1;    }  pthread_t th;  if (pthread_create (&th, NULL, tf, NULL) != 0)    {      puts ("1st create failed");      return 1;    }  int e = pthread_barrier_wait (&b);  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)    {      puts ("1st barrier_wait failed");      return 1;    }  if (pthread_mutex_lock (&m) != 0)    {      puts ("1st mutex_lock failed");      return 1;    }  if (pthread_cond_signal (&c) != 0)    {      puts ("1st cond_signal failed");      return 1;    }  if (pthread_cancel (th) != 0)    {      puts ("cancel failed");      return 1;    }  if (pthread_mutex_unlock (&m) != 0)    {      puts ("1st mutex_unlock failed");      return 1;    }  void *res;  if (pthread_join (th, &res) != 0)    {      puts ("1st join failed");      return 1;    }  if (res != PTHREAD_CANCELED)    {      puts ("first thread not canceled");      status = 1;    }  printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",	  c.__data.__lock, c.__data.__futex, c.__data.__total_seq,	  c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,	  c.__data.__nwaiters, c.__data.__broadcast_seq);  if (pthread_create (&th, NULL, tf, (void *) 1l) != 0)    {      puts ("2nd create failed");      return 1;    }  e = pthread_barrier_wait (&b);  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)    {      puts ("2nd barrier_wait failed");      return 1;    }  if (pthread_mutex_lock (&m) != 0)    {      puts ("2nd mutex_lock failed");      return 1;    }  if (pthread_cond_signal (&c) != 0)    {      puts ("2nd cond_signal failed");      return 1;    }  if (pthread_mutex_unlock (&m) != 0)    {      puts ("2nd mutex_unlock failed");      return 1;    }  if (pthread_join (th, &res) != 0)    {      puts ("2nd join failed");      return 1;    }  if (res != NULL)    {      puts ("2nd thread canceled");      status = 1;    }  printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",	  c.__data.__lock, c.__data.__futex, c.__data.__total_seq,	  c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,	  c.__data.__nwaiters, c.__data.__broadcast_seq);  return status;}#define TEST_FUNCTION do_test ()#include "../test-skeleton.c"
 |