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 #define _XOPEN_SOURCE 600 28 #include <pthread.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <signal.h> 33 #include "posixtest.h" 34 35 #define THREAD_NUM 5 36 #define LOOP_NUM 3 37 38 static pthread_barrier_t barrier; 39 static int serial; 40 static int normal_rt; 41 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 42 43 static void *fn_chld(void *arg) 44 { 45 int rc = 0; 46 int thread_num = *(int *)arg; 47 48 printf("child[%d]: barrier wait\n", thread_num); 49 rc = pthread_barrier_wait(&barrier); 50 if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { 51 printf 52 ("Test FAILED: child[%d]: pthread_barrier_wait() get unexpected " 53 "return code : %d\n", thread_num, rc); 54 exit(PTS_FAIL); 55 } else if (rc == PTHREAD_BARRIER_SERIAL_THREAD) { 56 serial++; 57 printf("child[%d]: get PTHREAD_BARRIER_SERIAL_THREAD\n", 58 thread_num); 59 } else { 60 pthread_mutex_lock(&mutex); 61 normal_rt++; 62 pthread_mutex_unlock(&mutex); 63 } 64 65 pthread_exit(0); 66 return NULL; 67 } 68 69 int main(void) 70 { 71 pthread_t child_threads[THREAD_NUM]; 72 int cnt; 73 int loop; 74 75 printf("Initialize barrier with count = %d\n", THREAD_NUM); 76 if (pthread_barrier_init(&barrier, NULL, THREAD_NUM) != 0) { 77 printf("main: Error at pthread_barrier_init()\n"); 78 return PTS_UNRESOLVED; 79 } 80 81 for (loop = 0; loop < LOOP_NUM; loop++) { 82 serial = 0; 83 normal_rt = 0; 84 printf("\n-Loop %d-\n", loop); 85 86 printf("main: create %d child threads\n", THREAD_NUM); 87 for (cnt = 0; cnt < THREAD_NUM; cnt++) { 88 if (pthread_create 89 (&child_threads[cnt], NULL, fn_chld, &cnt) != 0) { 90 printf("main: Error at %dth pthread_create()\n", 91 cnt); 92 return PTS_UNRESOLVED; 93 } 94 95 } 96 printf("main: wait for child threads to end\n"); 97 for (cnt = 0; cnt < THREAD_NUM; cnt++) { 98 if (pthread_join(child_threads[cnt], NULL) != 0) { 99 printf("main: Error at %dth pthread_join()\n", 100 cnt); 101 exit(PTS_UNRESOLVED); 102 } 103 } 104 105 if (serial != 1 || (serial + normal_rt) != THREAD_NUM) { 106 printf 107 ("Test FAILED: On %d loop, PTHREAD_BARRIER_SERIAL_THREAD " 108 "should be returned to one unspecified thread\n", 109 loop); 110 return PTS_FAIL; 111 } 112 113 } 114 115 if (pthread_barrier_destroy(&barrier) != 0) { 116 printf("Error at pthread_barrier_destroy()"); 117 return PTS_UNRESOLVED; 118 } 119 120 printf("\nTest PASSED\n"); 121 return PTS_PASS; 122 } 123