ATF_TC_BODY(pthread_join, tc) { pthread_t thread; PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc1, NULL)); PTHREAD_REQUIRE(pthread_join(thread, NULL)); }
ATF_TC_BODY(sleep1, tc) { pthread_t thread; struct itimerval it; struct sigaction act; sigset_t mtsm; printf("Testing sleeps unreasonably far into the future.\n"); act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, NULL); PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL)); /* make sure the signal is delivered to the child thread */ sigemptyset(&mtsm); sigaddset(&mtsm, SIGALRM); PTHREAD_REQUIRE(pthread_sigmask(SIG_BLOCK, &mtsm, 0)); timerclear(&it.it_interval); timerclear(&it.it_value); it.it_value.tv_sec = 1; setitimer(ITIMER_REAL, &it, NULL); PTHREAD_REQUIRE(pthread_join(thread, NULL)); }
ATF_TC_BODY(pthread_detach, tc) { const int state = PTHREAD_CREATE_JOINABLE; pthread_attr_t attr; pthread_t t; int rv; /* * Create a joinable thread. */ PTHREAD_REQUIRE(pthread_attr_init(&attr)); PTHREAD_REQUIRE(pthread_attr_setdetachstate(&attr, state)); PTHREAD_REQUIRE(pthread_create(&t, &attr, func, NULL)); /* * Detach the thread and try to * join it; EINVAL should follow. */ PTHREAD_REQUIRE(pthread_detach(t)); rv = pthread_join(t, NULL); ATF_REQUIRE(rv == EINVAL); #ifdef __FreeBSD__ atf_tc_expect_fail("PR # 191906: fails with EINVAL, not ESRCH"); #endif /* * As usual, ESRCH should follow if * we try to detach an invalid thread. */ rv = pthread_cancel(NULL); ATF_REQUIRE(rv == ESRCH); }
ATF_TC_BODY(fork, tc) { pthread_t p; pid_t fork_pid; parent = getpid(); PTHREAD_REQUIRE(pthread_create(&p, NULL, print_pid, NULL)); fork_pid = fork(); ATF_REQUIRE(fork_pid != -1); if (fork_pid) { int status; PTHREAD_REQUIRE(pthread_join(p, NULL)); ATF_REQUIRE_MSG(thread_survived, "thread did not survive in parent"); waitpid(fork_pid, &status, 0); ATF_REQUIRE_MSG(WIFEXITED(status), "child died wrongly"); ATF_REQUIRE_EQ_MSG(WEXITSTATUS(status), 0, "thread survived in child"); } else { sleep(5); #ifdef __FreeBSD__ _exit(thread_survived ? 1 : 0); #else exit(thread_survived ? 1 : 0); #endif } }
ATF_TC_BODY(swapcontext1, tc) { pthread_t thread; #if defined(__FreeBSD__) && defined(__mips__) /* * MIPS modifies TLS pointer in set_mcontext(), so * swapping contexts obtained from different threads * gives us different pthread_self() return value. */ atf_tc_skip("Platform is not supported."); #endif oself = (void *)&val1; nself = (void *)&val2; printf("Testing if swapcontext() alters pthread_self()\n"); #ifdef __FreeBSD__ ATF_REQUIRE_MSG(getcontext(&nctx) != -1, "getcontext failed: %s", strerror(errno)); #else PTHREAD_REQUIRE(getcontext(&nctx)); #endif PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL)); PTHREAD_REQUIRE(pthread_join(thread, NULL)); }
ATF_TC_BODY(simple, tc) { int i; pthread_t self; mainthread = pthread_self(); ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR); for (i = 0; i < NTHREAD; i++) { PTHREAD_REQUIRE(pthread_create(&th[i].id, NULL, f, &th[i])); } sched_yield(); self = pthread_self(); ATF_REQUIRE_EQ_MSG(self, mainthread, "thread id changed"); for (i = 0; i < NTHREAD; i++) { PTHREAD_REQUIRE(pthread_kill(th[i].id, SIGUSR1)); } for (i = 0; i < NTHREAD; i++) { PTHREAD_REQUIRE(pthread_join(th[i].id, NULL)); } }
static void * once3_threadfunc(void *arg) { PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); pthread_cleanup_push(once3_cleanup, &mutex); PTHREAD_REQUIRE(pthread_once(&once, once3_ofunc)); pthread_cleanup_pop(1); return NULL; }
ATF_TC_BODY(once1, tc) { printf("1: Test 1 of pthread_once()\n"); PTHREAD_REQUIRE(pthread_once(&once, ofunc)); PTHREAD_REQUIRE(pthread_once(&once, ofunc)); printf("1: X has value %d\n",x ); ATF_REQUIRE_EQ(x, 1); }
static void once3_cleanup(void *m) { pthread_mutex_t *mu = m; PTHREAD_REQUIRE(pthread_mutex_unlock(mu)); }
static void * signal_delay_wait_threadfunc(void *arg) { int *shared = (int *) arg; printf("2: Second thread.\n"); printf("2: Locking mutex\n"); PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); printf("2: Got mutex.\n"); printf("Shared value: %d. Changing to 0.\n", *shared); *shared = 0; PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); PTHREAD_REQUIRE(pthread_cond_signal(&cond)); return NULL; }
ATF_TC_BODY(once2, tc) { pthread_t threads[NTHREADS]; int id[NTHREADS]; int i; printf("1: Test 2 of pthread_once()\n"); for (i=0; i < NTHREADS; i++) { id[i] = i; PTHREAD_REQUIRE(pthread_create(&threads[i], NULL, once2_threadfunc, &id[i])); } for (i=0; i < NTHREADS; i++) PTHREAD_REQUIRE(pthread_join(threads[i], NULL)); printf("1: X has value %d\n",x ); ATF_REQUIRE_EQ(x, 2); }
ATF_TC_BODY(once3, tc) { pthread_t thread; struct sigaction act; struct itimerval it; printf("Test 3 of pthread_once() (test versus cancellation)\n"); act.sa_sigaction = handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; sigaction(SIGALRM, &act, NULL); timerclear(&it.it_value); it.it_value.tv_usec = 500000; timerclear(&it.it_interval); setitimer(ITIMER_REAL, &it, NULL); PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); PTHREAD_REQUIRE(pthread_create(&thread, NULL, once3_threadfunc, NULL)); PTHREAD_REQUIRE(pthread_cancel(thread)); PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); PTHREAD_REQUIRE(pthread_join(thread, NULL)); PTHREAD_REQUIRE(pthread_once(&once, ofunc)); /* Cancel timer */ timerclear(&it.it_value); setitimer(ITIMER_REAL, &it, NULL); printf("Test succeeded\n"); }
static void * once2_threadfunc(void *arg) { int num; PTHREAD_REQUIRE(pthread_once(&once, once2_ofunc)); num = *(int *)arg; printf("Thread %d sees x with value %d\n", num, x); ATF_REQUIRE_EQ(x, 2); return NULL; }
/* ARGSUSED0 */ static void * threadfunc(void *arg) { nctx.uc_stack.ss_sp = stack; nctx.uc_stack.ss_size = sizeof(stack); makecontext(&nctx, (void *)*swapfunc, 0); oself = (void *)pthread_self(); printf("before swapcontext self = %p\n", oself); #ifdef __FreeBSD__ ATF_REQUIRE_MSG(swapcontext(&octx, &nctx) != -1, "swapcontext failed: %s", strerror(errno)); #else PTHREAD_REQUIRE(swapcontext(&octx, &nctx)); #endif /* NOTREACHED */ return NULL; }
static void * threadfunc1(void *arg) { pthread_t thread[25]; pthread_t caller; void *val = NULL; uintptr_t i; int rv; pthread_attr_t attr; caller = pthread_self(); #ifdef CHECK_STACK_ALIGNMENT /* * Check alignment of thread stack, if supported. */ ATF_REQUIRE(check_stack_alignment()); #endif /* * The behavior is undefined, but should error * out, if we try to join the calling thread. */ rv = pthread_join(caller, NULL); /* * The specification recommends EDEADLK. */ ATF_REQUIRE(rv != 0); ATF_REQUIRE_EQ(rv, EDEADLK); ATF_REQUIRE(pthread_attr_init(&attr) == 0); for (i = 0; i < __arraycount(thread); i++) { error = true; ATF_REQUIRE(pthread_attr_setstacksize(&attr, STACKSIZE * (i + 1)) == 0); rv = pthread_create(&thread[i], &attr, threadfunc2, (void *)i); ATF_REQUIRE_EQ(rv, 0); /* * Check join and exit condition. */ PTHREAD_REQUIRE(pthread_join(thread[i], &val)); ATF_REQUIRE_EQ(error, false); ATF_REQUIRE(val != NULL); ATF_REQUIRE(val == (void *)(i + 1)); /* * Once the thread has returned, ESRCH should * again follow if we try to join it again. */ rv = pthread_join(thread[i], NULL); ATF_REQUIRE_EQ(rv, ESRCH); /* * Try to detach the exited thread. */ rv = pthread_detach(thread[i]); ATF_REQUIRE(rv != 0); } ATF_REQUIRE(pthread_attr_destroy(&attr) == 0); pthread_exit(NULL); return NULL; }