static void print_shared(pthread_barrierattr_t *attr) { int rc; int shared; char *s; rc = pthread_barrierattr_getpshared( attr, &shared ); assert( rc == 0 ); switch ( shared ) { case PTHREAD_PROCESS_PRIVATE: s = "PTHREAD_PROCESS_PRIVATE"; break; case PTHREAD_PROCESS_SHARED: s = "PTHREAD_PROCESS_SHARED"; break; default: s = "UNKNOWN"; break; } printf( "Process shared: %s\n", s ); }
int main() { int rc; pthread_barrierattr_t ba; int pshared; /* Initialize the barrier attribute object */ rc = pthread_barrierattr_init(&ba); if (rc != 0) { printf("Test FAILED: Error while initialize attribute object\n"); return PTS_FAIL; } /* Get the pshared value of the initialized barrierattr object */ if (pthread_barrierattr_getpshared(&ba, &pshared) != 0) { printf("Error at pthread_barrierattr_getpshared()\n"); return PTS_UNRESOLVED; } /* The default should be PTHREAD_PROCESS_PRIVATE */ if (pshared != PTHREAD_PROCESS_PRIVATE) { printf("Test FAILED: The process shared attribute was not set to " "default value\n"); return PTS_FAIL; } /* Cleanup */ rc = pthread_barrierattr_destroy(&ba); if (rc != 0) { printf("Error at pthread_barrierattr_destroy() " "return code: %d, %s", rc, strerror(rc)); return PTS_UNRESOLVED; } printf("Test PASSED\n"); return PTS_PASS; }
int main (int argc, char **argv) { pthread_barrierattr_t attr; pthread_barrier_t barrier; int i, j; error_t err; pthread_t tid[THREADS]; int havesyncs; err = pthread_barrierattr_init (&attr); if (err) error (1, err, "pthread_barrierattr_init"); err = pthread_barrierattr_getpshared (&attr, &i); if (err) error (1, err, "pthread_barrierattr_getpshared"); assert (i == PTHREAD_PROCESS_PRIVATE || i == PTHREAD_PROCESS_SHARED); err = pthread_barrierattr_setpshared (&attr, PTHREAD_PROCESS_PRIVATE); if (err) error (1, err, "pthread_barrierattr_setpshared"); err = pthread_barrier_init (&barrier, &attr, THREADS + 1); if (err) error (1, err, "pthread_barrier_init"); for (j = 0; j < WAITS; j ++) { for (i = 0; i < THREADS; i ++) { err = pthread_create (&tid[i], 0, dowait, &barrier); if (err) error (1, err, "pthread_create (%d)", i); } printf ("Manager will now call pthread_barrier_wait.\n"); havesyncs = pthread_barrier_wait (&barrier) == PTHREAD_BARRIER_SERIAL_THREAD ? 1 : 0; for (i = THREADS - 1; i >= 0; i --) { void *ret; err = pthread_join (tid[i], &ret); if (err) error (1, err, "pthread_join"); switch ((int) ret) { case 0: break; case PTHREAD_BARRIER_SERIAL_THREAD: havesyncs ++; break; default: assert (! "Unknown value returned from pthread_barrier_wait."); break; } } printf ("\n"); assert (havesyncs == 1); } return 0; }
static int do_test (void) { size_t ps = sysconf (_SC_PAGESIZE); char tmpfname[] = "/tmp/tst-barrier2.XXXXXX"; char data[ps]; void *mem; int fd; pthread_barrier_t *b; pthread_barrierattr_t a; pid_t pid; int serials = 0; int cnt; int status; int p; fd = mkstemp (tmpfname); if (fd == -1) { printf ("cannot open temporary file: %m\n"); return 1; } /* Make sure it is always removed. */ unlink (tmpfname); /* Create one page of data. */ memset (data, '\0', ps); /* Write the data to the file. */ if (write (fd, data, ps) != (ssize_t) ps) { puts ("short write"); return 1; } mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { printf ("mmap failed: %m\n"); return 1; } b = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t)) & ~(__alignof (pthread_barrier_t) - 1)); if (pthread_barrierattr_init (&a) != 0) { puts ("barrierattr_init failed"); return 1; } if (pthread_barrierattr_getpshared (&a, &p) != 0) { puts ("1st barrierattr_getpshared failed"); return 1; } if (p != PTHREAD_PROCESS_PRIVATE) { puts ("default pshared value wrong"); return 1; } if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed"); return 1; } if (pthread_barrierattr_getpshared (&a, &p) != 0) { puts ("2nd barrierattr_getpshared failed"); return 1; } if (p != PTHREAD_PROCESS_SHARED) { puts ("pshared value after setpshared call wrong"); return 1; } if (pthread_barrier_init (b, &a, 2) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrierattr_destroy (&a) != 0) { puts ("barrierattr_destroy failed"); return 1; } puts ("going to fork now"); pid = fork (); if (pid == -1) { puts ("fork failed"); return 1; } /* Just to be sure we don't hang forever. */ alarm (4); #define N 30 for (cnt = 0; cnt < N; ++cnt) { int e; e = pthread_barrier_wait (b); if (e == PTHREAD_BARRIER_SERIAL_THREAD) ++serials; else if (e != 0) { printf ("%s: barrier_wait returned value %d != 0 and PTHREAD_BARRIER_SERIAL_THREAD\n", pid == 0 ? "child" : "parent", e); return 1; } } alarm (0); printf ("%s: was %d times the serial thread\n", pid == 0 ? "child" : "parent", serials); if (pid == 0) /* The child. Pass the number of times we had the serializing thread back to the parent. */ exit (serials); if (waitpid (pid, &status, 0) != pid) { puts ("waitpid failed"); return 1; } if (!WIFEXITED (status)) { puts ("child exited abnormally"); return 1; } if (WEXITSTATUS (status) + serials != N) { printf ("total number of serials is %d, expected %d\n", WEXITSTATUS (status) + serials, N); return 1; } return 0; }
int main() { /* Make sure there is process-shared capability. */ #ifndef PTHREAD_PROCESS_SHARED fprintf(stderr,"process-shared attribute is not available for testing\n"); return PTS_UNSUPPORTED; #endif static pthread_barrier_t* barrier; pthread_barrierattr_t ba; int pshared = PTHREAD_PROCESS_SHARED; char shm_name[] = "tmp_pthread_barrierattr_getpshared"; int shm_fd; int pid; int loop; int serial = 0; int rc; int status = 0; struct sigaction act; /* Set up parent to handle SIGALRM */ act.sa_flags = 0; act.sa_handler = sig_handler; sigfillset(&act.sa_mask); sigaction(SIGALRM, &act, 0); /* Initialize a barrier attributes object */ if(pthread_barrierattr_init(&ba) != 0) { printf("Error at pthread_barrierattr_init()\n"); return PTS_UNRESOLVED; } /* Set the pshard value to private to shared */ if(pthread_barrierattr_setpshared(&ba, pshared) != 0) { printf("Error at pthread_barrierattr_setpshared()\n"); return PTS_UNRESOLVED; } if(pthread_barrierattr_getpshared(&ba, &pshared) != 0) { printf("Test FAILED: Error at pthread_barrierattr_getpshared()\n"); return PTS_FAIL; } if(pshared != PTHREAD_PROCESS_SHARED) { printf("Test FAILED: Incorrect pshared value %d\n", pshared); return PTS_FAIL; } /* Create shared object */ shm_unlink(shm_name); shm_fd = shm_open(shm_name, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR); if(shm_fd == -1) { perror("Error at shm_open()"); return PTS_UNRESOLVED; } if(ftruncate(shm_fd, sizeof(pthread_barrier_t)) != 0) { perror("Error at ftruncate()"); shm_unlink(shm_name); return PTS_UNRESOLVED; } /* Map the shared memory object to my memory */ barrier = mmap(NULL, sizeof(pthread_barrier_t), PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0); if(barrier == MAP_FAILED) { perror("Error at first mmap()"); shm_unlink(shm_name); return PTS_UNRESOLVED; } /* Initialize a barrier */ if((pthread_barrier_init(barrier, &ba, 2)) != 0) { printf("Error at pthread_barrier_init()\n"); return PTS_UNRESOLVED; } /* Cleanup */ if((pthread_barrierattr_destroy(&ba)) != 0) { printf("Error at pthread_barrierattr_destroy()\n"); return PTS_UNRESOLVED; } /* Fork a child process */ pid = fork(); if(pid == -1) { perror("Error at fork()"); return PTS_UNRESOLVED; } else if(pid == 0) { /* Child */ /* Map the shared object to child's memory */ barrier = mmap(NULL, sizeof(pthread_barrier_t), PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0); if(barrier == MAP_FAILED) { perror("child: Error at first mmap()"); return PTS_UNRESOLVED; } } else { printf("parent pid : %d, child pid : %d\n", getpid(), pid); printf("parent: send me SIGALRM 2 secs later in case I am blocked\n"); alarm(2); } for(loop = 0; loop < LOOP_NUM; loop++) { rc = pthread_barrier_wait(barrier); if(rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { printf("Test FAILED: %d: pthread_barrier_wait() got unexpected " "return code : %d\n" , getpid(), rc); exit(PTS_FAIL); } else if(rc == PTHREAD_BARRIER_SERIAL_THREAD) { serial++; printf("process %d: get PTHREAD_BARRIER_SERIAL_THREAD\n" , getpid()); } } if(pid > 0) { /* parent */ if( wait(&status) != pid) { printf("parent: error at waitpid()\n"); return PTS_UNRESOLVED; } if(!WIFEXITED(status)) { printf("Child exited abnormally\n"); return PTS_UNRESOLVED; } if((WEXITSTATUS(status) + serial) != LOOP_NUM) { printf("status = %d\n", status); printf("serial = %d\n", serial); printf("Test FAILED: One of the two processes should get " "PTHREAD_BARRIER_SERIAL_THREAD\n"); return PTS_FAIL; } /* Cleanup */ if(pthread_barrier_destroy(barrier) != 0) { printf("Error at pthread_barrier_destroy()"); return PTS_UNRESOLVED; } if((shm_unlink(shm_name)) != 0) { perror("Error at shm_unlink()"); return PTS_UNRESOLVED; } printf("Test PASSED\n"); return PTS_PASS; } if(pid == 0) { exit(serial); } return PTS_UNRESOLVED; }