(root)/
glibc-2.38/
sysdeps/
pthread/
tst-cond10.c
       1  /* Copyright (C) 2003-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <error.h>
      19  #include <pthread.h>
      20  #include <stdbool.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  
      24  
      25  #define N 10
      26  #define ROUNDS 100
      27  
      28  static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
      29  static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
      30  static pthread_barrier_t bN1;
      31  static pthread_barrier_t b2;
      32  
      33  
      34  static void *
      35  tf (void *p)
      36  {
      37    if (pthread_mutex_lock (&mut) != 0)
      38      {
      39        puts ("child: 1st mutex_lock failed");
      40        exit (1);
      41      }
      42  
      43    int e = pthread_barrier_wait (&b2);
      44    if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
      45      {
      46        puts ("child: 1st barrier_wait failed");
      47        exit (1);
      48      }
      49  
      50    if (pthread_cond_wait (&cond, &mut) != 0)
      51      {
      52        puts ("child: cond_wait failed");
      53        exit (1);
      54      }
      55  
      56    if (pthread_mutex_unlock (&mut) != 0)
      57      {
      58        puts ("child: mutex_unlock failed");
      59        exit (1);
      60      }
      61  
      62    e = pthread_barrier_wait (&bN1);
      63    if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
      64      {
      65        puts ("child: 2nd barrier_wait failed");
      66        exit (1);
      67      }
      68  
      69    return NULL;
      70  }
      71  
      72  
      73  static int
      74  do_test (void)
      75  {
      76    if (pthread_barrier_init (&bN1, NULL, N + 1) != 0)
      77      {
      78        puts ("barrier_init failed");
      79        exit (1);
      80      }
      81  
      82    if (pthread_barrier_init (&b2, NULL, 2) != 0)
      83      {
      84        puts ("barrier_init failed");
      85        exit (1);
      86      }
      87  
      88    pthread_attr_t at;
      89  
      90    if (pthread_attr_init (&at) != 0)
      91      {
      92        puts ("attr_init failed");
      93        return 1;
      94      }
      95  
      96    if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0)
      97      {
      98        puts ("attr_setstacksize failed");
      99        return 1;
     100      }
     101  
     102    int r;
     103    for (r = 0; r < ROUNDS; ++r)
     104      {
     105        printf ("round %d\n", r + 1);
     106  
     107        int i;
     108        pthread_t th[N];
     109        for (i = 0; i < N; ++i)
     110  	{
     111  	  if (pthread_create (&th[i], &at, tf, NULL) != 0)
     112  	    {
     113  	      puts ("create failed");
     114  	      exit (1);
     115  	    }
     116  
     117  	  int e = pthread_barrier_wait (&b2);
     118  	  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
     119  	    {
     120  	      puts ("parent: 1st barrier_wait failed");
     121  	      exit (1);
     122  	    }
     123  	}
     124  
     125        if (pthread_mutex_lock (&mut) != 0)
     126  	{
     127  	  puts ("parent: mutex_lock failed");
     128  	  exit (1);
     129  	}
     130        if (pthread_mutex_unlock (&mut) != 0)
     131  	{
     132  	  puts ("parent: mutex_unlock failed");
     133  	  exit (1);
     134  	}
     135  
     136        /* N single signal calls.  Without locking.  This tests that no
     137  	 signal gets lost.  */
     138        for (i = 0; i < N; ++i)
     139  	if (pthread_cond_signal (&cond) != 0)
     140  	  {
     141  	    puts ("cond_signal failed");
     142  	    exit (1);
     143  	  }
     144  
     145        int e = pthread_barrier_wait (&bN1);
     146        if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
     147  	{
     148  	  puts ("parent: 2nd barrier_wait failed");
     149  	  exit (1);
     150  	}
     151  
     152        for (i = 0; i < N; ++i)
     153  	if (pthread_join (th[i], NULL) != 0)
     154  	  {
     155  	    puts ("join failed");
     156  	    exit (1);
     157  	  }
     158      }
     159  
     160    if (pthread_attr_destroy (&at) != 0)
     161      {
     162        puts ("attr_destroy failed");
     163        return 1;
     164      }
     165  
     166    return 0;
     167  }
     168  
     169  
     170  #define TEST_FUNCTION do_test ()
     171  #include "../test-skeleton.c"