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 * When the required number of threads have called pthread_barrier_wait() 102c28215423293e443469a07ae7011135d058b671Garrett Cooper * specifying the barrier, the constant PTHREAD_BARRIER_SERIAL_THREAD shall 112c28215423293e443469a07ae7011135d058b671Garrett Cooper * be returned to one unspecified thread and zero shall be returned 120dc076565f772bb1953209fb69ea150b494aaa40robbiew * to each of the remaining threads. At this point, the barrier shall 132c28215423293e443469a07ae7011135d058b671Garrett Cooper * be reset to the state it had as a result of the most recent 14e9410dfd93b8e415ecbe3f7e09a085462b27836eGarrett Cooper * pthread_barrier_init() function that referenced it. 152c28215423293e443469a07ae7011135d058b671Garrett Cooper * 160dc076565f772bb1953209fb69ea150b494aaa40robbiew * Steps: 170dc076565f772bb1953209fb69ea150b494aaa40robbiew * 1. Main thread do the following for LOOP_NUM times 180dc076565f772bb1953209fb69ea150b494aaa40robbiew * 2. In each loop, Main thread initialize barrier, with count set to THREAD_NUM 190dc076565f772bb1953209fb69ea150b494aaa40robbiew * 3. Main create THREAD_NUM threads 200dc076565f772bb1953209fb69ea150b494aaa40robbiew * 4. Each thread will call pthread_barrier_wait() 212c28215423293e443469a07ae7011135d058b671Garrett Cooper * 5. When the last thread calls pthread_barrier_wait, only one thread will 220dc076565f772bb1953209fb69ea150b494aaa40robbiew * get PTHREAD_BARRIER_SERIAL_THREAD, all the other threads should get zero 230dc076565f772bb1953209fb69ea150b494aaa40robbiew * 6. This holds true for every loop. 242c28215423293e443469a07ae7011135d058b671Garrett Cooper * 250dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 260dc076565f772bb1953209fb69ea150b494aaa40robbiew 270dc076565f772bb1953209fb69ea150b494aaa40robbiew#define _XOPEN_SOURCE 600 280dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <pthread.h> 290dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdio.h> 300dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdlib.h> 310dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <unistd.h> 320dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <signal.h> 330dc076565f772bb1953209fb69ea150b494aaa40robbiew#include "posixtest.h" 340dc076565f772bb1953209fb69ea150b494aaa40robbiew 352c28215423293e443469a07ae7011135d058b671Garrett Cooper#define THREAD_NUM 5 362c28215423293e443469a07ae7011135d058b671Garrett Cooper#define LOOP_NUM 3 370dc076565f772bb1953209fb69ea150b494aaa40robbiew 380dc076565f772bb1953209fb69ea150b494aaa40robbiewstatic pthread_barrier_t barrier; 390dc076565f772bb1953209fb69ea150b494aaa40robbiewstatic int serial; 400dc076565f772bb1953209fb69ea150b494aaa40robbiewstatic int normal_rt; 4104c9398977a261ffca56f61196439a6af4e8922cWei Yangstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 420dc076565f772bb1953209fb69ea150b494aaa40robbiew 43354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void *fn_chld(void *arg) 442c28215423293e443469a07ae7011135d058b671Garrett Cooper{ 450dc076565f772bb1953209fb69ea150b494aaa40robbiew int rc = 0; 46354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int thread_num = *(int *)arg; 472c28215423293e443469a07ae7011135d058b671Garrett Cooper 480dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("child[%d]: barrier wait\n", thread_num); 490dc076565f772bb1953209fb69ea150b494aaa40robbiew rc = pthread_barrier_wait(&barrier); 50354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { 51354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 52354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Test FAILED: child[%d]: pthread_barrier_wait() get unexpected " 53354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "return code : %d\n", thread_num, rc); 540dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_FAIL); 55354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (rc == PTHREAD_BARRIER_SERIAL_THREAD) { 560dc076565f772bb1953209fb69ea150b494aaa40robbiew serial++; 57354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("child[%d]: get PTHREAD_BARRIER_SERIAL_THREAD\n", 58354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao thread_num); 59354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 6004c9398977a261ffca56f61196439a6af4e8922cWei Yang pthread_mutex_lock(&mutex); 610dc076565f772bb1953209fb69ea150b494aaa40robbiew normal_rt++; 6204c9398977a261ffca56f61196439a6af4e8922cWei Yang pthread_mutex_unlock(&mutex); 630dc076565f772bb1953209fb69ea150b494aaa40robbiew } 642c28215423293e443469a07ae7011135d058b671Garrett Cooper 650dc076565f772bb1953209fb69ea150b494aaa40robbiew pthread_exit(0); 660dc076565f772bb1953209fb69ea150b494aaa40robbiew return NULL; 670dc076565f772bb1953209fb69ea150b494aaa40robbiew} 682c28215423293e443469a07ae7011135d058b671Garrett Cooper 694ca2bbdcd3003f3c8df4e6129e9c7b2bd1514f87Cyril Hrubisint main(void) 700dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 710dc076565f772bb1953209fb69ea150b494aaa40robbiew pthread_t child_threads[THREAD_NUM]; 720dc076565f772bb1953209fb69ea150b494aaa40robbiew int cnt; 730dc076565f772bb1953209fb69ea150b494aaa40robbiew int loop; 740dc076565f772bb1953209fb69ea150b494aaa40robbiew 750dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Initialize barrier with count = %d\n", THREAD_NUM); 76354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_barrier_init(&barrier, NULL, THREAD_NUM) != 0) { 770dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: Error at pthread_barrier_init()\n"); 780dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 790dc076565f772bb1953209fb69ea150b494aaa40robbiew } 800dc076565f772bb1953209fb69ea150b494aaa40robbiew 81354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (loop = 0; loop < LOOP_NUM; loop++) { 820dc076565f772bb1953209fb69ea150b494aaa40robbiew serial = 0; 830dc076565f772bb1953209fb69ea150b494aaa40robbiew normal_rt = 0; 840dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("\n-Loop %d-\n", loop); 850dc076565f772bb1953209fb69ea150b494aaa40robbiew 860dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: create %d child threads\n", THREAD_NUM); 87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (cnt = 0; cnt < THREAD_NUM; cnt++) { 88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_create 89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (&child_threads[cnt], NULL, fn_chld, &cnt) != 0) { 90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("main: Error at %dth pthread_create()\n", 91354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao cnt); 920dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 930dc076565f772bb1953209fb69ea150b494aaa40robbiew } 942c28215423293e443469a07ae7011135d058b671Garrett Cooper 950dc076565f772bb1953209fb69ea150b494aaa40robbiew } 960dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("main: wait for child threads to end\n"); 97354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (cnt = 0; cnt < THREAD_NUM; cnt++) { 98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_join(child_threads[cnt], NULL) != 0) { 99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("main: Error at %dth pthread_join()\n", 100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao cnt); 1010dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_UNRESOLVED); 1020dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1030dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1042c28215423293e443469a07ae7011135d058b671Garrett Cooper 105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (serial != 1 || (serial + normal_rt) != THREAD_NUM) { 106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Test FAILED: On %d loop, PTHREAD_BARRIER_SERIAL_THREAD " 108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "should be returned to one unspecified thread\n", 109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao loop); 1100dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_FAIL; 1110dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1122c28215423293e443469a07ae7011135d058b671Garrett Cooper 1130dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1140dc076565f772bb1953209fb69ea150b494aaa40robbiew 115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_barrier_destroy(&barrier) != 0) { 1160dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Error at pthread_barrier_destroy()"); 1170dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 1182c28215423293e443469a07ae7011135d058b671Garrett Cooper } 1190dc076565f772bb1953209fb69ea150b494aaa40robbiew 1200dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("\nTest PASSED\n"); 1210dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_PASS; 12204c9398977a261ffca56f61196439a6af4e8922cWei Yang} 123