(root)/
glibc-2.38/
sysdeps/
pthread/
tst-barrier4.c
       1  /* This tests destruction of a barrier right after waiting on it.
       2     Copyright (C) 2004-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <errno.h>
      20  #include <pthread.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  
      24  
      25  static pthread_barrier_t b1;
      26  static pthread_barrier_t b2;
      27  
      28  
      29  #define N 20
      30  
      31  static void *
      32  tf (void *arg)
      33  {
      34    int round = 0;
      35  
      36    while (round++ < 30)
      37      {
      38        if (pthread_barrier_wait (&b1) == PTHREAD_BARRIER_SERIAL_THREAD)
      39  	{
      40  	  pthread_barrier_destroy (&b1);
      41  	  if (pthread_barrier_init (&b1, NULL, N) != 0)
      42  	    {
      43  	      puts ("tf: 1st barrier_init failed");
      44  	      exit (1);
      45  	    }
      46  	}
      47  
      48        if (pthread_barrier_wait (&b2) == PTHREAD_BARRIER_SERIAL_THREAD)
      49  	{
      50  	  pthread_barrier_destroy (&b2);
      51  	  if (pthread_barrier_init (&b2, NULL, N) != 0)
      52  	    {
      53  	      puts ("tf: 2nd barrier_init failed");
      54  	      exit (1);
      55  	    }
      56  	}
      57      }
      58  
      59    return NULL;
      60  }
      61  
      62  
      63  static int
      64  do_test (void)
      65  {
      66    pthread_attr_t at;
      67    int cnt;
      68  
      69    if (pthread_attr_init (&at) != 0)
      70      {
      71        puts ("attr_init failed");
      72        return 1;
      73      }
      74  
      75    if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0)
      76      {
      77        puts ("attr_setstacksize failed");
      78        return 1;
      79      }
      80  
      81    if (pthread_barrier_init (&b1, NULL, N) != 0)
      82      {
      83        puts ("1st barrier_init failed");
      84        return 1;
      85      }
      86  
      87    if (pthread_barrier_init (&b2, NULL, N) != 0)
      88      {
      89        puts ("2nd barrier_init failed");
      90        return 1;
      91      }
      92  
      93    pthread_t th[N - 1];
      94    for (cnt = 0; cnt < N - 1; ++cnt)
      95      if (pthread_create (&th[cnt], &at, tf, NULL) != 0)
      96        {
      97  	puts ("pthread_create failed");
      98  	return 1;
      99        }
     100  
     101    if (pthread_attr_destroy (&at) != 0)
     102      {
     103        puts ("attr_destroy failed");
     104        return 1;
     105      }
     106  
     107    tf (NULL);
     108  
     109    for (cnt = 0; cnt < N - 1; ++cnt)
     110      if (pthread_join (th[cnt], NULL) != 0)
     111        {
     112  	puts ("pthread_join failed");
     113  	return 1;
     114        }
     115  
     116    return 0;
     117  }
     118  
     119  #define TEST_FUNCTION do_test ()
     120  #include "../test-skeleton.c"