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 * The pthread_barrier_wait() function shall synchronize participating threads 10 * at the barrier referenced by barrier. The calling thread shall block 11 * until the required number of threads have called pthread_barrier_wait() 12 * specifying the barrier. 13 * 14 * Steps: 15 * 1. Main initialize barrier with count 2 16 * 2. Main create a child thread 17 * 3. Child thread call pthread_barrier_wait(), should block 18 * 4. Main call pthread_barrier_wait(), child and main should all return 19 * from pthread_barrier_wait() 20 */ 21 #define _XOPEN_SOURCE 600 22 #include <pthread.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <unistd.h> 26 #include <signal.h> 27 #include <string.h> 28 #include "posixtest.h" 29 30 static pthread_barrier_t barrier; 31 static int thread_state; 32 #define NOT_CREATED_THREAD 1 33 #define ENTERED_THREAD 2 34 #define EXITING_THREAD 3 35 36 static void *fn_chld(void *arg) 37 { 38 int rc = 0; 39 thread_state = ENTERED_THREAD; 40 41 printf("child: barrier wait\n"); 42 rc = pthread_barrier_wait(&barrier); 43 if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { 44 printf 45 ("Test FAILED: child: pthread_barrier_wait() got unexpected " 46 "return code : %d\n", rc); 47 exit(PTS_FAIL); 48 } else if (rc == PTHREAD_BARRIER_SERIAL_THREAD) { 49 printf("child: get PTHREAD_BARRIER_SERIAL_THREAD\n"); 50 } 51 52 thread_state = EXITING_THREAD; 53 pthread_exit(0); 54 return NULL; 55 } 56 57 void sig_handler() 58 { 59 printf("Interrupted by SIGALRM\n"); 60 printf("Test FAILED: main blocked on barrier wait\n"); 61 exit(PTS_FAIL); 62 } 63 64 int main(void) 65 { 66 int cnt = 0; 67 int rc; 68 pthread_t child_thread; 69 struct sigaction act; 70 71 /* Set up main thread to handle SIGALRM */ 72 act.sa_flags = 0; 73 act.sa_handler = sig_handler; 74 sigfillset(&act.sa_mask); 75 sigaction(SIGALRM, &act, 0); 76 77 printf("Initialize barrier with count = 2\n"); 78 if (pthread_barrier_init(&barrier, NULL, 2) != 0) { 79 printf("main: Error at pthread_barrier_init()\n"); 80 return PTS_UNRESOLVED; 81 } 82 83 printf("main: create child thread\n"); 84 thread_state = NOT_CREATED_THREAD; 85 if (pthread_create(&child_thread, NULL, fn_chld, NULL) != 0) { 86 printf("main: Error at pthread_create()\n"); 87 return PTS_UNRESOLVED; 88 } 89 90 /* Expect the child to block */ 91 cnt = 0; 92 do { 93 sleep(1); 94 } while (thread_state != EXITING_THREAD && cnt++ < 2); 95 96 if (thread_state == EXITING_THREAD) { 97 /* child thread did not block */ 98 printf("Test FAILED: child thread did not block on " 99 "pthread_barrier_wait()\n"); 100 exit(PTS_FAIL); 101 } else if (thread_state != ENTERED_THREAD) { 102 printf("Unexpected thread state: %d\n", thread_state); 103 exit(PTS_UNRESOLVED); 104 } 105 106 printf("main: call barrier wait\n"); 107 108 /* we should not block here, but just in case we do */ 109 alarm(2); 110 111 rc = pthread_barrier_wait(&barrier); 112 113 if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { 114 printf 115 ("Test FAILED: main: pthread_barrier_wait() get unexpected " 116 "return code : %d\n", rc); 117 exit(PTS_FAIL); 118 } else if (rc == PTHREAD_BARRIER_SERIAL_THREAD) { 119 printf("main: got PTHREAD_BARRIER_SERIAL_THREAD\n"); 120 } 121 122 /* We expected the child returned from barrier wait */ 123 cnt = 1; 124 do { 125 sleep(1); 126 } while (thread_state != EXITING_THREAD && cnt++ < 3); 127 128 if (thread_state == ENTERED_THREAD) { 129 printf("Test FAILED: child thread still blocked on " 130 "barrier wait\n"); 131 return PTS_FAIL; 132 } else if (thread_state != EXITING_THREAD) { 133 printf("main: Unexpected thread state: %d\n", thread_state); 134 return PTS_UNRESOLVED; 135 } 136 137 if (pthread_join(child_thread, NULL) != 0) { 138 printf("main: Error at pthread_join()\n"); 139 exit(PTS_UNRESOLVED); 140 } 141 142 if (pthread_barrier_destroy(&barrier) != 0) { 143 printf("Error at pthread_barrier_destroy()"); 144 return PTS_UNRESOLVED; 145 } 146 147 printf("Test PASSED\n"); 148 return PTS_PASS; 149 } 150