1 /* Test barriers.
2    Copyright (C) 2000-2022 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 #define _GNU_SOURCE
20 
21 #include <pthread.h>
22 #include <stdio.h>
23 #include <error.h>
24 #include <assert.h>
25 #include <errno.h>
26 
27 #define THREADS 500
28 #define WAITS 3
29 
30 void *
dowait(void * arg)31 dowait (void *arg)
32 {
33   pthread_barrier_t *barrier = arg;
34   int ret;
35 
36   ret = pthread_barrier_wait (barrier);
37   printf ("%d ", pthread_self ());
38   return (void *) ret;
39 }
40 
41 int
main(int argc,char ** argv)42 main (int argc, char **argv)
43 {
44   pthread_barrierattr_t attr;
45   pthread_barrier_t barrier;
46 
47   int i, j;
48   error_t err;
49   pthread_t tid[THREADS];
50 
51   int havesyncs;
52 
53   err = pthread_barrierattr_init (&attr);
54   if (err)
55     error (1, err, "pthread_barrierattr_init");
56 
57   err = pthread_barrierattr_getpshared (&attr, &i);
58   if (err)
59     error (1, err, "pthread_barrierattr_getpshared");
60   assert (i == PTHREAD_PROCESS_PRIVATE || i == PTHREAD_PROCESS_SHARED);
61 
62   err = pthread_barrierattr_setpshared (&attr, PTHREAD_PROCESS_PRIVATE);
63   if (err)
64     error (1, err, "pthread_barrierattr_setpshared");
65 
66   err = pthread_barrier_init (&barrier, &attr, THREADS + 1);
67   if (err)
68     error (1, err, "pthread_barrier_init");
69 
70   for (j = 0; j < WAITS; j++)
71     {
72 
73       for (i = 0; i < THREADS; i++)
74 	{
75 	  err = pthread_create (&tid[i], 0, dowait, &barrier);
76 	  if (err)
77 	    error (1, err, "pthread_create (%d)", i);
78 	}
79 
80       printf ("Manager will now call pthread_barrier_wait.\n");
81 
82       havesyncs
83 	  = pthread_barrier_wait (&barrier) == PTHREAD_BARRIER_SERIAL_THREAD
84 	  ? 1 : 0;
85 
86       for (i = THREADS - 1; i >= 0; i--)
87 	{
88 	  void *ret;
89 	  err = pthread_join (tid[i], &ret);
90 	  if (err)
91 	    error (1, err, "pthread_join");
92 
93 	  switch ((int) ret)
94 	    {
95 	    case 0:
96 	      break;
97 
98 	    case PTHREAD_BARRIER_SERIAL_THREAD:
99 	      havesyncs++;
100 	      break;
101 
102 	    default:
103 	      assert (!"Unknown value returned from pthread_barrier_wait.");
104 	      break;
105 	    }
106 	}
107 
108       printf ("\n");
109 
110       assert (havesyncs == 1);
111     }
112 
113   return 0;
114 }
115