]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/test/nptl/tst-barrier3.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / test / nptl / tst-barrier3.c
1 /* Copyright (C) 2002 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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    <http://www.gnu.org/licenses/>.  */
18
19 /* Test of POSIX barriers.  */
20
21 #include <pthread.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #define NTHREADS 20
27
28 #define ROUNDS 20
29
30 static pthread_barrier_t barriers[NTHREADS];
31
32 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
33 static int counters[NTHREADS];
34 static int serial[NTHREADS];
35
36 static void *
37 worker (void *arg)
38 {
39   void *result = NULL;
40   int nr = (long int) arg;
41   int i;
42
43   for (i = 0; i < ROUNDS; ++i)
44     {
45       int j;
46       int retval;
47
48       if (nr == 0)
49         {
50           memset (counters, '\0', sizeof (counters));
51           memset (serial, '\0', sizeof (serial));
52         }
53
54       retval = pthread_barrier_wait (&barriers[NTHREADS - 1]);
55       if (retval != 0 && retval != PTHREAD_BARRIER_SERIAL_THREAD)
56         {
57           printf ("thread %d failed to wait for all the others\n", nr);
58           result = (void *) 1;
59         }
60
61       for (j = nr; j < NTHREADS; ++j)
62         {
63           /* Increment the counter for this round.  */
64           pthread_mutex_lock (&lock);
65           ++counters[j];
66           pthread_mutex_unlock (&lock);
67
68           /* Wait for the rest.  */
69           retval = pthread_barrier_wait (&barriers[j]);
70
71           /* Test the result.  */
72           if (nr == 0 && counters[j] != j + 1)
73             {
74               printf ("barrier in round %d released but count is %d\n",
75                       j, counters[j]);
76               result = (void *) 1;
77             }
78
79           if (retval != 0)
80             {
81               if (retval != PTHREAD_BARRIER_SERIAL_THREAD)
82                 {
83                   printf ("thread %d in round %d has nonzero return value != PTHREAD_BARRIER_SERIAL_THREAD\n",
84                           nr, j);
85                   result = (void *) 1;
86                 }
87               else
88                 {
89                   pthread_mutex_lock (&lock);
90                   ++serial[j];
91                   pthread_mutex_unlock (&lock);
92                 }
93             }
94
95           /* Wait for the rest again.  */
96           retval = pthread_barrier_wait (&barriers[j]);
97
98           /* Now we can check whether exactly one thread was serializing.  */
99           if (nr == 0 && serial[j] != 1)
100             {
101               printf ("not exactly one serial thread in round %d\n", j);
102               result = (void *) 1;
103             }
104         }
105     }
106
107   return result;
108 }
109
110
111 #define TEST_FUNCTION do_test ()
112 #define TIMEOUT 60
113 static int
114 do_test (void)
115 {
116   pthread_t threads[NTHREADS];
117   int i;
118   void *res;
119   int result = 0;
120
121   /* Initialized the barrier variables.  */
122   for (i = 0; i < NTHREADS; ++i)
123     if (pthread_barrier_init (&barriers[i], NULL, i + 1) != 0)
124       {
125         printf ("Failed to initialize barrier %d\n", i);
126         exit (1);
127       }
128
129   /* Start the threads.  */
130   for (i = 0; i < NTHREADS; ++i)
131     if (pthread_create (&threads[i], NULL, worker, (void *) (long int) i) != 0)
132       {
133         printf ("Failed to start thread %d\n", i);
134         exit (1);
135       }
136
137   /* And wait for them.  */
138   for (i = 0; i < NTHREADS; ++i)
139     if (pthread_join (threads[i], &res) != 0 || res != NULL)
140       {
141         printf ("thread %d returned a failure\n", i);
142         result = 1;
143       }
144     else
145       printf ("joined threads %d\n", i);
146
147   if (result == 0)
148     puts ("all OK");
149
150   return result;
151 }
152
153 #include "../test-skeleton.c"