int main() { int rc; pthread_barrierattr_t ba; pthread_barrier_t barriers [BARRIER_NUM]; int cnt; /* 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; } /* Initialize BARRIER_NUM barrier objects, with count==1 */ for(cnt = 0; cnt < BARRIER_NUM; cnt++) { if(pthread_barrier_init(&barriers[cnt], &ba, 1) != 0) { printf("Error at %dth initialization\n", cnt); return PTS_UNRESOLVED; } } /* Destroy barrier attribute object */ rc = pthread_barrierattr_destroy(&ba); if(rc != 0) { printf("Error at pthread_barrierattr_destroy() " "return code: %d, %s", rc, strerror(rc)); return PTS_UNRESOLVED; } /* Check that pthread_barrier_wait can still be performed, even after the attributes * object has been destroyed */ for(cnt = 0; cnt < BARRIER_NUM; cnt++) { rc = pthread_barrier_wait(&barriers[cnt]); if(rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { printf("Test Fail: Error at %dth wait, %s\n", cnt, strerror(rc)); return PTS_FAIL; } } /* Cleanup */ for(cnt = 0; cnt < BARRIER_NUM; cnt++) { rc = pthread_barrier_destroy(&barriers[cnt]); if(rc != 0) { printf("Error at %dth destruction, %s\n", cnt, strerror(rc)); return PTS_UNRESOLVED; } } printf("Test PASSED\n"); return PTS_PASS; }
int pthread_test_barrier3() { pthread_t t; pthread_barrierattr_t ba; assert(pthread_barrierattr_init(&ba) == 0); assert(pthread_barrierattr_setpshared(&ba, PTHREAD_PROCESS_PRIVATE) == 0); assert(pthread_barrier_init(&barrier, &ba, 1) == 0); assert(pthread_create(&t, NULL, func, NULL) == 0); assert(pthread_join(t, (void **) &result) == 0); assert(result == PTHREAD_BARRIER_SERIAL_THREAD); assert(pthread_barrier_destroy(&barrier) == 0); assert(pthread_barrierattr_destroy(&ba) == 0); return 0; }
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 do_test (void) { char tmpfname[] = "/tmp/tst-mqueue3-barrier.XXXXXX"; int 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. */ size_t ps = sysconf (_SC_PAGESIZE); char data[ps]; memset (data, '\0', ps); /* Write the data to the file. */ if (write (fd, data, ps) != (ssize_t) ps) { puts ("short write"); return 1; } void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { printf ("mmap failed: %m\n"); return 1; } pthread_barrier_t *b; b = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t)) & ~(__alignof (pthread_barrier_t) - 1)); pthread_barrierattr_t a; if (pthread_barrierattr_init (&a) != 0) { puts ("barrierattr_init failed"); return 1; } if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed, could not test"); return 0; } 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; } /* Name for the message queue. */ char mqname[sizeof ("/tst-mqueue3-") + 3 * sizeof (pid_t)]; snprintf (mqname, sizeof (mqname) - 1, "/tst-mqueue3-%ld", (long int) getpid ()); /* Create the message queue. */ struct mq_attr attr = { .mq_maxmsg = MAXMSG, .mq_msgsize = MSGSIZE }; m = mq_open (mqname, O_CREAT | O_EXCL | O_RDWR, 0600, &attr); if (m == -1) { if (errno == ENOSYS) { puts ("not implemented"); return 0; } puts ("mq_open failed"); return 1; } /* Unlink the message queue right away. */ if (mq_unlink (mqname) != 0) { puts ("mq_unlink failed"); return 1; } pid = fork (); if (pid == -1) { puts ("fork failed"); return 1; } if (pid == 0) { /* Request notification via thread. */ struct sigevent ev; ev.sigev_notify = SIGEV_THREAD; ev.sigev_notify_function = fct; ev.sigev_value.sival_ptr = NULL; ev.sigev_notify_attributes = NULL; /* Tell the kernel. */ if (mq_notify (m,&ev) != 0) { puts ("mq_notify failed"); exit (1); } /* Tell the parent we are ready. */ (void) pthread_barrier_wait (b); /* Make sure the process goes away eventually. */ alarm (10); /* Do nothing forever. */ while (1) pause (); } /* Wait for the child process to register to notification method. */ (void) pthread_barrier_wait (b); /* Send the message. */ if (mq_send (m, message, sizeof (message), 1) != 0) { kill (pid, SIGKILL); puts ("mq_send failed"); return 1; } int r; if (TEMP_FAILURE_RETRY (waitpid (pid, &r, 0)) != pid) { kill (pid, SIGKILL); puts ("waitpid failed"); return 1; } return WIFEXITED (r) && WEXITSTATUS (r) == UNIQUE ? 0 : 1; }
static int do_test (void) { int result = 0; char tmpfname[] = "/tmp/tst-mqueue5-barrier.XXXXXX"; int 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. */ size_t ps = sysconf (_SC_PAGESIZE); char data[ps]; memset (data, '\0', ps); /* Write the data to the file. */ if (write (fd, data, ps) != (ssize_t) ps) { puts ("short write"); return 1; } void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { printf ("mmap failed: %m\n"); return 1; } pthread_barrier_t *b2; b2 = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t)) & ~(__alignof (pthread_barrier_t) - 1)); pthread_barrier_t *b3; b3 = b2 + 1; pthread_barrierattr_t a; if (pthread_barrierattr_init (&a) != 0) { puts ("barrierattr_init failed"); return 1; } if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed, could not test"); return 0; } if (pthread_barrier_init (b2, &a, 2) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrier_init (b3, &a, 3) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrierattr_destroy (&a) != 0) { puts ("barrierattr_destroy failed"); return 1; } char name[sizeof "/tst-mqueue5-" + sizeof (pid_t) * 3]; snprintf (name, sizeof (name), "/tst-mqueue5-%u", getpid ()); struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = 1 }; mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr); if (q == (mqd_t) -1) { printf ("mq_open failed with: %m\n"); return result; } else add_temp_mq (name); struct sigevent ev; memset (&ev, 0xaa, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q, &ev) != 0) { printf ("mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } if (mq_notify (q, &ev) == 0) { puts ("second mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded"); result = 1; } else if (errno != EBUSY) { printf ("second mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } result |= mqsend (q); if (mq_notify (q, &ev) != 0) { printf ("third mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } result |= mqrecv (q); if (mq_notify (q, NULL) != 0) { printf ("mq_notify (q, NULL) failed with: %m\n"); result = 1; } if (mq_notify (q, NULL) != 0) { /* Implementation-defined behaviour, so don't fail, just inform. */ printf ("second mq_notify (q, NULL) failed with: %m\n"); } struct sigaction sa = { .sa_sigaction = rtmin_handler, .sa_flags = SA_SIGINFO }; sigemptyset (&sa.sa_mask); sigaction (SIGRTMIN, &sa, NULL); memset (&ev, 0x55, sizeof (ev)); ev.sigev_notify = SIGEV_SIGNAL; ev.sigev_signo = SIGRTMIN; ev.sigev_value.sival_int = 26; if (mq_notify (q, &ev) != 0) { printf ("mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } ev.sigev_value.sival_ptr = &ev; if (mq_notify (q, &ev) == 0) { puts ("second mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded"); result = 1; } else if (errno != EBUSY) { printf ("second mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } if (rtmin_cnt != 0) { puts ("SIGRTMIN signal caught too early"); result = 1; } result |= mqsend (q); if (rtmin_cnt != 1) { puts ("SIGRTMIN signal did not arrive"); result = 1; } else if (rtmin_pid != getpid () || rtmin_uid != getuid () || rtmin_code != SI_MESGQ || rtmin_sigval.sival_int != 26) { printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (26)\n", rtmin_pid, getpid (), rtmin_uid, getuid (), rtmin_code, SI_MESGQ, rtmin_sigval.sival_int); result = 1; } ev.sigev_value.sival_int = 75; if (mq_notify (q, &ev) != 0) { printf ("third mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } result |= mqrecv (q); if (mq_notify (q, NULL) != 0) { printf ("mq_notify (q, NULL) failed with: %m\n"); result = 1; } memset (&ev, 0x33, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q, &ev) != 0) { printf ("fourth mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } pid_t pid = fork (); if (pid == -1) { printf ("fork () failed: %m\n"); mq_unlink (name); return 1; } if (pid == 0) do_child (name, b2, b3, q); /* Child unsuccessfully attempts to mq_notify. */ (void) pthread_barrier_wait (b2); result |= mqsend (q); (void) pthread_barrier_wait (b2); /* Child successfully calls mq_notify SIGEV_SIGNAL now. */ result |= mqrecv (q); (void) pthread_barrier_wait (b2); memset (&ev, 0xbb, sizeof (ev)); ev.sigev_notify = SIGEV_SIGNAL; ev.sigev_signo = SIGRTMIN; ev.sigev_value.sival_int = 15; if (mq_notify (q, &ev) == 0) { puts ("fourth mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded"); result = 1; } else if (errno != EBUSY) { printf ("fourth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } result |= mqsend (q); if (mq_notify (q, &ev) != 0) { printf ("fifth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n"); result = 1; } if (rtmin_cnt != 1) { puts ("SIGRTMIN signal caught too early"); result = 1; } result |= mqrecv (q); (void) pthread_barrier_wait (b2); /* Child verifies caught SIGRTMIN signal. */ /* Child calls mq_send (q) which triggers SIGRTMIN signal here. */ (void) pthread_barrier_wait (b2); /* Child mq_open's another mqd_t for the same queue (q2). */ if (rtmin_cnt != 2) { puts ("SIGRTMIN signal did not arrive"); result = 1; } else if (rtmin_pid != pid || rtmin_uid != getuid () || rtmin_code != SI_MESGQ || rtmin_sigval.sival_int != 15) { printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (15)\n", rtmin_pid, pid, rtmin_uid, getuid (), rtmin_code, SI_MESGQ, rtmin_sigval.sival_int); result = 1; } result |= mqrecv (q); (void) pthread_barrier_wait (b2); /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q2. */ (void) pthread_barrier_wait (b2); memset (&ev, 0xbb, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q, &ev) == 0) { puts ("fifth mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded"); result = 1; } else if (errno != EBUSY) { printf ("fifth mq_notify (q, { SIGEV_NONE }) failed with: %m\n"); result = 1; } (void) pthread_barrier_wait (b2); /* Child calls mq_close on q2, which makes the queue available again for notification. */ mqd_t q3 = mq_open (name, O_RDWR); if (q3 == (mqd_t) -1) { printf ("mq_open q3 in parent failed with: %m\n"); result = 1; } (void) pthread_barrier_wait (b2); memset (&ev, 0x12, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q3, &ev) != 0) { printf ("mq_notify (q3, { SIGEV_NONE }) failed with: %m\n"); result = 1; } (void) pthread_barrier_wait (b2); /* Child unsuccessfully attempts to mq_notify { SIGEV_SIGNAL } on q. */ (void) pthread_barrier_wait (b2); if (mq_close (q3) != 0) { printf ("mq_close failed: %m\n"); result = 1; } (void) pthread_barrier_wait (b2); /* Child successfully calls mq_notify { SIGEV_NONE } on q. */ /* Child successfully calls mq_notify NULL on q. */ (void) pthread_barrier_wait (b2); /* Child creates new thread. */ /* Thread blocks on mqrecv (q). */ /* Child sleeps for 1sec so that thread has time to reach that point. */ /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q. */ (void) pthread_barrier_wait (b2); result |= mqsend (q); (void) pthread_barrier_wait (b3); /* Child verifies SIGRTMIN has not been sent. */ (void) pthread_barrier_wait (b3); result |= mqsend (q); (void) pthread_barrier_wait (b3); /* Thread verifies SIGRTMIN has been caught. */ /* Thread calls mq_notify (q, { SIGEV_NONE }) to verify notification is now available for registration. */ /* Thread calls mq_notify (q, NULL). */ (void) pthread_barrier_wait (b3); /* Child calls mq_notify (q, { SIGEV_SIGNAL }). */ (void) pthread_barrier_wait (b3); /* Thread calls mq_notify (q, NULL). */ (void) pthread_barrier_wait (b3); result |= mqsend (q); result |= mqrecv (q); (void) pthread_barrier_wait (b3); /* Child verifies SIGRTMIN has not been sent. */ /* Child calls mq_notify (q, { SIGEV_SIGNAL }). */ (void) pthread_barrier_wait (b3); /* Thread opens a new O_RDONLY mqd_t (q4). */ /* Thread calls mq_notify (q4, NULL). */ /* Thread calls mq_close (q4). */ (void) pthread_barrier_wait (b3); result |= mqsend (q); result |= mqrecv (q); (void) pthread_barrier_wait (b3); /* Child verifies SIGRTMIN has not been sent. */ /* Child calls mq_notify (q, { SIGEV_SIGNAL }). */ (void) pthread_barrier_wait (b3); /* Thread opens a new O_WRONLY mqd_t (q5). */ /* Thread calls mq_notify (q5, NULL). */ /* Thread calls mq_close (q5). */ (void) pthread_barrier_wait (b3); result |= mqsend (q); result |= mqrecv (q); (void) pthread_barrier_wait (b3); /* Child verifies SIGRTMIN has not been sent. */ int status; if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) { puts ("waitpid failed"); kill (pid, SIGKILL); result = 1; } else if (!WIFEXITED (status) || WEXITSTATUS (status)) { printf ("child failed with status %d\n", status); result = 1; } if (mq_unlink (name) != 0) { printf ("mq_unlink failed: %m\n"); result = 1; } if (mq_close (q) != 0) { printf ("mq_close failed: %m\n"); result = 1; } if (mq_notify (q, NULL) == 0) { puts ("mq_notify on closed mqd_t unexpectedly succeeded"); result = 1; } else if (errno != EBADF) { printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n"); result = 1; } memset (&ev, 0x55, sizeof (ev)); ev.sigev_notify = SIGEV_NONE; if (mq_notify (q, &ev) == 0) { puts ("mq_notify on closed mqd_t unexpectedly succeeded"); result = 1; } else if (errno != EBADF) { printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n"); result = 1; } return result; }
//!Destructor ~barrierattr_wrapper() { pthread_barrierattr_destroy(&m_attr); }
static void * tf (void *arg) { if (pthread_mutex_lock (&lock)) { puts ("1st locking of lock failed"); exit (1); } struct flock fl = { .l_type = F_WRLCK, .l_start = 0, .l_whence = SEEK_SET, .l_len = 10 }; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("fourth fcntl failed"); exit (1); } pthread_mutex_unlock (&lock); pthread_mutex_lock (&lock2); return NULL; } static int do_test (void) { fd = create_temp_file("tst-flock2-", NULL); if (fd == -1) { puts ("create_temp_file failed"); return 1; } int i; for (i = 0; i < 20; ++i) write (fd, "foobar xyzzy", 12); pthread_barrier_t *b; #ifdef __EMX__ APIRET arc; arc = DosAllocSharedMem ((PPVOID) &b, NULL, sizeof (pthread_barrier_t), PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_GETTABLE); if (arc) { puts ("DosAllocSharedMem failed"); return 1; } b->hmtx = NULLHANDLE; arc = DosCreateMutexSem (NULL, &b->hmtx, DC_SEM_SHARED, FALSE); if (arc) { puts ("DosCreateMutexSem failed"); return 1; } b->hev = NULLHANDLE; arc = DosCreateEventSem (NULL, &b->hev, DC_SEM_SHARED | DCE_AUTORESET, FALSE); if (arc) { puts ("DosCreateEventSem failed"); return 1; } b->cnt = 0; b->cnt_max = 2; #else b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (b == MAP_FAILED) { puts ("mmap failed"); return 1; } pthread_barrierattr_t ba; if (pthread_barrierattr_init (&ba) != 0) { puts ("barrierattr_init failed"); return 1; } if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed"); return 1; } if (pthread_barrier_init (b, &ba, 2) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrierattr_destroy (&ba) != 0) { puts ("barrierattr_destroy failed"); return 1; } #endif struct flock fl = { .l_type = F_WRLCK, .l_start = 0, .l_whence = SEEK_SET, .l_len = 10 }; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("first fcntl failed"); return 1; } pid_t pid = fork (); if (pid == -1) { puts ("fork failed"); return 1; } if (pid == 0) { #ifdef __EMX__ arc = DosGetSharedMem (b, PAG_READ | PAG_WRITE); if (arc) { puts ("DosGetSharedMem failed"); return 1; } arc = DosOpenMutexSem (NULL, &b->hmtx); if (arc) { puts ("DosOpenMutexSem failed"); return 1; } arc = DosOpenEventSem (NULL, &b->hev); if (arc) { puts ("DosOpenEventSem failed"); return 1; } #endif /* Make sure the child does not stay around indefinitely. */ alarm (10); /* Try to get the lock. */ if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0) { puts ("child: second flock succeeded"); return 1; } } pthread_barrier_wait (b); if (pid != 0) { fl.l_type = F_UNLCK; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("third fcntl failed"); return 1; } } pthread_barrier_wait (b); pthread_t th; if (pid == 0) { if (pthread_mutex_lock (&lock2) != 0) { puts ("1st locking of lock2 failed"); return 1; } if (pthread_create (&th, NULL, tf, NULL) != 0) { puts ("pthread_create failed"); return 1; } /* Let the new thread run. */ sleep (1); if (pthread_mutex_lock (&lock) != 0) { puts ("2nd locking of lock failed"); return 1; } puts ("child locked file"); } pthread_barrier_wait (b); if (pid != 0) { fl.l_type = F_WRLCK; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0) { puts ("fifth fcntl succeeded"); return 1; } puts ("file locked by child"); } pthread_barrier_wait (b); if (pid == 0) { if (pthread_mutex_unlock (&lock2) != 0) { puts ("unlock of lock2 failed"); return 1; } if (pthread_join (th, NULL) != 0) { puts ("join failed"); return 1; } puts ("child's thread terminated"); } pthread_barrier_wait (b); if (pid != 0) { fl.l_type = F_WRLCK; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0) { puts ("fifth fcntl succeeded"); return 1; } puts ("file still locked"); } pthread_barrier_wait (b); if (pid == 0) { _exit (0); } int status; if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) { puts ("waitpid failed"); return 1; } puts ("child terminated"); if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("sixth fcntl failed"); return 1; } return status; }
void barrier_test(void) { pthread_t barrier_thread[CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS]; pthread_addr_t result; pthread_attr_t attr; pthread_barrierattr_t barrierattr; int status; int i; printf("barrier_test: Initializing barrier\n"); status = pthread_barrierattr_init(&barrierattr); if (status != OK) { printf("barrier_test: pthread_barrierattr_init failed, status=%d\n", status); } status = pthread_barrier_init(&barrier, &barrierattr, CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS); if (status != OK) { printf("barrier_test: pthread_barrierattr_init failed, status=%d\n", status); } /* Create the barrier */ (void)pthread_barrierattr_init(&barrierattr); /* Start CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS thread instances */ status = pthread_attr_init(&attr); if (status != OK) { printf("barrier_test: pthread_attr_init failed, status=%d\n", status); } for (i = 0; i < CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS; i++) { status = pthread_create(&barrier_thread[i], &attr, barrier_func, (pthread_addr_t)((uintptr_t)i)); if (status != 0) { printf("barrier_test: Error in thread %d create, status=%d\n", i, status); printf("barrier_test: Test aborted with waiting threads\n"); goto abort_test; } else { printf("barrier_test: Thread %d created\n", i); } } FFLUSH(); /* Wait for all thread instances to complete */ for (i = 0; i < CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS; i++) { status = pthread_join(barrier_thread[i], &result); if (status != 0) { printf("barrier_test: Error in thread %d join, status=%d\n", i, status); } else { printf("barrier_test: Thread %d completed with result=%p\n", i, result); } } /* Destroy the barrier */ abort_test: status = pthread_barrier_destroy(&barrier); if (status != OK) { printf("barrier_test: pthread_barrier_destroy failed, status=%d\n", status); } status = pthread_barrierattr_destroy(&barrierattr); if (status != OK) { printf("barrier_test: pthread_barrierattr_destroy failed, status=%d\n", status); } FFLUSH(); }
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; }
static int do_test (void) { char tmp[] = "/tmp/tst-signal1-XXXXXX"; int fd = mkstemp (tmp); if (fd == -1) { puts ("mkstemp failed"); exit (1); } unlink (tmp); int i; for (i = 0; i < 20; ++i) write (fd, "foobar xyzzy", 12); b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (b == MAP_FAILED) { puts ("mmap failed"); exit (1); } pthread_barrierattr_t ba; if (pthread_barrierattr_init (&ba) != 0) { puts ("barrierattr_init failed"); exit (1); } if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed"); exit (1); } if (pthread_barrier_init (b, &ba, 2) != 0) { puts ("barrier_init failed"); exit (1); } if (pthread_barrierattr_destroy (&ba) != 0) { puts ("barrierattr_destroy failed"); exit (1); } pid_t pid = fork (); if (pid == -1) { puts ("fork failed"); exit (1); } if (pid == 0) receiver (); pthread_barrier_wait (b); /* Wait a bit more. */ struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; nanosleep (&ts, NULL); /* Send the signal. */ puts ("sending the signal now"); kill (pid, SIGINT); /* Wait for the process to terminate. */ int status; if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) { puts ("wrong child reported terminated"); exit (1); } if (!WIFSIGNALED (status)) { puts ("child wasn't signalled"); exit (1); } if (WTERMSIG (status) != SIGINT) { puts ("child not terminated with SIGINT"); exit (1); } return 0; }
static int do_test (void) { size_t ps = sysconf (_SC_PAGESIZE); char tmpfname[] = "/tmp/tst-mutex4.XXXXXX"; char data[ps]; void *mem; int fd; pthread_mutex_t *m; pthread_mutexattr_t a; pid_t pid; char *p; int err; int s; pthread_barrier_t *b; pthread_barrierattr_t ba; 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; } m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t) - 1) & ~(__alignof (pthread_mutex_t) - 1)); b = (pthread_barrier_t *) (((uintptr_t) (m + 1) + __alignof (pthread_barrier_t) - 1) & ~(__alignof (pthread_barrier_t) - 1)); p = (char *) (b + 1); if (pthread_mutexattr_init (&a) != 0) { puts ("mutexattr_init failed"); return 1; } if (pthread_mutexattr_getpshared (&a, &s) != 0) { puts ("1st mutexattr_getpshared failed"); return 1; } if (s != PTHREAD_PROCESS_PRIVATE) { puts ("default pshared value wrong"); return 1; } if (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0) { puts ("mutexattr_setpshared failed"); return 1; } if (pthread_mutexattr_getpshared (&a, &s) != 0) { puts ("2nd mutexattr_getpshared failed"); return 1; } if (s != PTHREAD_PROCESS_SHARED) { puts ("pshared value after setpshared call wrong"); return 1; } #ifdef ENABLE_PI if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0) { puts ("pthread_mutexattr_setprotocol failed"); return 1; } #endif if ((err = pthread_mutex_init (m, &a)) != 0) { #ifdef ENABLE_PI if (err == ENOTSUP) { puts ("PI mutexes unsupported"); return 0; } #endif puts ("mutex_init failed"); return 1; } if (pthread_mutex_lock (m) != 0) { puts ("mutex_lock failed"); return 1; } if (pthread_mutexattr_destroy (&a) != 0) { puts ("mutexattr_destroy failed"); return 1; } if (pthread_barrierattr_init (&ba) != 0) { puts ("barrierattr_init failed"); return 1; } if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed"); return 1; } if (pthread_barrier_init (b, &ba, 2) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrierattr_destroy (&ba) != 0) { puts ("barrierattr_destroy failed"); return 1; } err = pthread_mutex_trylock (m); if (err == 0) { puts ("mutex_trylock succeeded"); return 1; } else if (err != EBUSY) { puts ("mutex_trylock didn't return EBUSY"); return 1; } *p = 0; if (pthread_mutex_unlock (m) != 0) { puts ("parent: 1st mutex_unlock failed"); return 1; } puts ("going to fork now"); pid = fork (); if (pid == -1) { puts ("fork failed"); return 1; } else if (pid == 0) { if (pthread_mutex_lock (m) != 0) { puts ("child: mutex_lock failed"); return 1; } int e = pthread_barrier_wait (b); if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) { puts ("child: barrier_wait failed"); return 1; } if ((*p)++ != 0) { puts ("child: *p != 0"); return 1; } if (pthread_mutex_unlock (m) != 0) { puts ("child: mutex_unlock failed"); return 1; } puts ("child done"); } else { int e = pthread_barrier_wait (b); if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) { puts ("parent: barrier_wait failed"); return 1; } if (pthread_mutex_lock (m) != 0) { puts ("parent: 2nd mutex_lock failed"); return 1; } if (*p != 1) { puts ("*p != 1"); return 1; } if (pthread_mutex_unlock (m) != 0) { puts ("parent: 2nd mutex_unlock failed"); return 1; } if (pthread_mutex_destroy (m) != 0) { puts ("mutex_destroy failed"); return 1; } if (pthread_barrier_destroy (b) != 0) { puts ("barrier_destroy failed"); return 1; } puts ("parent done"); } return 0; }
static void * tf (void *arg) { struct flock fl = { .l_type = F_WRLCK, .l_start = 0, .l_whence = SEEK_SET, .l_len = 10 }; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("fourth fcntl failed"); exit (1); } pthread_mutex_unlock (&lock); pthread_mutex_lock (&lock2); return NULL; } static int do_test (void) { char tmp[] = "/tmp/tst-flock2-XXXXXX"; fd = mkstemp (tmp); if (fd == -1) { puts ("mkstemp failed"); return 1; } unlink (tmp); int i; for (i = 0; i < 20; ++i) write (fd, "foobar xyzzy", 12); pthread_barrier_t *b; b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (b == MAP_FAILED) { puts ("mmap failed"); return 1; } pthread_barrierattr_t ba; if (pthread_barrierattr_init (&ba) != 0) { puts ("barrierattr_init failed"); return 1; } if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0) { puts ("barrierattr_setpshared failed"); return 1; } if (pthread_barrier_init (b, &ba, 2) != 0) { puts ("barrier_init failed"); return 1; } if (pthread_barrierattr_destroy (&ba) != 0) { puts ("barrierattr_destroy failed"); return 1; } struct flock fl = { .l_type = F_WRLCK, .l_start = 0, .l_whence = SEEK_SET, .l_len = 10 }; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("first fcntl failed"); return 1; } pid_t pid = fork (); if (pid == -1) { puts ("fork failed"); return 1; } if (pid == 0) { /* Make sure the child does not stay around indefinitely. */ alarm (10); /* Try to get the lock. */ if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0) { puts ("child: second flock succeeded"); return 1; } } pthread_barrier_wait (b); if (pid != 0) { fl.l_type = F_UNLCK; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("third fcntl failed"); return 1; } } pthread_barrier_wait (b); pthread_t th; if (pid == 0) { if (pthread_mutex_lock (&lock) != 0) { puts ("1st locking of lock failed"); return 1; } if (pthread_mutex_lock (&lock2) != 0) { puts ("1st locking of lock2 failed"); return 1; } if (pthread_create (&th, NULL, tf, NULL) != 0) { puts ("pthread_create failed"); return 1; } if (pthread_mutex_lock (&lock) != 0) { puts ("2nd locking of lock failed"); return 1; } puts ("child locked file"); } pthread_barrier_wait (b); if (pid != 0) { fl.l_type = F_WRLCK; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0) { puts ("fifth fcntl succeeded"); return 1; } puts ("file locked by child"); } pthread_barrier_wait (b); if (pid == 0) { if (pthread_mutex_unlock (&lock2) != 0) { puts ("unlock of lock2 failed"); return 1; } if (pthread_join (th, NULL) != 0) { puts ("join failed"); return 1; } puts ("child's thread terminated"); } pthread_barrier_wait (b); if (pid != 0) { fl.l_type = F_WRLCK; if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0) { puts ("fifth fcntl succeeded"); return 1; } puts ("file still locked"); } pthread_barrier_wait (b); if (pid == 0) { _exit (0); } int status; if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) { puts ("waitpid failed"); return 1; } puts ("child terminated"); if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0) { puts ("sixth fcntl failed"); return 1; } return status; }
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; }