1f40f3adcSEnji Cooper /* $NetBSD: t_sem.c,v 1.3 2017/01/14 20:58:20 christos Exp $ */ 257718be8SEnji Cooper 357718be8SEnji Cooper /* 457718be8SEnji Cooper * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. 557718be8SEnji Cooper * All rights reserved. 657718be8SEnji Cooper * 757718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 857718be8SEnji Cooper * modification, are permitted provided that the following conditions 957718be8SEnji Cooper * are met: 1057718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 1157718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 1257718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1357718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 1457718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 1557718be8SEnji Cooper * 1657718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1757718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1857718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1957718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2057718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2157718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2257718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2357718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2457718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2557718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2657718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 2757718be8SEnji Cooper */ 2857718be8SEnji Cooper 2957718be8SEnji Cooper /* 3057718be8SEnji Cooper * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. 3157718be8SEnji Cooper * All rights reserved. 3257718be8SEnji Cooper * 3357718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 3457718be8SEnji Cooper * modification, are permitted provided that the following conditions 3557718be8SEnji Cooper * are met: 3657718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 3757718be8SEnji Cooper * notice(s), this list of conditions and the following disclaimer as 3857718be8SEnji Cooper * the first lines of this file unmodified other than the possible 3957718be8SEnji Cooper * addition of one or more copyright notices. 4057718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 4157718be8SEnji Cooper * notice(s), this list of conditions and the following disclaimer in 4257718be8SEnji Cooper * the documentation and/or other materials provided with the 4357718be8SEnji Cooper * distribution. 4457718be8SEnji Cooper * 4557718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 4657718be8SEnji Cooper * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4757718be8SEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4857718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 4957718be8SEnji Cooper * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 5057718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 5157718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 5257718be8SEnji Cooper * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 5357718be8SEnji Cooper * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 5457718be8SEnji Cooper * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 5557718be8SEnji Cooper * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5657718be8SEnji Cooper */ 5757718be8SEnji Cooper 5857718be8SEnji Cooper #include <sys/cdefs.h> 5957718be8SEnji Cooper __COPYRIGHT("@(#) Copyright (c) 2008, 2010\ 6057718be8SEnji Cooper The NetBSD Foundation, inc. All rights reserved."); 61f40f3adcSEnji Cooper __RCSID("$NetBSD: t_sem.c,v 1.3 2017/01/14 20:58:20 christos Exp $"); 6257718be8SEnji Cooper 6331466594SEric van Gyzen #ifdef __FreeBSD__ 6431466594SEric van Gyzen #include <sys/types.h> 6531466594SEric van Gyzen #include <sys/sysctl.h> 6631466594SEric van Gyzen #endif 6731466594SEric van Gyzen 68b215ceaaSEric van Gyzen #include <sys/time.h> 6957718be8SEnji Cooper #include <sys/wait.h> 7057718be8SEnji Cooper 7157718be8SEnji Cooper #include <errno.h> 7257718be8SEnji Cooper #include <fcntl.h> 7357718be8SEnji Cooper #include <semaphore.h> 74b215ceaaSEric van Gyzen #include <signal.h> 7557718be8SEnji Cooper #include <stdio.h> 76b215ceaaSEric van Gyzen #include <time.h> 7757718be8SEnji Cooper #include <unistd.h> 7857718be8SEnji Cooper 7957718be8SEnji Cooper #include <atf-c.h> 8057718be8SEnji Cooper 8157718be8SEnji Cooper #define NCHILDREN 10 8257718be8SEnji Cooper 83b215ceaaSEric van Gyzen #define SEM_REQUIRE(x) \ 84b215ceaaSEric van Gyzen ATF_REQUIRE_EQ_MSG(x, 0, "%s", strerror(errno)) 85b215ceaaSEric van Gyzen 8631466594SEric van Gyzen #ifdef __FreeBSD__ 8731466594SEric van Gyzen static bool 8831466594SEric van Gyzen machine_is_virtual(void) 8931466594SEric van Gyzen { 9031466594SEric van Gyzen char vm_guest[32]; 9131466594SEric van Gyzen int error; 9231466594SEric van Gyzen 9331466594SEric van Gyzen error = sysctlbyname("kern.vm_guest", vm_guest, 9431466594SEric van Gyzen &(size_t){sizeof(vm_guest)}, NULL, 0); 9531466594SEric van Gyzen ATF_CHECK_EQ_MSG(0, error, "sysctlbyname(kern.vm_guest): %s", 9631466594SEric van Gyzen strerror(errno)); 9731466594SEric van Gyzen if (error != 0) { 9831466594SEric van Gyzen return (false); 9931466594SEric van Gyzen } 10031466594SEric van Gyzen return (strcmp(vm_guest, "none") != 0); 10131466594SEric van Gyzen } 10231466594SEric van Gyzen #endif 10331466594SEric van Gyzen 104c8300756SEnji Cooper ATF_TC_WITH_CLEANUP(basic); 10557718be8SEnji Cooper ATF_TC_HEAD(basic, tc) 10657718be8SEnji Cooper { 10757718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Checks basic functionality of POSIX " 10857718be8SEnji Cooper "semaphores"); 10957718be8SEnji Cooper } 11057718be8SEnji Cooper ATF_TC_BODY(basic, tc) 11157718be8SEnji Cooper { 11257718be8SEnji Cooper int val; 11357718be8SEnji Cooper sem_t *sem_b; 11457718be8SEnji Cooper 11557718be8SEnji Cooper if (sysconf(_SC_SEMAPHORES) == -1) 11657718be8SEnji Cooper atf_tc_skip("POSIX semaphores not supported"); 11757718be8SEnji Cooper 11857718be8SEnji Cooper sem_b = sem_open("/sem_b", O_CREAT | O_EXCL, 0644, 0); 11957718be8SEnji Cooper ATF_REQUIRE(sem_b != SEM_FAILED); 12057718be8SEnji Cooper 12157718be8SEnji Cooper ATF_REQUIRE_EQ(sem_getvalue(sem_b, &val), 0); 12257718be8SEnji Cooper ATF_REQUIRE_EQ(val, 0); 12357718be8SEnji Cooper 12457718be8SEnji Cooper ATF_REQUIRE_EQ(sem_post(sem_b), 0); 12557718be8SEnji Cooper ATF_REQUIRE_EQ(sem_getvalue(sem_b, &val), 0); 12657718be8SEnji Cooper ATF_REQUIRE_EQ(val, 1); 12757718be8SEnji Cooper 12857718be8SEnji Cooper ATF_REQUIRE_EQ(sem_wait(sem_b), 0); 12957718be8SEnji Cooper ATF_REQUIRE_EQ(sem_trywait(sem_b), -1); 13057718be8SEnji Cooper ATF_REQUIRE_EQ(errno, EAGAIN); 13157718be8SEnji Cooper ATF_REQUIRE_EQ(sem_post(sem_b), 0); 13257718be8SEnji Cooper ATF_REQUIRE_EQ(sem_trywait(sem_b), 0); 13357718be8SEnji Cooper ATF_REQUIRE_EQ(sem_post(sem_b), 0); 13457718be8SEnji Cooper ATF_REQUIRE_EQ(sem_wait(sem_b), 0); 13557718be8SEnji Cooper ATF_REQUIRE_EQ(sem_post(sem_b), 0); 13657718be8SEnji Cooper 13757718be8SEnji Cooper ATF_REQUIRE_EQ(sem_close(sem_b), 0); 13857718be8SEnji Cooper ATF_REQUIRE_EQ(sem_unlink("/sem_b"), 0); 13957718be8SEnji Cooper } 140c8300756SEnji Cooper ATF_TC_CLEANUP(basic, tc) 141c8300756SEnji Cooper { 142c8300756SEnji Cooper (void)sem_unlink("/sem_b"); 143c8300756SEnji Cooper } 14457718be8SEnji Cooper 145c8300756SEnji Cooper ATF_TC_WITH_CLEANUP(child); 14657718be8SEnji Cooper ATF_TC_HEAD(child, tc) 14757718be8SEnji Cooper { 14857718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Checks using semaphores to synchronize " 14957718be8SEnji Cooper "parent with multiple child processes"); 150b215ceaaSEric van Gyzen atf_tc_set_md_var(tc, "timeout", "5"); 15157718be8SEnji Cooper } 15257718be8SEnji Cooper ATF_TC_BODY(child, tc) 15357718be8SEnji Cooper { 15457718be8SEnji Cooper pid_t children[NCHILDREN]; 15557718be8SEnji Cooper unsigned i, j; 15657718be8SEnji Cooper sem_t *sem_a; 15757718be8SEnji Cooper int status; 15857718be8SEnji Cooper 15957718be8SEnji Cooper pid_t pid; 16057718be8SEnji Cooper 16157718be8SEnji Cooper if (sysconf(_SC_SEMAPHORES) == -1) 16257718be8SEnji Cooper atf_tc_skip("POSIX semaphores not supported"); 16357718be8SEnji Cooper 16457718be8SEnji Cooper sem_a = sem_open("/sem_a", O_CREAT | O_EXCL, 0644, 0); 16557718be8SEnji Cooper ATF_REQUIRE(sem_a != SEM_FAILED); 16657718be8SEnji Cooper 16757718be8SEnji Cooper for (j = 1; j <= 2; j++) { 16857718be8SEnji Cooper for (i = 0; i < NCHILDREN; i++) { 16957718be8SEnji Cooper switch ((pid = fork())) { 17057718be8SEnji Cooper case -1: 17157718be8SEnji Cooper atf_tc_fail("fork() returned -1"); 17257718be8SEnji Cooper case 0: 17357718be8SEnji Cooper printf("PID %d waiting for semaphore...\n", 17457718be8SEnji Cooper getpid()); 17557718be8SEnji Cooper ATF_REQUIRE_MSG(sem_wait(sem_a) == 0, 17657718be8SEnji Cooper "sem_wait failed; iteration %d", j); 17757718be8SEnji Cooper printf("PID %d got semaphore\n", getpid()); 17857718be8SEnji Cooper _exit(0); 17957718be8SEnji Cooper default: 18057718be8SEnji Cooper children[i] = pid; 18157718be8SEnji Cooper break; 18257718be8SEnji Cooper } 18357718be8SEnji Cooper } 18457718be8SEnji Cooper 18557718be8SEnji Cooper for (i = 0; i < NCHILDREN; i++) { 186b215ceaaSEric van Gyzen usleep(100000); 18757718be8SEnji Cooper printf("main loop %d: posting...\n", j); 18857718be8SEnji Cooper ATF_REQUIRE_EQ(sem_post(sem_a), 0); 18957718be8SEnji Cooper } 19057718be8SEnji Cooper 19157718be8SEnji Cooper for (i = 0; i < NCHILDREN; i++) { 19257718be8SEnji Cooper ATF_REQUIRE_EQ(waitpid(children[i], &status, 0), children[i]); 19357718be8SEnji Cooper ATF_REQUIRE(WIFEXITED(status)); 19457718be8SEnji Cooper ATF_REQUIRE_EQ(WEXITSTATUS(status), 0); 19557718be8SEnji Cooper } 19657718be8SEnji Cooper } 19757718be8SEnji Cooper 19857718be8SEnji Cooper ATF_REQUIRE_EQ(sem_close(sem_a), 0); 19957718be8SEnji Cooper ATF_REQUIRE_EQ(sem_unlink("/sem_a"), 0); 20057718be8SEnji Cooper } 201c8300756SEnji Cooper ATF_TC_CLEANUP(child, tc) 202c8300756SEnji Cooper { 203c8300756SEnji Cooper (void)sem_unlink("/sem_a"); 204c8300756SEnji Cooper } 20557718be8SEnji Cooper 206b215ceaaSEric van Gyzen static inline void 207b215ceaaSEric van Gyzen timespec_add_ms(struct timespec *ts, int ms) 208b215ceaaSEric van Gyzen { 209b215ceaaSEric van Gyzen ts->tv_nsec += ms * 1000*1000; 210b215ceaaSEric van Gyzen if (ts->tv_nsec > 1000*1000*1000) { 211b215ceaaSEric van Gyzen ts->tv_sec++; 212b215ceaaSEric van Gyzen ts->tv_nsec -= 1000*1000*1000; 213b215ceaaSEric van Gyzen } 214b215ceaaSEric van Gyzen } 215b215ceaaSEric van Gyzen 216ac29e8a9SKyle Evans static volatile sig_atomic_t got_sigalrm = 0; 217b215ceaaSEric van Gyzen 218b215ceaaSEric van Gyzen static void 219b215ceaaSEric van Gyzen sigalrm_handler(int sig __unused) 220b215ceaaSEric van Gyzen { 221b215ceaaSEric van Gyzen got_sigalrm = 1; 222b215ceaaSEric van Gyzen } 223b215ceaaSEric van Gyzen 2242334abfdSEric van Gyzen #ifdef __FreeBSD__ 2252334abfdSEric van Gyzen /* This is refactored from the timedwait test case. */ 2262334abfdSEric van Gyzen static void 2272334abfdSEric van Gyzen setup_signals(void) 2282334abfdSEric van Gyzen { 2292334abfdSEric van Gyzen struct sigaction act = { 2302334abfdSEric van Gyzen .sa_handler = sigalrm_handler, 2312334abfdSEric van Gyzen .sa_flags = 0 /* not SA_RESTART */ 2322334abfdSEric van Gyzen }; 2332334abfdSEric van Gyzen 2342334abfdSEric van Gyzen ATF_REQUIRE_MSG(sigemptyset(&act.sa_mask) == 0, 2352334abfdSEric van Gyzen "%s", strerror(errno)); 2362334abfdSEric van Gyzen ATF_REQUIRE_MSG(sigaction(SIGALRM, &act, NULL) == 0, 2372334abfdSEric van Gyzen "%s", strerror(errno)); 2382334abfdSEric van Gyzen } 2392334abfdSEric van Gyzen #endif 2402334abfdSEric van Gyzen 241b215ceaaSEric van Gyzen ATF_TC(timedwait); 242b215ceaaSEric van Gyzen ATF_TC_HEAD(timedwait, tc) 243b215ceaaSEric van Gyzen { 2442334abfdSEric van Gyzen atf_tc_set_md_var(tc, "descr", "Tests sem_timedwait(3)"); 245b215ceaaSEric van Gyzen atf_tc_set_md_var(tc, "timeout", "20"); 246b215ceaaSEric van Gyzen } 247b215ceaaSEric van Gyzen ATF_TC_BODY(timedwait, tc) 248b215ceaaSEric van Gyzen { 249b215ceaaSEric van Gyzen struct timespec ts; 250b215ceaaSEric van Gyzen sem_t sem; 251b215ceaaSEric van Gyzen 252b215ceaaSEric van Gyzen SEM_REQUIRE(sem_init(&sem, 0, 0)); 253b215ceaaSEric van Gyzen SEM_REQUIRE(sem_post(&sem)); 254b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(clock_gettime(CLOCK_REALTIME, &ts) == 0, 255b215ceaaSEric van Gyzen "%s", strerror(errno)); 256b215ceaaSEric van Gyzen timespec_add_ms(&ts, 100); 257b215ceaaSEric van Gyzen SEM_REQUIRE(sem_timedwait(&sem, &ts)); 258b215ceaaSEric van Gyzen ATF_REQUIRE_ERRNO(ETIMEDOUT, sem_timedwait(&sem, &ts)); 259b215ceaaSEric van Gyzen ts.tv_sec--; 260b215ceaaSEric van Gyzen ATF_REQUIRE_ERRNO(ETIMEDOUT, sem_timedwait(&sem, &ts)); 261b215ceaaSEric van Gyzen SEM_REQUIRE(sem_post(&sem)); 262b215ceaaSEric van Gyzen SEM_REQUIRE(sem_timedwait(&sem, &ts)); 263b215ceaaSEric van Gyzen 264b215ceaaSEric van Gyzen /* timespec validation, in the past */ 265b215ceaaSEric van Gyzen ts.tv_nsec += 1000*1000*1000; 266b215ceaaSEric van Gyzen ATF_REQUIRE_ERRNO(EINVAL, sem_timedwait(&sem, &ts)); 267b215ceaaSEric van Gyzen ts.tv_nsec = -1; 268b215ceaaSEric van Gyzen ATF_REQUIRE_ERRNO(EINVAL, sem_timedwait(&sem, &ts)); 269b215ceaaSEric van Gyzen /* timespec validation, in the future */ 270b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(clock_gettime(CLOCK_REALTIME, &ts) == 0, 271b215ceaaSEric van Gyzen "%s", strerror(errno)); 272b215ceaaSEric van Gyzen ts.tv_sec++; 273b215ceaaSEric van Gyzen ts.tv_nsec = 1000*1000*1000; 274b215ceaaSEric van Gyzen ATF_REQUIRE_ERRNO(EINVAL, sem_timedwait(&sem, &ts)); 275b215ceaaSEric van Gyzen ts.tv_nsec = -1; 276b215ceaaSEric van Gyzen ATF_REQUIRE_ERRNO(EINVAL, sem_timedwait(&sem, &ts)); 277b215ceaaSEric van Gyzen 278b215ceaaSEric van Gyzen /* EINTR */ 2792334abfdSEric van Gyzen #ifdef __FreeBSD__ 2802334abfdSEric van Gyzen /* This is refactored into a function. */ 2812334abfdSEric van Gyzen setup_signals(); 2822334abfdSEric van Gyzen #endif 283b215ceaaSEric van Gyzen struct itimerval it = { 284b215ceaaSEric van Gyzen .it_value.tv_usec = 50*1000 285b215ceaaSEric van Gyzen }; 286b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(setitimer(ITIMER_REAL, &it, NULL) == 0, 287b215ceaaSEric van Gyzen "%s", strerror(errno)); 288b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(clock_gettime(CLOCK_REALTIME, &ts) == 0, 289b215ceaaSEric van Gyzen "%s", strerror(errno)); 290b215ceaaSEric van Gyzen timespec_add_ms(&ts, 100); 291b215ceaaSEric van Gyzen ATF_REQUIRE_ERRNO(EINTR, sem_timedwait(&sem, &ts)); 292b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(got_sigalrm, "did not get SIGALRM"); 2932334abfdSEric van Gyzen } 294b215ceaaSEric van Gyzen 295b215ceaaSEric van Gyzen #ifdef __FreeBSD__ 2962334abfdSEric van Gyzen 2972334abfdSEric van Gyzen ATF_TC(clockwait_monotonic_absolute); 2982334abfdSEric van Gyzen ATF_TC_HEAD(clockwait_monotonic_absolute, tc) 2992334abfdSEric van Gyzen { 3002334abfdSEric van Gyzen atf_tc_set_md_var(tc, "descr", 3012334abfdSEric van Gyzen "sem_clockwait_np(3) with monotonic clock and absolute time"); 3022334abfdSEric van Gyzen atf_tc_set_md_var(tc, "timeout", "20"); 3032334abfdSEric van Gyzen } 3042334abfdSEric van Gyzen ATF_TC_BODY(clockwait_monotonic_absolute, tc) 3052334abfdSEric van Gyzen { 3062334abfdSEric van Gyzen struct timespec ts; 3072334abfdSEric van Gyzen sem_t sem; 3082334abfdSEric van Gyzen 3092334abfdSEric van Gyzen SEM_REQUIRE(sem_init(&sem, 0, 0)); 3102334abfdSEric van Gyzen 311b215ceaaSEric van Gyzen SEM_REQUIRE(sem_post(&sem)); 312b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(clock_gettime(CLOCK_MONOTONIC, &ts) == 0, 313b215ceaaSEric van Gyzen "%s", strerror(errno)); 314b215ceaaSEric van Gyzen timespec_add_ms(&ts, 100); 315b215ceaaSEric van Gyzen SEM_REQUIRE(sem_clockwait_np(&sem, CLOCK_MONOTONIC, TIMER_ABSTIME, 316b215ceaaSEric van Gyzen &ts, NULL)); 317b215ceaaSEric van Gyzen ATF_REQUIRE_ERRNO(ETIMEDOUT, 318b215ceaaSEric van Gyzen sem_clockwait_np(&sem, CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL)); 3192334abfdSEric van Gyzen } 320b215ceaaSEric van Gyzen 3212334abfdSEric van Gyzen ATF_TC(clockwait_monotonic_relative); 3222334abfdSEric van Gyzen ATF_TC_HEAD(clockwait_monotonic_relative, tc) 3232334abfdSEric van Gyzen { 3242334abfdSEric van Gyzen atf_tc_set_md_var(tc, "descr", 3252334abfdSEric van Gyzen "sem_clockwait_np(3) with monotonic clock and relative time"); 3262334abfdSEric van Gyzen atf_tc_set_md_var(tc, "timeout", "20"); 3272334abfdSEric van Gyzen } 3282334abfdSEric van Gyzen ATF_TC_BODY(clockwait_monotonic_relative, tc) 3292334abfdSEric van Gyzen { 3302334abfdSEric van Gyzen struct timespec ts; 3312334abfdSEric van Gyzen sem_t sem; 3322334abfdSEric van Gyzen 3332334abfdSEric van Gyzen SEM_REQUIRE(sem_init(&sem, 0, 0)); 3342334abfdSEric van Gyzen 335b215ceaaSEric van Gyzen SEM_REQUIRE(sem_post(&sem)); 336b215ceaaSEric van Gyzen ts.tv_sec = 0; 337b215ceaaSEric van Gyzen ts.tv_nsec = 100*1000*1000; 338b215ceaaSEric van Gyzen SEM_REQUIRE(sem_clockwait_np(&sem, CLOCK_MONOTONIC, 0, 339b215ceaaSEric van Gyzen &ts, NULL)); 340b215ceaaSEric van Gyzen ATF_REQUIRE_ERRNO(ETIMEDOUT, 341b215ceaaSEric van Gyzen sem_clockwait_np(&sem, CLOCK_MONOTONIC, 0, &ts, NULL)); 3422334abfdSEric van Gyzen } 343b215ceaaSEric van Gyzen 3442334abfdSEric van Gyzen ATF_TC(clockwait_absolute_intr_remaining); 3452334abfdSEric van Gyzen ATF_TC_HEAD(clockwait_absolute_intr_remaining, tc) 3462334abfdSEric van Gyzen { 3472334abfdSEric van Gyzen atf_tc_set_md_var(tc, "descr", 3482334abfdSEric van Gyzen "sem_clockwait_np(3) with absolute time does not update " 3492334abfdSEric van Gyzen "remaining time on EINTR"); 3502334abfdSEric van Gyzen atf_tc_set_md_var(tc, "timeout", "20"); 3512334abfdSEric van Gyzen } 3522334abfdSEric van Gyzen ATF_TC_BODY(clockwait_absolute_intr_remaining, tc) 3532334abfdSEric van Gyzen { 3542334abfdSEric van Gyzen struct timespec ts; 3552334abfdSEric van Gyzen sem_t sem; 3562334abfdSEric van Gyzen 3572334abfdSEric van Gyzen SEM_REQUIRE(sem_init(&sem, 0, 0)); 3582334abfdSEric van Gyzen setup_signals(); 3592334abfdSEric van Gyzen 360b215ceaaSEric van Gyzen struct timespec remain = {42, 1000*1000*1000}; 3612334abfdSEric van Gyzen struct itimerval it = { 3622334abfdSEric van Gyzen .it_value.tv_usec = 50*1000 3632334abfdSEric van Gyzen }; 364b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(setitimer(ITIMER_REAL, &it, NULL) == 0, 365b215ceaaSEric van Gyzen "%s", strerror(errno)); 366b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(clock_gettime(CLOCK_MONOTONIC, &ts) == 0, 367b215ceaaSEric van Gyzen "%s", strerror(errno)); 368b215ceaaSEric van Gyzen timespec_add_ms(&ts, 100); 369*35e4527eSEric van Gyzen ATF_REQUIRE_EQ(-1, sem_clockwait_np(&sem, CLOCK_MONOTONIC, 370b215ceaaSEric van Gyzen TIMER_ABSTIME, &ts, &remain)); 371*35e4527eSEric van Gyzen ATF_REQUIRE_ERRNO(EINTR, 1); 372b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(got_sigalrm, "did not get SIGALRM"); 373b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(remain.tv_sec == 42 && remain.tv_nsec == 1000*1000*1000, 374b215ceaaSEric van Gyzen "an absolute clockwait modified the remaining time on EINTR"); 3752334abfdSEric van Gyzen } 376b215ceaaSEric van Gyzen 3772334abfdSEric van Gyzen ATF_TC(clockwait_relative_intr_remaining); 3782334abfdSEric van Gyzen ATF_TC_HEAD(clockwait_relative_intr_remaining, tc) 3792334abfdSEric van Gyzen { 3802334abfdSEric van Gyzen atf_tc_set_md_var(tc, "descr", 3812334abfdSEric van Gyzen "sem_clockwait_np(3) with relative time updates " 3822334abfdSEric van Gyzen "remaining time on EINTR"); 3832334abfdSEric van Gyzen atf_tc_set_md_var(tc, "timeout", "20"); 3842334abfdSEric van Gyzen } 3852334abfdSEric van Gyzen ATF_TC_BODY(clockwait_relative_intr_remaining, tc) 3862334abfdSEric van Gyzen { 3872334abfdSEric van Gyzen struct timespec ts; 3882334abfdSEric van Gyzen sem_t sem; 3892334abfdSEric van Gyzen 3902334abfdSEric van Gyzen SEM_REQUIRE(sem_init(&sem, 0, 0)); 3912334abfdSEric van Gyzen setup_signals(); 3922334abfdSEric van Gyzen 3932334abfdSEric van Gyzen struct timespec remain = {42, 1000*1000*1000}; 3942334abfdSEric van Gyzen struct itimerval it = { 3952334abfdSEric van Gyzen .it_value.tv_usec = 50*1000 3962334abfdSEric van Gyzen }; 397b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(setitimer(ITIMER_REAL, &it, NULL) == 0, 398b215ceaaSEric van Gyzen "%s", strerror(errno)); 399b215ceaaSEric van Gyzen ts.tv_sec = 0; 400b215ceaaSEric van Gyzen ts.tv_nsec = 100*1000*1000; 401*35e4527eSEric van Gyzen ATF_REQUIRE_EQ(-1, sem_clockwait_np(&sem, CLOCK_MONOTONIC, 0, &ts, 402b215ceaaSEric van Gyzen &remain)); 403*35e4527eSEric van Gyzen ATF_REQUIRE_ERRNO(EINTR, 1); 404b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(got_sigalrm, "did not get SIGALRM"); 405b215ceaaSEric van Gyzen ATF_REQUIRE_MSG(remain.tv_sec == 0 && 40631466594SEric van Gyzen (remain.tv_nsec >= 25*1000*1000 || machine_is_virtual()) && 407b215ceaaSEric van Gyzen remain.tv_nsec <= 75*1000*1000, 408b215ceaaSEric van Gyzen "the remaining time was not as expected when a relative clockwait" 40931466594SEric van Gyzen " got EINTR: %ld.%09ld", remain.tv_sec, remain.tv_nsec); 410b215ceaaSEric van Gyzen } 411b215ceaaSEric van Gyzen 4122334abfdSEric van Gyzen #endif /* __FreeBSD__ */ 4132334abfdSEric van Gyzen 41457718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 41557718be8SEnji Cooper { 41657718be8SEnji Cooper 41757718be8SEnji Cooper ATF_TP_ADD_TC(tp, basic); 41857718be8SEnji Cooper ATF_TP_ADD_TC(tp, child); 419b215ceaaSEric van Gyzen ATF_TP_ADD_TC(tp, timedwait); 4202334abfdSEric van Gyzen #ifdef __FreeBSD__ 4212334abfdSEric van Gyzen ATF_TP_ADD_TC(tp, clockwait_monotonic_absolute); 4222334abfdSEric van Gyzen ATF_TP_ADD_TC(tp, clockwait_monotonic_relative); 4232334abfdSEric van Gyzen ATF_TP_ADD_TC(tp, clockwait_absolute_intr_remaining); 4242334abfdSEric van Gyzen ATF_TP_ADD_TC(tp, clockwait_relative_intr_remaining); 4252334abfdSEric van Gyzen #endif 42657718be8SEnji Cooper 42757718be8SEnji Cooper return atf_no_error(); 42857718be8SEnji Cooper } 429