1*3b0a9131SEnji Cooper /* $NetBSD: t_sem.c,v 1.9 2017/01/16 16:22:22 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)2004 YAMAMOTO Takashi, 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, this list of conditions and the following disclaimer. 3857718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 3957718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 4057718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 4157718be8SEnji Cooper * 4257718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 4357718be8SEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4457718be8SEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4557718be8SEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4657718be8SEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4757718be8SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4857718be8SEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4957718be8SEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5057718be8SEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5157718be8SEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5257718be8SEnji Cooper * SUCH DAMAGE. 5357718be8SEnji Cooper */ 5457718be8SEnji Cooper 5557718be8SEnji Cooper /**************************************************************************** 5657718be8SEnji Cooper * 5757718be8SEnji Cooper * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. 5857718be8SEnji Cooper * All rights reserved. 5957718be8SEnji Cooper * 6057718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 6157718be8SEnji Cooper * modification, are permitted provided that the following conditions 6257718be8SEnji Cooper * are met: 6357718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 6457718be8SEnji Cooper * notice(s), this list of conditions and the following disclaimer as 6557718be8SEnji Cooper * the first lines of this file unmodified other than the possible 6657718be8SEnji Cooper * addition of one or more copyright notices. 6757718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 6857718be8SEnji Cooper * notice(s), this list of conditions and the following disclaimer in 6957718be8SEnji Cooper * the documentation and/or other materials provided with the 7057718be8SEnji Cooper * distribution. 7157718be8SEnji Cooper * 7257718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 7357718be8SEnji Cooper * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 7457718be8SEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 7557718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 7657718be8SEnji Cooper * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 7757718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 7857718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 7957718be8SEnji Cooper * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 8057718be8SEnji Cooper * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 8157718be8SEnji Cooper * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 8257718be8SEnji Cooper * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 8357718be8SEnji Cooper * 8457718be8SEnji Cooper ****************************************************************************/ 8557718be8SEnji Cooper 8657718be8SEnji Cooper #include <sys/cdefs.h> 8757718be8SEnji Cooper __COPYRIGHT("@(#) Copyright (c) 2008, 2010\ 8857718be8SEnji Cooper The NetBSD Foundation, inc. All rights reserved."); 89*3b0a9131SEnji Cooper __RCSID("$NetBSD: t_sem.c,v 1.9 2017/01/16 16:22:22 christos Exp $"); 9057718be8SEnji Cooper 91*3b0a9131SEnji Cooper #include <sys/time.h> 9257718be8SEnji Cooper #include <errno.h> 9357718be8SEnji Cooper #include <fcntl.h> 9457718be8SEnji Cooper #include <pthread.h> 9557718be8SEnji Cooper #include <semaphore.h> 9657718be8SEnji Cooper #include <signal.h> 9757718be8SEnji Cooper #include <stdio.h> 9857718be8SEnji Cooper #include <stdlib.h> 9957718be8SEnji Cooper #include <string.h> 10057718be8SEnji Cooper #include <unistd.h> 10157718be8SEnji Cooper 10257718be8SEnji Cooper #include <atf-c.h> 10357718be8SEnji Cooper 10457718be8SEnji Cooper #include "h_common.h" 10557718be8SEnji Cooper 10657718be8SEnji Cooper #define NTHREADS 10 10757718be8SEnji Cooper 10857718be8SEnji Cooper #define _LIBC_R_ 10957718be8SEnji Cooper 11057718be8SEnji Cooper #define SEM_REQUIRE(x) \ 11157718be8SEnji Cooper ATF_REQUIRE_EQ_MSG(x, 0, "%s", strerror(errno)) 11257718be8SEnji Cooper 11357718be8SEnji Cooper static sem_t sem; 11457718be8SEnji Cooper 115a20294deSEnji Cooper #ifdef __FreeBSD__ 116a20294deSEnji Cooper #include <sys/time.h> 117a20294deSEnji Cooper #endif 118a20294deSEnji Cooper 11957718be8SEnji Cooper ATF_TC(named); 12057718be8SEnji Cooper ATF_TC_HEAD(named, tc) 12157718be8SEnji Cooper { 12257718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Checks named semaphores"); 12357718be8SEnji Cooper } 12457718be8SEnji Cooper ATF_TC_BODY(named, tc) 12557718be8SEnji Cooper { 12657718be8SEnji Cooper sem_t *semp; 12757718be8SEnji Cooper 12857718be8SEnji Cooper ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno)); 12957718be8SEnji Cooper 13057718be8SEnji Cooper printf("Test begin\n"); 13157718be8SEnji Cooper 13257718be8SEnji Cooper (void) sem_unlink("/foo"); 13357718be8SEnji Cooper semp = sem_open("/foo", O_CREAT | O_EXCL, 0644, 0); 13457718be8SEnji Cooper ATF_REQUIRE_MSG(semp != SEM_FAILED, "%s", strerror(errno)); 13557718be8SEnji Cooper SEM_REQUIRE(sem_close(semp)); 13657718be8SEnji Cooper SEM_REQUIRE(sem_unlink("/foo")); 13757718be8SEnji Cooper 13857718be8SEnji Cooper printf("Test end\n"); 13957718be8SEnji Cooper } 14057718be8SEnji Cooper 14157718be8SEnji Cooper ATF_TC(unnamed); 14257718be8SEnji Cooper ATF_TC_HEAD(unnamed, tc) 14357718be8SEnji Cooper { 14457718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Checks unnamed semaphores"); 14557718be8SEnji Cooper } 14657718be8SEnji Cooper 14757718be8SEnji Cooper static void * 14857718be8SEnji Cooper entry(void * a_arg) 14957718be8SEnji Cooper { 15057718be8SEnji Cooper pthread_t self = pthread_self(); 15157718be8SEnji Cooper sem_t *semp = (sem_t *) a_arg; 15257718be8SEnji Cooper 15357718be8SEnji Cooper printf("Thread %p waiting for semaphore...\n", self); 15457718be8SEnji Cooper sem_wait(semp); 15557718be8SEnji Cooper printf("Thread %p got semaphore\n", self); 15657718be8SEnji Cooper 15757718be8SEnji Cooper return NULL; 15857718be8SEnji Cooper } 15957718be8SEnji Cooper 16057718be8SEnji Cooper ATF_TC_BODY(unnamed, tc) 16157718be8SEnji Cooper { 16257718be8SEnji Cooper sem_t sem_a, sem_b; 16357718be8SEnji Cooper pthread_t threads[NTHREADS]; 16457718be8SEnji Cooper unsigned i, j; 16557718be8SEnji Cooper int val; 16657718be8SEnji Cooper 16757718be8SEnji Cooper ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno)); 16857718be8SEnji Cooper 16957718be8SEnji Cooper printf("Test begin\n"); 17057718be8SEnji Cooper 17157718be8SEnji Cooper SEM_REQUIRE(sem_init(&sem_b, 0, 0)); 17257718be8SEnji Cooper SEM_REQUIRE(sem_getvalue(&sem_b, &val)); 17357718be8SEnji Cooper ATF_REQUIRE_EQ(0, val); 17457718be8SEnji Cooper 17557718be8SEnji Cooper SEM_REQUIRE(sem_post(&sem_b)); 17657718be8SEnji Cooper SEM_REQUIRE(sem_getvalue(&sem_b, &val)); 17757718be8SEnji Cooper ATF_REQUIRE_EQ(1, val); 17857718be8SEnji Cooper 17957718be8SEnji Cooper SEM_REQUIRE(sem_wait(&sem_b)); 18057718be8SEnji Cooper ATF_REQUIRE_EQ(sem_trywait(&sem_b), -1); 18157718be8SEnji Cooper ATF_REQUIRE_EQ(errno, EAGAIN); 18257718be8SEnji Cooper SEM_REQUIRE(sem_post(&sem_b)); 18357718be8SEnji Cooper SEM_REQUIRE(sem_trywait(&sem_b)); 18457718be8SEnji Cooper SEM_REQUIRE(sem_post(&sem_b)); 18557718be8SEnji Cooper SEM_REQUIRE(sem_wait(&sem_b)); 18657718be8SEnji Cooper SEM_REQUIRE(sem_post(&sem_b)); 18757718be8SEnji Cooper 18857718be8SEnji Cooper SEM_REQUIRE(sem_destroy(&sem_b)); 18957718be8SEnji Cooper 19057718be8SEnji Cooper SEM_REQUIRE(sem_init(&sem_a, 0, 0)); 19157718be8SEnji Cooper 19257718be8SEnji Cooper for (j = 0; j < 2; j++) { 19357718be8SEnji Cooper for (i = 0; i < NTHREADS; i++) { 19457718be8SEnji Cooper PTHREAD_REQUIRE(pthread_create(&threads[i], NULL, 19557718be8SEnji Cooper entry, (void *) &sem_a)); 19657718be8SEnji Cooper } 19757718be8SEnji Cooper 19857718be8SEnji Cooper for (i = 0; i < NTHREADS; i++) { 19957718be8SEnji Cooper usleep(10000); 20057718be8SEnji Cooper printf("main loop %u: posting...\n", j+1); 20157718be8SEnji Cooper SEM_REQUIRE(sem_post(&sem_a)); 20257718be8SEnji Cooper } 20357718be8SEnji Cooper 20457718be8SEnji Cooper for (i = 0; i < NTHREADS; i++) { 20557718be8SEnji Cooper PTHREAD_REQUIRE(pthread_join(threads[i], NULL)); 20657718be8SEnji Cooper } 20757718be8SEnji Cooper } 20857718be8SEnji Cooper 20957718be8SEnji Cooper SEM_REQUIRE(sem_destroy(&sem_a)); 21057718be8SEnji Cooper 21157718be8SEnji Cooper printf("Test end\n"); 21257718be8SEnji Cooper } 21357718be8SEnji Cooper 21457718be8SEnji Cooper static void 21557718be8SEnji Cooper sighandler(int signo) 21657718be8SEnji Cooper { 21757718be8SEnji Cooper /* printf("signal %d\n", signo); */ 21857718be8SEnji Cooper 21957718be8SEnji Cooper ATF_REQUIRE_EQ_MSG(signo, SIGALRM, "unexpected signal"); 22057718be8SEnji Cooper SEM_REQUIRE(sem_post(&sem)); 22157718be8SEnji Cooper } 22257718be8SEnji Cooper 22357718be8SEnji Cooper static void 22457718be8SEnji Cooper alarm_ms(const int ms) 22557718be8SEnji Cooper { 22657718be8SEnji Cooper struct itimerval timer; 22757718be8SEnji Cooper timer.it_interval.tv_sec = 0; 22857718be8SEnji Cooper timer.it_interval.tv_usec = 0; 22957718be8SEnji Cooper timer.it_value.tv_sec = 0; 23057718be8SEnji Cooper timer.it_value.tv_usec = ms * 1000; 23157718be8SEnji Cooper ATF_REQUIRE(setitimer(ITIMER_REAL, &timer, NULL) == 0); 23257718be8SEnji Cooper } 23357718be8SEnji Cooper 23457718be8SEnji Cooper static void * 23557718be8SEnji Cooper threadfunc(void *arg) 23657718be8SEnji Cooper { 23757718be8SEnji Cooper int i, ret; 23857718be8SEnji Cooper 23957718be8SEnji Cooper printf("Entering loop\n"); 24057718be8SEnji Cooper for (i = 0; i < 500; ) { 24157718be8SEnji Cooper if ((i & 1) != 0) { 24257718be8SEnji Cooper do { 24357718be8SEnji Cooper ret = sem_wait(&sem); 24457718be8SEnji Cooper } while (ret == -1 && errno == EINTR); 24557718be8SEnji Cooper ATF_REQUIRE(ret == 0); 24657718be8SEnji Cooper } else { 24757718be8SEnji Cooper ret = sem_trywait(&sem); 24857718be8SEnji Cooper if (ret == -1) { 24957718be8SEnji Cooper ATF_REQUIRE(errno == EAGAIN); 25057718be8SEnji Cooper continue; 25157718be8SEnji Cooper } 25257718be8SEnji Cooper } 25357718be8SEnji Cooper printf("%s: %d\n", __func__, i); 25457718be8SEnji Cooper alarm_ms(5); 25557718be8SEnji Cooper i++; 25657718be8SEnji Cooper } 25757718be8SEnji Cooper 25857718be8SEnji Cooper return NULL; 25957718be8SEnji Cooper } 26057718be8SEnji Cooper 26157718be8SEnji Cooper static void 26257718be8SEnji Cooper before_start_test(const bool use_pthread) 26357718be8SEnji Cooper { 26457718be8SEnji Cooper pthread_t t; 26557718be8SEnji Cooper 26657718be8SEnji Cooper SEM_REQUIRE(sem_init(&sem, 0, 0)); 26757718be8SEnji Cooper ATF_REQUIRE(SIG_ERR != signal(SIGALRM, sighandler)); 26857718be8SEnji Cooper 26957718be8SEnji Cooper alarm_ms(5); 27057718be8SEnji Cooper 27157718be8SEnji Cooper if (use_pthread) { 27257718be8SEnji Cooper PTHREAD_REQUIRE(pthread_create(&t, NULL, threadfunc, NULL)); 27357718be8SEnji Cooper PTHREAD_REQUIRE(pthread_join(t, NULL)); 27457718be8SEnji Cooper } else { 27557718be8SEnji Cooper threadfunc(NULL); 27657718be8SEnji Cooper } 27757718be8SEnji Cooper } 27857718be8SEnji Cooper 27957718be8SEnji Cooper ATF_TC(before_start_no_threads); 28057718be8SEnji Cooper ATF_TC_HEAD(before_start_no_threads, tc) 28157718be8SEnji Cooper { 28257718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Checks using semaphores without any " 28357718be8SEnji Cooper "thread running"); 28457718be8SEnji Cooper atf_tc_set_md_var(tc, "timeout", "40"); 28557718be8SEnji Cooper } 28657718be8SEnji Cooper ATF_TC_BODY(before_start_no_threads, tc) 28757718be8SEnji Cooper { 28857718be8SEnji Cooper before_start_test(false); 28957718be8SEnji Cooper } 29057718be8SEnji Cooper 29157718be8SEnji Cooper ATF_TC(before_start_one_thread); 29257718be8SEnji Cooper ATF_TC_HEAD(before_start_one_thread, tc) 29357718be8SEnji Cooper { 29457718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "Checks using semaphores before " 29557718be8SEnji Cooper "starting one thread"); 29657718be8SEnji Cooper atf_tc_set_md_var(tc, "timeout", "40"); 29757718be8SEnji Cooper } 29857718be8SEnji Cooper ATF_TC_BODY(before_start_one_thread, tc) 29957718be8SEnji Cooper { 30057718be8SEnji Cooper before_start_test(true); 30157718be8SEnji Cooper } 30257718be8SEnji Cooper 30357718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 30457718be8SEnji Cooper { 30557718be8SEnji Cooper ATF_TP_ADD_TC(tp, named); 30657718be8SEnji Cooper ATF_TP_ADD_TC(tp, unnamed); 30757718be8SEnji Cooper ATF_TP_ADD_TC(tp, before_start_no_threads); 30857718be8SEnji Cooper ATF_TP_ADD_TC(tp, before_start_one_thread); 30957718be8SEnji Cooper 31057718be8SEnji Cooper return atf_no_error(); 31157718be8SEnji Cooper } 312