(root)/
glibc-2.38/
nptl/
tst-cond22.c
       1  #include <pthread.h>
       2  #include <stdio.h>
       3  #include <stdlib.h>
       4  
       5  
       6  static pthread_barrier_t b;
       7  static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
       8  static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
       9  
      10  
      11  static void
      12  cl (void *arg)
      13  {
      14    pthread_mutex_unlock (&m);
      15  }
      16  
      17  
      18  static void *
      19  tf (void *arg)
      20  {
      21    if (pthread_mutex_lock (&m) != 0)
      22      {
      23        printf ("%s: mutex_lock failed\n", __func__);
      24        exit (1);
      25      }
      26    int e = pthread_barrier_wait (&b);
      27    if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
      28      {
      29        printf ("%s: barrier_wait failed\n", __func__);
      30        exit (1);
      31      }
      32    pthread_cleanup_push (cl, NULL);
      33    /* We have to loop here because the cancellation might come after
      34       the cond_wait call left the cancelable area and is then waiting
      35       on the mutex.  In this case the beginning of the second cond_wait
      36       call will cause the cancellation to happen.  */
      37    do
      38      if (pthread_cond_wait (&c, &m) != 0)
      39        {
      40  	printf ("%s: cond_wait failed\n", __func__);
      41  	exit (1);
      42        }
      43    while (arg == NULL);
      44    pthread_cleanup_pop (0);
      45    if (pthread_mutex_unlock (&m) != 0)
      46      {
      47        printf ("%s: mutex_unlock failed\n", __func__);
      48        exit (1);
      49      }
      50    return NULL;
      51  }
      52  
      53  
      54  static int
      55  do_test (void)
      56  {
      57    int status = 0;
      58  
      59    if (pthread_barrier_init (&b, NULL, 2) != 0)
      60      {
      61        puts ("barrier_init failed");
      62        return 1;
      63      }
      64  
      65    pthread_t th;
      66    if (pthread_create (&th, NULL, tf, NULL) != 0)
      67      {
      68        puts ("1st create failed");
      69        return 1;
      70      }
      71    int e = pthread_barrier_wait (&b);
      72    if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
      73      {
      74        puts ("1st barrier_wait failed");
      75        return 1;
      76      }
      77    if (pthread_mutex_lock (&m) != 0)
      78      {
      79        puts ("1st mutex_lock failed");
      80        return 1;
      81      }
      82    if (pthread_cond_signal (&c) != 0)
      83      {
      84        puts ("1st cond_signal failed");
      85        return 1;
      86      }
      87    if (pthread_cancel (th) != 0)
      88      {
      89        puts ("cancel failed");
      90        return 1;
      91      }
      92    if (pthread_mutex_unlock (&m) != 0)
      93      {
      94        puts ("1st mutex_unlock failed");
      95        return 1;
      96      }
      97    void *res;
      98    if (pthread_join (th, &res) != 0)
      99      {
     100        puts ("1st join failed");
     101        return 1;
     102      }
     103    if (res != PTHREAD_CANCELED)
     104      {
     105        puts ("first thread not canceled");
     106        status = 1;
     107      }
     108  
     109    printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n",
     110  	  c.__data.__wseq.__value32.__high,
     111  	  c.__data.__wseq.__value32.__low,
     112  	  c.__data.__g1_start.__value32.__high,
     113  	  c.__data.__g1_start.__value32.__low,
     114  	  c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
     115  	  c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
     116  	  c.__data.__g1_orig_size, c.__data.__wrefs);
     117  
     118    if (pthread_create (&th, NULL, tf, (void *) 1l) != 0)
     119      {
     120        puts ("2nd create failed");
     121        return 1;
     122      }
     123    e = pthread_barrier_wait (&b);
     124    if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
     125      {
     126        puts ("2nd barrier_wait failed");
     127        return 1;
     128      }
     129    if (pthread_mutex_lock (&m) != 0)
     130      {
     131        puts ("2nd mutex_lock failed");
     132        return 1;
     133      }
     134    if (pthread_cond_signal (&c) != 0)
     135      {
     136        puts ("2nd cond_signal failed");
     137        return 1;
     138      }
     139    if (pthread_mutex_unlock (&m) != 0)
     140      {
     141        puts ("2nd mutex_unlock failed");
     142        return 1;
     143      }
     144    if (pthread_join (th, &res) != 0)
     145      {
     146        puts ("2nd join failed");
     147        return 1;
     148      }
     149    if (res != NULL)
     150      {
     151        puts ("2nd thread canceled");
     152        status = 1;
     153      }
     154  
     155    printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n",
     156  	  c.__data.__wseq.__value32.__high,
     157  	  c.__data.__wseq.__value32.__low,
     158  	  c.__data.__g1_start.__value32.__high,
     159  	  c.__data.__g1_start.__value32.__low,
     160  	  c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
     161  	  c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
     162  	  c.__data.__g1_orig_size, c.__data.__wrefs);
     163  
     164    return status;
     165  }
     166  
     167  #define TEST_FUNCTION do_test ()
     168  #include "../test-skeleton.c"