12c28215423293e443469a07ae7011135d058b671Garrett Cooper/* 20dc076565f772bb1953209fb69ea150b494aaa40robbiew * Copyright (c) 2002, Intel Corporation. All rights reserved. 30dc076565f772bb1953209fb69ea150b494aaa40robbiew * This file is licensed under the GPL license. For the full content 42c28215423293e443469a07ae7011135d058b671Garrett Cooper * of this license, see the COPYING file at the top level of this 50dc076565f772bb1953209fb69ea150b494aaa40robbiew * source tree. 60dc076565f772bb1953209fb69ea150b494aaa40robbiew * 70dc076565f772bb1953209fb69ea150b494aaa40robbiew * pthread_barrier_wait() 80dc076565f772bb1953209fb69ea150b494aaa40robbiew * 92c28215423293e443469a07ae7011135d058b671Garrett Cooper * The pthread_barrier_wait() function shall synchronize participating threads 102c28215423293e443469a07ae7011135d058b671Garrett Cooper * at the barrier referenced by barrier. The calling thread shall block 112c28215423293e443469a07ae7011135d058b671Garrett Cooper * until the required number of threads have called pthread_barrier_wait() 120dc076565f772bb1953209fb69ea150b494aaa40robbiew * specifying the barrier. 130dc076565f772bb1953209fb69ea150b494aaa40robbiew * 140dc076565f772bb1953209fb69ea150b494aaa40robbiew * Steps: 150dc076565f772bb1953209fb69ea150b494aaa40robbiew * 1. Main initialize barrier with count 2 160dc076565f772bb1953209fb69ea150b494aaa40robbiew * 2. Main create a child thread 170dc076565f772bb1953209fb69ea150b494aaa40robbiew * 3. Child thread call pthread_barrier_wait(), should block 182c28215423293e443469a07ae7011135d058b671Garrett Cooper * 4. Main call pthread_barrier_wait(), child and main should all return 190dc076565f772bb1953209fb69ea150b494aaa40robbiew * from pthread_barrier_wait() 200dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 210dc076565f772bb1953209fb69ea150b494aaa40robbiew#define _XOPEN_SOURCE 600 220dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <pthread.h> 230dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdio.h> 240dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdlib.h> 250dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <unistd.h> 260dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <signal.h> 270dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <string.h> 280dc076565f772bb1953209fb69ea150b494aaa40robbiew#include "posixtest.h" 290dc076565f772bb1953209fb69ea150b494aaa40robbiew 300dc076565f772bb1953209fb69ea150b494aaa40robbiewstatic pthread_barrier_t barrier; 312c28215423293e443469a07ae7011135d058b671Garrett Cooperstatic int thread_state; 320dc076565f772bb1953209fb69ea150b494aaa40robbiew#define NOT_CREATED_THREAD 1 330dc076565f772bb1953209fb69ea150b494aaa40robbiew#define ENTERED_THREAD 2 340dc076565f772bb1953209fb69ea150b494aaa40robbiew#define EXITING_THREAD 3 350dc076565f772bb1953209fb69ea150b494aaa40robbiew 36354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void *fn_chld(void *arg) 372c28215423293e443469a07ae7011135d058b671Garrett Cooper{ 380dc076565f772bb1953209fb69ea150b494aaa40robbiew int rc = 0; 390dc076565f772bb1953209fb69ea150b494aaa40robbiew thread_state = ENTERED_THREAD; 402c28215423293e443469a07ae7011135d058b671Garrett Cooper 410dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("child: barrier wait\n"); 420dc076565f772bb1953209fb69ea150b494aaa40robbiew rc = pthread_barrier_wait(&barrier); 43354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { 44354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 45354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Test FAILED: child: pthread_barrier_wait() got unexpected " 46354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "return code : %d\n", rc); 470dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_FAIL); 48354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (rc == PTHREAD_BARRIER_SERIAL_THREAD) { 490dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("child: get PTHREAD_BARRIER_SERIAL_THREAD\n"); 502c28215423293e443469a07ae7011135d058b671Garrett Cooper } 512c28215423293e443469a07ae7011135d058b671Garrett Cooper 520dc076565f772bb1953209fb69ea150b494aaa40robbiew thread_state = EXITING_THREAD; 530dc076565f772bb1953209fb69ea150b494aaa40robbiew pthread_exit(0); 540dc076565f772bb1953209fb69ea150b494aaa40robbiew return NULL; 550dc076565f772bb1953209fb69ea150b494aaa40robbiew} 560dc076565f772bb1953209fb69ea150b494aaa40robbiew 570dc076565f772bb1953209fb69ea150b494aaa40robbiewvoid sig_handler() 580dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 590dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Interrupted by SIGALRM\n"); 600dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Test FAILED: main blocked on barrier wait\n"); 610dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_FAIL); 620dc076565f772bb1953209fb69ea150b494aaa40robbiew} 632c28215423293e443469a07ae7011135d058b671Garrett Cooper 644ca2bbdcd3003f3c8df4e6129e9c7b2bd1514f87Cyril Hrubisint main(void) 650dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 660dc076565f772bb1953209fb69ea150b494aaa40robbiew int cnt = 0; 670dc076565f772bb1953209fb69ea150b494aaa40robbiew int rc; 680dc076565f772bb1953209fb69ea150b494aaa40robbiew pthread_t child_thread; 692c28215423293e443469a07ae7011135d058b671Garrett Cooper struct sigaction act; 700dc076565f772bb1953209fb69ea150b494aaa40robbiew 710dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Set up main thread to handle SIGALRM */ 720dc076565f772bb1953209fb69ea150b494aaa40robbiew act.sa_flags = 0; 730dc076565f772bb1953209fb69ea150b494aaa40robbiew act.sa_handler = sig_handler; 740dc076565f772bb1953209fb69ea150b494aaa40robbiew sigfillset(&act.sa_mask); 750dc076565f772bb1953209fb69ea150b494aaa40robbiew sigaction(SIGALRM, &act, 0); 762c28215423293e443469a07ae7011135d058b671Garrett Cooper 770dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Initialize barrier with count = 2\n"); 78354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_barrier_init(&barrier, NULL, 2) != 0) { 790dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: Error at pthread_barrier_init()\n"); 800dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 810dc076565f772bb1953209fb69ea150b494aaa40robbiew } 820dc076565f772bb1953209fb69ea150b494aaa40robbiew 830dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: create child thread\n"); 840dc076565f772bb1953209fb69ea150b494aaa40robbiew thread_state = NOT_CREATED_THREAD; 85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_create(&child_thread, NULL, fn_chld, NULL) != 0) { 860dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: Error at pthread_create()\n"); 870dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 880dc076565f772bb1953209fb69ea150b494aaa40robbiew } 892c28215423293e443469a07ae7011135d058b671Garrett Cooper 90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Expect the child to block */ 910dc076565f772bb1953209fb69ea150b494aaa40robbiew cnt = 0; 92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao do { 930dc076565f772bb1953209fb69ea150b494aaa40robbiew sleep(1); 94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } while (thread_state != EXITING_THREAD && cnt++ < 2); 952c28215423293e443469a07ae7011135d058b671Garrett Cooper 96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (thread_state == EXITING_THREAD) { 970dc076565f772bb1953209fb69ea150b494aaa40robbiew /* child thread did not block */ 980dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Test FAILED: child thread did not block on " 99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "pthread_barrier_wait()\n"); 1000dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_FAIL); 101354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (thread_state != ENTERED_THREAD) { 1020dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Unexpected thread state: %d\n", thread_state); 1030dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_UNRESOLVED); 1040dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1050dc076565f772bb1953209fb69ea150b494aaa40robbiew 1060dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: call barrier wait\n"); 1072c28215423293e443469a07ae7011135d058b671Garrett Cooper 1080dc076565f772bb1953209fb69ea150b494aaa40robbiew /* we should not block here, but just in case we do */ 1090dc076565f772bb1953209fb69ea150b494aaa40robbiew alarm(2); 1100dc076565f772bb1953209fb69ea150b494aaa40robbiew 1110dc076565f772bb1953209fb69ea150b494aaa40robbiew rc = pthread_barrier_wait(&barrier); 1122c28215423293e443469a07ae7011135d058b671Garrett Cooper 113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { 114354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Test FAILED: main: pthread_barrier_wait() get unexpected " 116354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "return code : %d\n", rc); 1170dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_FAIL); 118354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (rc == PTHREAD_BARRIER_SERIAL_THREAD) { 1190dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: got PTHREAD_BARRIER_SERIAL_THREAD\n"); 1200dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1212c28215423293e443469a07ae7011135d058b671Garrett Cooper 1220dc076565f772bb1953209fb69ea150b494aaa40robbiew /* We expected the child returned from barrier wait */ 1232c28215423293e443469a07ae7011135d058b671Garrett Cooper cnt = 1; 124354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao do { 1250dc076565f772bb1953209fb69ea150b494aaa40robbiew sleep(1); 126354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } while (thread_state != EXITING_THREAD && cnt++ < 3); 1272c28215423293e443469a07ae7011135d058b671Garrett Cooper 128354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (thread_state == ENTERED_THREAD) { 1290dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Test FAILED: child thread still blocked on " 130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "barrier wait\n"); 1310dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_FAIL; 132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (thread_state != EXITING_THREAD) { 1330dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: Unexpected thread state: %d\n", thread_state); 1340dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 1350dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1360dc076565f772bb1953209fb69ea150b494aaa40robbiew 137354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_join(child_thread, NULL) != 0) { 1380dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: Error at pthread_join()\n"); 1390dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_UNRESOLVED); 1400dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1410dc076565f772bb1953209fb69ea150b494aaa40robbiew 142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_barrier_destroy(&barrier) != 0) { 1430dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Error at pthread_barrier_destroy()"); 1440dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 1452c28215423293e443469a07ae7011135d058b671Garrett Cooper } 1460dc076565f772bb1953209fb69ea150b494aaa40robbiew 1470dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Test PASSED\n"); 1480dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_PASS; 149ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 150