Home | History | Annotate | Download | only in pthread_barrier_wait
      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