1*11be35a1SLionel Sambuc /* $NetBSD: t_sem.c,v 1.7 2012/03/09 19:46:37 joerg Exp $ */ 2*11be35a1SLionel Sambuc 3*11be35a1SLionel Sambuc /* 4*11be35a1SLionel Sambuc * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. 5*11be35a1SLionel Sambuc * All rights reserved. 6*11be35a1SLionel Sambuc * 7*11be35a1SLionel Sambuc * Redistribution and use in source and binary forms, with or without 8*11be35a1SLionel Sambuc * modification, are permitted provided that the following conditions 9*11be35a1SLionel Sambuc * are met: 10*11be35a1SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 11*11be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer. 12*11be35a1SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 13*11be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 14*11be35a1SLionel Sambuc * documentation and/or other materials provided with the distribution. 15*11be35a1SLionel Sambuc * 16*11be35a1SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17*11be35a1SLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18*11be35a1SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19*11be35a1SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20*11be35a1SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21*11be35a1SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22*11be35a1SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23*11be35a1SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24*11be35a1SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25*11be35a1SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26*11be35a1SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE. 27*11be35a1SLionel Sambuc */ 28*11be35a1SLionel Sambuc 29*11be35a1SLionel Sambuc /*- 30*11be35a1SLionel Sambuc * Copyright (c)2004 YAMAMOTO Takashi, 31*11be35a1SLionel Sambuc * All rights reserved. 32*11be35a1SLionel Sambuc * 33*11be35a1SLionel Sambuc * Redistribution and use in source and binary forms, with or without 34*11be35a1SLionel Sambuc * modification, are permitted provided that the following conditions 35*11be35a1SLionel Sambuc * are met: 36*11be35a1SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 37*11be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer. 38*11be35a1SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 39*11be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 40*11be35a1SLionel Sambuc * documentation and/or other materials provided with the distribution. 41*11be35a1SLionel Sambuc * 42*11be35a1SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 43*11be35a1SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44*11be35a1SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 45*11be35a1SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 46*11be35a1SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 47*11be35a1SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 48*11be35a1SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49*11be35a1SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50*11be35a1SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 51*11be35a1SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52*11be35a1SLionel Sambuc * SUCH DAMAGE. 53*11be35a1SLionel Sambuc */ 54*11be35a1SLionel Sambuc 55*11be35a1SLionel Sambuc /**************************************************************************** 56*11be35a1SLionel Sambuc * 57*11be35a1SLionel Sambuc * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. 58*11be35a1SLionel Sambuc * All rights reserved. 59*11be35a1SLionel Sambuc * 60*11be35a1SLionel Sambuc * Redistribution and use in source and binary forms, with or without 61*11be35a1SLionel Sambuc * modification, are permitted provided that the following conditions 62*11be35a1SLionel Sambuc * are met: 63*11be35a1SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 64*11be35a1SLionel Sambuc * notice(s), this list of conditions and the following disclaimer as 65*11be35a1SLionel Sambuc * the first lines of this file unmodified other than the possible 66*11be35a1SLionel Sambuc * addition of one or more copyright notices. 67*11be35a1SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 68*11be35a1SLionel Sambuc * notice(s), this list of conditions and the following disclaimer in 69*11be35a1SLionel Sambuc * the documentation and/or other materials provided with the 70*11be35a1SLionel Sambuc * distribution. 71*11be35a1SLionel Sambuc * 72*11be35a1SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 73*11be35a1SLionel Sambuc * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 74*11be35a1SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 75*11be35a1SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 76*11be35a1SLionel Sambuc * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 77*11be35a1SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 78*11be35a1SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 79*11be35a1SLionel Sambuc * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 80*11be35a1SLionel Sambuc * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 81*11be35a1SLionel Sambuc * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 82*11be35a1SLionel Sambuc * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 83*11be35a1SLionel Sambuc * 84*11be35a1SLionel Sambuc ****************************************************************************/ 85*11be35a1SLionel Sambuc 86*11be35a1SLionel Sambuc #include <sys/cdefs.h> 87*11be35a1SLionel Sambuc __COPYRIGHT("@(#) Copyright (c) 2008, 2010\ 88*11be35a1SLionel Sambuc The NetBSD Foundation, inc. All rights reserved."); 89*11be35a1SLionel Sambuc __RCSID("$NetBSD: t_sem.c,v 1.7 2012/03/09 19:46:37 joerg Exp $"); 90*11be35a1SLionel Sambuc 91*11be35a1SLionel Sambuc #include <errno.h> 92*11be35a1SLionel Sambuc #include <fcntl.h> 93*11be35a1SLionel Sambuc #include <pthread.h> 94*11be35a1SLionel Sambuc #include <semaphore.h> 95*11be35a1SLionel Sambuc #include <signal.h> 96*11be35a1SLionel Sambuc #include <stdio.h> 97*11be35a1SLionel Sambuc #include <stdlib.h> 98*11be35a1SLionel Sambuc #include <string.h> 99*11be35a1SLionel Sambuc #include <unistd.h> 100*11be35a1SLionel Sambuc 101*11be35a1SLionel Sambuc #include <atf-c.h> 102*11be35a1SLionel Sambuc #include <atf-c/config.h> 103*11be35a1SLionel Sambuc 104*11be35a1SLionel Sambuc #include "h_common.h" 105*11be35a1SLionel Sambuc 106*11be35a1SLionel Sambuc #define NTHREADS 10 107*11be35a1SLionel Sambuc 108*11be35a1SLionel Sambuc #define _LIBC_R_ 109*11be35a1SLionel Sambuc 110*11be35a1SLionel Sambuc #define SEM_REQUIRE(x) \ 111*11be35a1SLionel Sambuc ATF_REQUIRE_EQ_MSG(x, 0, "%s", strerror(errno)) 112*11be35a1SLionel Sambuc 113*11be35a1SLionel Sambuc static sem_t sem; 114*11be35a1SLionel Sambuc 115*11be35a1SLionel Sambuc ATF_TC(named); 116*11be35a1SLionel Sambuc ATF_TC_HEAD(named, tc) 117*11be35a1SLionel Sambuc { 118*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Checks named semaphores"); 119*11be35a1SLionel Sambuc } 120*11be35a1SLionel Sambuc ATF_TC_BODY(named, tc) 121*11be35a1SLionel Sambuc { 122*11be35a1SLionel Sambuc sem_t *semp; 123*11be35a1SLionel Sambuc 124*11be35a1SLionel Sambuc ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno)); 125*11be35a1SLionel Sambuc 126*11be35a1SLionel Sambuc printf("Test begin\n"); 127*11be35a1SLionel Sambuc 128*11be35a1SLionel Sambuc (void) sem_unlink("/foo"); 129*11be35a1SLionel Sambuc semp = sem_open("/foo", O_CREAT | O_EXCL, 0644, 0); 130*11be35a1SLionel Sambuc ATF_REQUIRE_MSG(semp != SEM_FAILED, "%s", strerror(errno)); 131*11be35a1SLionel Sambuc SEM_REQUIRE(sem_close(semp)); 132*11be35a1SLionel Sambuc SEM_REQUIRE(sem_unlink("/foo")); 133*11be35a1SLionel Sambuc 134*11be35a1SLionel Sambuc printf("Test end\n"); 135*11be35a1SLionel Sambuc } 136*11be35a1SLionel Sambuc 137*11be35a1SLionel Sambuc ATF_TC(unnamed); 138*11be35a1SLionel Sambuc ATF_TC_HEAD(unnamed, tc) 139*11be35a1SLionel Sambuc { 140*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Checks unnamed semaphores"); 141*11be35a1SLionel Sambuc } 142*11be35a1SLionel Sambuc 143*11be35a1SLionel Sambuc static void * 144*11be35a1SLionel Sambuc entry(void * a_arg) 145*11be35a1SLionel Sambuc { 146*11be35a1SLionel Sambuc pthread_t self = pthread_self(); 147*11be35a1SLionel Sambuc sem_t *semp = (sem_t *) a_arg; 148*11be35a1SLionel Sambuc 149*11be35a1SLionel Sambuc printf("Thread %p waiting for semaphore...\n", self); 150*11be35a1SLionel Sambuc sem_wait(semp); 151*11be35a1SLionel Sambuc printf("Thread %p got semaphore\n", self); 152*11be35a1SLionel Sambuc 153*11be35a1SLionel Sambuc return NULL; 154*11be35a1SLionel Sambuc } 155*11be35a1SLionel Sambuc 156*11be35a1SLionel Sambuc ATF_TC_BODY(unnamed, tc) 157*11be35a1SLionel Sambuc { 158*11be35a1SLionel Sambuc sem_t sem_a, sem_b; 159*11be35a1SLionel Sambuc pthread_t threads[NTHREADS]; 160*11be35a1SLionel Sambuc unsigned i, j; 161*11be35a1SLionel Sambuc int val; 162*11be35a1SLionel Sambuc 163*11be35a1SLionel Sambuc ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno)); 164*11be35a1SLionel Sambuc 165*11be35a1SLionel Sambuc printf("Test begin\n"); 166*11be35a1SLionel Sambuc 167*11be35a1SLionel Sambuc SEM_REQUIRE(sem_init(&sem_b, 0, 0)); 168*11be35a1SLionel Sambuc SEM_REQUIRE(sem_getvalue(&sem_b, &val)); 169*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(0, val); 170*11be35a1SLionel Sambuc 171*11be35a1SLionel Sambuc SEM_REQUIRE(sem_post(&sem_b)); 172*11be35a1SLionel Sambuc SEM_REQUIRE(sem_getvalue(&sem_b, &val)); 173*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(1, val); 174*11be35a1SLionel Sambuc 175*11be35a1SLionel Sambuc SEM_REQUIRE(sem_wait(&sem_b)); 176*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(sem_trywait(&sem_b), -1); 177*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(errno, EAGAIN); 178*11be35a1SLionel Sambuc SEM_REQUIRE(sem_post(&sem_b)); 179*11be35a1SLionel Sambuc SEM_REQUIRE(sem_trywait(&sem_b)); 180*11be35a1SLionel Sambuc SEM_REQUIRE(sem_post(&sem_b)); 181*11be35a1SLionel Sambuc SEM_REQUIRE(sem_wait(&sem_b)); 182*11be35a1SLionel Sambuc SEM_REQUIRE(sem_post(&sem_b)); 183*11be35a1SLionel Sambuc 184*11be35a1SLionel Sambuc SEM_REQUIRE(sem_destroy(&sem_b)); 185*11be35a1SLionel Sambuc 186*11be35a1SLionel Sambuc SEM_REQUIRE(sem_init(&sem_a, 0, 0)); 187*11be35a1SLionel Sambuc 188*11be35a1SLionel Sambuc for (j = 0; j < 2; j++) { 189*11be35a1SLionel Sambuc for (i = 0; i < NTHREADS; i++) { 190*11be35a1SLionel Sambuc PTHREAD_REQUIRE(pthread_create(&threads[i], NULL, 191*11be35a1SLionel Sambuc entry, (void *) &sem_a)); 192*11be35a1SLionel Sambuc } 193*11be35a1SLionel Sambuc 194*11be35a1SLionel Sambuc for (i = 0; i < NTHREADS; i++) { 195*11be35a1SLionel Sambuc usleep(10000); 196*11be35a1SLionel Sambuc printf("main loop %u: posting...\n", j+1); 197*11be35a1SLionel Sambuc SEM_REQUIRE(sem_post(&sem_a)); 198*11be35a1SLionel Sambuc } 199*11be35a1SLionel Sambuc 200*11be35a1SLionel Sambuc for (i = 0; i < NTHREADS; i++) { 201*11be35a1SLionel Sambuc PTHREAD_REQUIRE(pthread_join(threads[i], NULL)); 202*11be35a1SLionel Sambuc } 203*11be35a1SLionel Sambuc } 204*11be35a1SLionel Sambuc 205*11be35a1SLionel Sambuc SEM_REQUIRE(sem_destroy(&sem_a)); 206*11be35a1SLionel Sambuc 207*11be35a1SLionel Sambuc printf("Test end\n"); 208*11be35a1SLionel Sambuc } 209*11be35a1SLionel Sambuc 210*11be35a1SLionel Sambuc static void 211*11be35a1SLionel Sambuc sighandler(int signo) 212*11be35a1SLionel Sambuc { 213*11be35a1SLionel Sambuc /* printf("signal %d\n", signo); */ 214*11be35a1SLionel Sambuc 215*11be35a1SLionel Sambuc ATF_REQUIRE_EQ_MSG(signo, SIGALRM, "unexpected signal"); 216*11be35a1SLionel Sambuc SEM_REQUIRE(sem_post(&sem)); 217*11be35a1SLionel Sambuc } 218*11be35a1SLionel Sambuc 219*11be35a1SLionel Sambuc static void 220*11be35a1SLionel Sambuc alarm_ms(const int ms) 221*11be35a1SLionel Sambuc { 222*11be35a1SLionel Sambuc struct itimerval timer; 223*11be35a1SLionel Sambuc timer.it_interval.tv_sec = 0; 224*11be35a1SLionel Sambuc timer.it_interval.tv_usec = 0; 225*11be35a1SLionel Sambuc timer.it_value.tv_sec = 0; 226*11be35a1SLionel Sambuc timer.it_value.tv_usec = ms * 1000; 227*11be35a1SLionel Sambuc ATF_REQUIRE(setitimer(ITIMER_REAL, &timer, NULL) == 0); 228*11be35a1SLionel Sambuc } 229*11be35a1SLionel Sambuc 230*11be35a1SLionel Sambuc static void * 231*11be35a1SLionel Sambuc threadfunc(void *arg) 232*11be35a1SLionel Sambuc { 233*11be35a1SLionel Sambuc int i, ret; 234*11be35a1SLionel Sambuc 235*11be35a1SLionel Sambuc printf("Entering loop\n"); 236*11be35a1SLionel Sambuc for (i = 0; i < 500; ) { 237*11be35a1SLionel Sambuc if ((i & 1) != 0) { 238*11be35a1SLionel Sambuc do { 239*11be35a1SLionel Sambuc ret = sem_wait(&sem); 240*11be35a1SLionel Sambuc } while (ret == -1 && errno == EINTR); 241*11be35a1SLionel Sambuc ATF_REQUIRE(ret == 0); 242*11be35a1SLionel Sambuc } else { 243*11be35a1SLionel Sambuc ret = sem_trywait(&sem); 244*11be35a1SLionel Sambuc if (ret == -1) { 245*11be35a1SLionel Sambuc ATF_REQUIRE(errno == EAGAIN); 246*11be35a1SLionel Sambuc continue; 247*11be35a1SLionel Sambuc } 248*11be35a1SLionel Sambuc } 249*11be35a1SLionel Sambuc printf("%s: %d\n", __func__, i); 250*11be35a1SLionel Sambuc alarm_ms(5); 251*11be35a1SLionel Sambuc i++; 252*11be35a1SLionel Sambuc } 253*11be35a1SLionel Sambuc 254*11be35a1SLionel Sambuc return NULL; 255*11be35a1SLionel Sambuc } 256*11be35a1SLionel Sambuc 257*11be35a1SLionel Sambuc static void 258*11be35a1SLionel Sambuc before_start_test(const bool use_pthread) 259*11be35a1SLionel Sambuc { 260*11be35a1SLionel Sambuc pthread_t t; 261*11be35a1SLionel Sambuc 262*11be35a1SLionel Sambuc SEM_REQUIRE(sem_init(&sem, 0, 0)); 263*11be35a1SLionel Sambuc ATF_REQUIRE(SIG_ERR != signal(SIGALRM, sighandler)); 264*11be35a1SLionel Sambuc 265*11be35a1SLionel Sambuc alarm_ms(5); 266*11be35a1SLionel Sambuc 267*11be35a1SLionel Sambuc if (use_pthread) { 268*11be35a1SLionel Sambuc PTHREAD_REQUIRE(pthread_create(&t, NULL, threadfunc, NULL)); 269*11be35a1SLionel Sambuc PTHREAD_REQUIRE(pthread_join(t, NULL)); 270*11be35a1SLionel Sambuc } else { 271*11be35a1SLionel Sambuc threadfunc(NULL); 272*11be35a1SLionel Sambuc } 273*11be35a1SLionel Sambuc } 274*11be35a1SLionel Sambuc 275*11be35a1SLionel Sambuc ATF_TC(before_start_no_threads); 276*11be35a1SLionel Sambuc ATF_TC_HEAD(before_start_no_threads, tc) 277*11be35a1SLionel Sambuc { 278*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Checks using semaphores without any " 279*11be35a1SLionel Sambuc "thread running"); 280*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "timeout", "40"); 281*11be35a1SLionel Sambuc } 282*11be35a1SLionel Sambuc ATF_TC_BODY(before_start_no_threads, tc) 283*11be35a1SLionel Sambuc { 284*11be35a1SLionel Sambuc before_start_test(false); 285*11be35a1SLionel Sambuc } 286*11be35a1SLionel Sambuc 287*11be35a1SLionel Sambuc ATF_TC(before_start_one_thread); 288*11be35a1SLionel Sambuc ATF_TC_HEAD(before_start_one_thread, tc) 289*11be35a1SLionel Sambuc { 290*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Checks using semaphores before " 291*11be35a1SLionel Sambuc "starting one thread"); 292*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "timeout", "40"); 293*11be35a1SLionel Sambuc } 294*11be35a1SLionel Sambuc ATF_TC_BODY(before_start_one_thread, tc) 295*11be35a1SLionel Sambuc { 296*11be35a1SLionel Sambuc before_start_test(true); 297*11be35a1SLionel Sambuc } 298*11be35a1SLionel Sambuc 299*11be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp) 300*11be35a1SLionel Sambuc { 301*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, named); 302*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, unnamed); 303*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, before_start_no_threads); 304*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, before_start_one_thread); 305*11be35a1SLionel Sambuc 306*11be35a1SLionel Sambuc return atf_no_error(); 307*11be35a1SLionel Sambuc } 308