1 /*
2 * Copyright (c) 2002, Intel Corporation. All rights reserved.
3 * This file is licensed under the GPL license. For the full content
4 * of this license, see the COPYING file at the top level of this
5 * source tree.
6 *
7 * pthread_barrier_wait()
8 *
9 * When the required number of threads have called pthread_barrier_wait()
10 * specifying the barrier, the constant PTHREAD_BARRIER_SERIAL_THREAD shall
11 * be returned to one unspecified thread and zero shall be returned
12 * to each of the remaining threads. At this point, the barrier shall
13 * be reset to the state it had as a result of the most recent
14 * pthread_barrier_init() function that referenced it.
15 *
16 * Steps:
17 * 1. Main thread do the following for LOOP_NUM times
18 * 2. In each loop, Main thread initialize barrier, with count set to THREAD_NUM
19 * 3. Main create THREAD_NUM threads
20 * 4. Each thread will call pthread_barrier_wait()
21 * 5. When the last thread calls pthread_barrier_wait, only one thread will
22 * get PTHREAD_BARRIER_SERIAL_THREAD, all the other threads should get zero
23 * 6. This holds true for every loop.
24 *
25 */
26
27 #include <pthread.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <signal.h>
32 #include "posixtest.h"
33
34 #define THREAD_NUM 5
35 #define LOOP_NUM 3
36
37 static pthread_barrier_t barrier;
38 static int serial;
39 static int normal_rt;
40 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
41
fn_chld(void * arg)42 static void *fn_chld(void *arg)
43 {
44 int rc = 0;
45 int thread_num = *(int *)arg;
46
47 printf("child[%d]: barrier wait\n", thread_num);
48 rc = pthread_barrier_wait(&barrier);
49 if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
50 printf
51 ("Test FAILED: child[%d]: pthread_barrier_wait() get unexpected "
52 "return code : %d\n", thread_num, rc);
53 exit(PTS_FAIL);
54 } else if (rc == PTHREAD_BARRIER_SERIAL_THREAD) {
55 serial++;
56 printf("child[%d]: get PTHREAD_BARRIER_SERIAL_THREAD\n",
57 thread_num);
58 } else {
59 pthread_mutex_lock(&mutex);
60 normal_rt++;
61 pthread_mutex_unlock(&mutex);
62 }
63
64 pthread_exit(0);
65 return NULL;
66 }
67
main(void)68 int main(void)
69 {
70 pthread_t child_threads[THREAD_NUM];
71 int cnt;
72 int loop;
73
74 printf("Initialize barrier with count = %d\n", THREAD_NUM);
75 if (pthread_barrier_init(&barrier, NULL, THREAD_NUM) != 0) {
76 printf("main: Error at pthread_barrier_init()\n");
77 return PTS_UNRESOLVED;
78 }
79
80 for (loop = 0; loop < LOOP_NUM; loop++) {
81 serial = 0;
82 normal_rt = 0;
83 printf("\n-Loop %d-\n", loop);
84
85 printf("main: create %d child threads\n", THREAD_NUM);
86 for (cnt = 0; cnt < THREAD_NUM; cnt++) {
87 if (pthread_create
88 (&child_threads[cnt], NULL, fn_chld, &cnt) != 0) {
89 printf("main: Error at %dth pthread_create()\n",
90 cnt);
91 return PTS_UNRESOLVED;
92 }
93
94 }
95 printf("main: wait for child threads to end\n");
96 for (cnt = 0; cnt < THREAD_NUM; cnt++) {
97 if (pthread_join(child_threads[cnt], NULL) != 0) {
98 printf("main: Error at %dth pthread_join()\n",
99 cnt);
100 exit(PTS_UNRESOLVED);
101 }
102 }
103
104 if (serial != 1 || (serial + normal_rt) != THREAD_NUM) {
105 printf
106 ("Test FAILED: On %d loop, PTHREAD_BARRIER_SERIAL_THREAD "
107 "should be returned to one unspecified thread\n",
108 loop);
109 return PTS_FAIL;
110 }
111
112 }
113
114 if (pthread_barrier_destroy(&barrier) != 0) {
115 printf("Error at pthread_barrier_destroy()\n");
116 return PTS_UNRESOLVED;
117 }
118
119 printf("\nTest PASSED\n");
120 return PTS_PASS;
121 }
122