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 * The idea of this case comes from GNU C library NPTL test tst-barrier2.c. 80dc076565f772bb1953209fb69ea150b494aaa40robbiew * 92c28215423293e443469a07ae7011135d058b671Garrett Cooper * The process-shared attribute is set to PTHREAD_PROCESS_SHARED to permit 102c28215423293e443469a07ae7011135d058b671Garrett Cooper * a barrier to be operated upon by any thread that has access to the memory 112c28215423293e443469a07ae7011135d058b671Garrett Cooper * where the barrier is allocated. If the process-shared attribute 120dc076565f772bb1953209fb69ea150b494aaa40robbiew * is PTHREAD_PROCESS_PRIVATE, the barrier shall only be operated 132c28215423293e443469a07ae7011135d058b671Garrett Cooper * upon by threads created within the same process as the thread 142c28215423293e443469a07ae7011135d058b671Garrett Cooper * that initialized the barrier; if threads of different processes attempt 150dc076565f772bb1953209fb69ea150b494aaa40robbiew * to operate on such a barrier, the behavior is undefined. 160dc076565f772bb1953209fb69ea150b494aaa40robbiew * The default value of the attribute shall be PTHREAD_PROCESS_PRIVATE. Both constants 170dc076565f772bb1953209fb69ea150b494aaa40robbiew * PTHREAD_PROCESS_SHARED and PTHREAD_PROCESS_PRIVATE are defined in <pthread.h>. 180dc076565f772bb1953209fb69ea150b494aaa40robbiew * 190dc076565f772bb1953209fb69ea150b494aaa40robbiew * steps: 200dc076565f772bb1953209fb69ea150b494aaa40robbiew * 1. Create a piece of shared memory object, create pthread barrier object 'barrier' 210dc076565f772bb1953209fb69ea150b494aaa40robbiew * and set the PTHREAD_PROCESS_SHARED attribute. 220dc076565f772bb1953209fb69ea150b494aaa40robbiew * 2. Parent map the shared memory to its memory space, put 'barrier' into it; 230dc076565f772bb1953209fb69ea150b494aaa40robbiew * 3. Parent fork to create child process; 240dc076565f772bb1953209fb69ea150b494aaa40robbiew * 4. Child process map the 'barrier' to its memory space; 250dc076565f772bb1953209fb69ea150b494aaa40robbiew * 5. Parent and Child execute same code: loop N times, calling pthread_barrier_wait() 262c28215423293e443469a07ae7011135d058b671Garrett Cooper * 6. Parent and Child should not block on pthread_barrier_wait() 270dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 280dc076565f772bb1953209fb69ea150b494aaa40robbiew 290dc076565f772bb1953209fb69ea150b494aaa40robbiew#define _XOPEN_SOURCE 600 300dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <pthread.h> 310dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdio.h> 320dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdlib.h> 330dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <unistd.h> 340dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <errno.h> 350dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/mman.h> 360dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <fcntl.h> 370dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/wait.h> 380dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/stat.h> 390dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <signal.h> 400dc076565f772bb1953209fb69ea150b494aaa40robbiew#include "posixtest.h" 410dc076565f772bb1953209fb69ea150b494aaa40robbiew 420dc076565f772bb1953209fb69ea150b494aaa40robbiew#define LOOP_NUM 10 430dc076565f772bb1953209fb69ea150b494aaa40robbiew 440dc076565f772bb1953209fb69ea150b494aaa40robbiewvoid sig_handler() 450dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 460dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Interrupted by SIGALRM\n"); 470dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Test Fail: block on pthread_barrier_wait()\n"); 480dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_FAIL); 490dc076565f772bb1953209fb69ea150b494aaa40robbiew} 500dc076565f772bb1953209fb69ea150b494aaa40robbiew 514ca2bbdcd3003f3c8df4e6129e9c7b2bd1514f87Cyril Hrubisint main(void) 520dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 532c28215423293e443469a07ae7011135d058b671Garrett Cooper 542c28215423293e443469a07ae7011135d058b671Garrett Cooper /* Make sure there is process-shared capability. */ 55354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#ifndef PTHREAD_PROCESS_SHARED 56354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 57354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "process-shared attribute is not available for testing\n"); 58354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return PTS_UNSUPPORTED; 59354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#endif 600dc076565f772bb1953209fb69ea150b494aaa40robbiew 61354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao static pthread_barrier_t *barrier; 620dc076565f772bb1953209fb69ea150b494aaa40robbiew pthread_barrierattr_t ba; 63354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int pshared = PTHREAD_PROCESS_SHARED; 64354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 65354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char shm_name[] = "tmp_pthread_barrierattr_getpshared"; 66354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int shm_fd; 67354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int pid; 68354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int loop; 69354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int serial = 0; 70354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int rc; 71354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int status = 0; 720dc076565f772bb1953209fb69ea150b494aaa40robbiew struct sigaction act; 732c28215423293e443469a07ae7011135d058b671Garrett Cooper 740dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Set up parent to handle SIGALRM */ 750dc076565f772bb1953209fb69ea150b494aaa40robbiew act.sa_flags = 0; 760dc076565f772bb1953209fb69ea150b494aaa40robbiew act.sa_handler = sig_handler; 770dc076565f772bb1953209fb69ea150b494aaa40robbiew sigfillset(&act.sa_mask); 780dc076565f772bb1953209fb69ea150b494aaa40robbiew sigaction(SIGALRM, &act, 0); 790dc076565f772bb1953209fb69ea150b494aaa40robbiew 800dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Initialize a barrier attributes object */ 81354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_barrierattr_init(&ba) != 0) { 820dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Error at pthread_barrierattr_init()\n"); 830dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 840dc076565f772bb1953209fb69ea150b494aaa40robbiew } 852c28215423293e443469a07ae7011135d058b671Garrett Cooper 860dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Set the pshard value to private to shared */ 87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_barrierattr_setpshared(&ba, pshared) != 0) { 880dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Error at pthread_barrierattr_setpshared()\n"); 890dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 900dc076565f772bb1953209fb69ea150b494aaa40robbiew } 912c28215423293e443469a07ae7011135d058b671Garrett Cooper 92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_barrierattr_getpshared(&ba, &pshared) != 0) { 93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Test FAILED: Error at pthread_barrierattr_getpshared()\n"); 950dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_FAIL; 960dc076565f772bb1953209fb69ea150b494aaa40robbiew } 972c28215423293e443469a07ae7011135d058b671Garrett Cooper 98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pshared != PTHREAD_PROCESS_SHARED) { 990dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Test FAILED: Incorrect pshared value %d\n", pshared); 1000dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_FAIL; 1010dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1022c28215423293e443469a07ae7011135d058b671Garrett Cooper 1030dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Create shared object */ 1040dc076565f772bb1953209fb69ea150b494aaa40robbiew shm_unlink(shm_name); 105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao shm_fd = 106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao shm_open(shm_name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); 107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (shm_fd == -1) { 1080dc076565f772bb1953209fb69ea150b494aaa40robbiew perror("Error at shm_open()"); 1090dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 1100dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1112c28215423293e443469a07ae7011135d058b671Garrett Cooper 112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ftruncate(shm_fd, sizeof(pthread_barrier_t)) != 0) { 113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao perror("Error at ftruncate()"); 114354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao shm_unlink(shm_name); 115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return PTS_UNRESOLVED; 116354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 1172c28215423293e443469a07ae7011135d058b671Garrett Cooper 1180dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Map the shared memory object to my memory */ 119354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao barrier = mmap(NULL, sizeof(pthread_barrier_t), PROT_READ | PROT_WRITE, 120354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao MAP_SHARED, shm_fd, 0); 1210dc076565f772bb1953209fb69ea150b494aaa40robbiew 122354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (barrier == MAP_FAILED) { 1230dc076565f772bb1953209fb69ea150b494aaa40robbiew perror("Error at first mmap()"); 124354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao shm_unlink(shm_name); 1250dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 1260dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1272c28215423293e443469a07ae7011135d058b671Garrett Cooper 1280dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Initialize a barrier */ 129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((pthread_barrier_init(barrier, &ba, 2)) != 0) { 1300dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Error at pthread_barrier_init()\n"); 1310dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 1320dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1330dc076565f772bb1953209fb69ea150b494aaa40robbiew 1342c28215423293e443469a07ae7011135d058b671Garrett Cooper /* Cleanup */ 135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((pthread_barrierattr_destroy(&ba)) != 0) { 1360dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Error at pthread_barrierattr_destroy()\n"); 1370dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 1380dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1390dc076565f772bb1953209fb69ea150b494aaa40robbiew 1400dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Fork a child process */ 1410dc076565f772bb1953209fb69ea150b494aaa40robbiew pid = fork(); 142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pid == -1) { 1430dc076565f772bb1953209fb69ea150b494aaa40robbiew perror("Error at fork()"); 1440dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 145354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (pid == 0) { 1460dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Child */ 1470dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Map the shared object to child's memory */ 148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao barrier = 149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao mmap(NULL, sizeof(pthread_barrier_t), 150354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); 1510dc076565f772bb1953209fb69ea150b494aaa40robbiew 152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (barrier == MAP_FAILED) { 1530dc076565f772bb1953209fb69ea150b494aaa40robbiew perror("child: Error at first mmap()"); 1540dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 1550dc076565f772bb1953209fb69ea150b494aaa40robbiew } 156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 1570dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("parent pid : %d, child pid : %d\n", getpid(), pid); 158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("parent: send me SIGALRM 2 secs later in case I am blocked\n"); 1600dc076565f772bb1953209fb69ea150b494aaa40robbiew alarm(2); 1610dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1620dc076565f772bb1953209fb69ea150b494aaa40robbiew 163354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao for (loop = 0; loop < LOOP_NUM; loop++) { 1640dc076565f772bb1953209fb69ea150b494aaa40robbiew rc = pthread_barrier_wait(barrier); 165354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { 166354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 167354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Test FAILED: %d: pthread_barrier_wait() got unexpected " 168354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "return code : %d\n", getpid(), rc); 1690dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(PTS_FAIL); 170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (rc == PTHREAD_BARRIER_SERIAL_THREAD) { 1710dc076565f772bb1953209fb69ea150b494aaa40robbiew serial++; 172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("process %d: get PTHREAD_BARRIER_SERIAL_THREAD\n", 174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao getpid()); 1750dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1762c28215423293e443469a07ae7011135d058b671Garrett Cooper 1770dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1780dc076565f772bb1953209fb69ea150b494aaa40robbiew 179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pid > 0) { 1800dc076565f772bb1953209fb69ea150b494aaa40robbiew /* parent */ 181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (wait(&status) != pid) { 1820dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("parent: error at waitpid()\n"); 1830dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 1840dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1852c28215423293e443469a07ae7011135d058b671Garrett Cooper 186354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!WIFEXITED(status)) { 1870dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Child exited abnormally\n"); 1882c28215423293e443469a07ae7011135d058b671Garrett Cooper return PTS_UNRESOLVED; 1892c28215423293e443469a07ae7011135d058b671Garrett Cooper } 1900dc076565f772bb1953209fb69ea150b494aaa40robbiew 191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((WEXITSTATUS(status) + serial) != LOOP_NUM) { 1920dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("status = %d\n", status); 1930dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("serial = %d\n", serial); 194354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 195354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Test FAILED: One of the two processes should get " 196354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "PTHREAD_BARRIER_SERIAL_THREAD\n"); 1970dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_FAIL; 1980dc076565f772bb1953209fb69ea150b494aaa40robbiew } 1992c28215423293e443469a07ae7011135d058b671Garrett Cooper 2000dc076565f772bb1953209fb69ea150b494aaa40robbiew /* Cleanup */ 201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pthread_barrier_destroy(barrier) != 0) { 2020dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Error at pthread_barrier_destroy()"); 2030dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 2042c28215423293e443469a07ae7011135d058b671Garrett Cooper } 2052c28215423293e443469a07ae7011135d058b671Garrett Cooper 206354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((shm_unlink(shm_name)) != 0) { 2070dc076565f772bb1953209fb69ea150b494aaa40robbiew perror("Error at shm_unlink()"); 2080dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_UNRESOLVED; 2092c28215423293e443469a07ae7011135d058b671Garrett Cooper } 2102c28215423293e443469a07ae7011135d058b671Garrett Cooper 2110dc076565f772bb1953209fb69ea150b494aaa40robbiew printf("Test PASSED\n"); 2120dc076565f772bb1953209fb69ea150b494aaa40robbiew return PTS_PASS; 2130dc076565f772bb1953209fb69ea150b494aaa40robbiew } 2142c28215423293e443469a07ae7011135d058b671Garrett Cooper 215354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pid == 0) { 2160dc076565f772bb1953209fb69ea150b494aaa40robbiew exit(serial); 2170dc076565f772bb1953209fb69ea150b494aaa40robbiew } 2182c28215423293e443469a07ae7011135d058b671Garrett Cooper 219ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 220