1*03831d35Sstevel /* 2*03831d35Sstevel * CDDL HEADER START 3*03831d35Sstevel * 4*03831d35Sstevel * The contents of this file are subject to the terms of the 5*03831d35Sstevel * Common Development and Distribution License, Version 1.0 only 6*03831d35Sstevel * (the "License"). You may not use this file except in compliance 7*03831d35Sstevel * with the License. 8*03831d35Sstevel * 9*03831d35Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*03831d35Sstevel * or http://www.opensolaris.org/os/licensing. 11*03831d35Sstevel * See the License for the specific language governing permissions 12*03831d35Sstevel * and limitations under the License. 13*03831d35Sstevel * 14*03831d35Sstevel * When distributing Covered Code, include this CDDL HEADER in each 15*03831d35Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*03831d35Sstevel * If applicable, add the following below this CDDL HEADER, with the 17*03831d35Sstevel * fields enclosed by brackets "[]" replaced with your own identifying 18*03831d35Sstevel * information: Portions Copyright [yyyy] [name of copyright owner] 19*03831d35Sstevel * 20*03831d35Sstevel * CDDL HEADER END 21*03831d35Sstevel */ 22*03831d35Sstevel /* 23*03831d35Sstevel * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 24*03831d35Sstevel * Use is subject to license terms. 25*03831d35Sstevel */ 26*03831d35Sstevel 27*03831d35Sstevel #pragma ident "%Z%%M% %I% %E% SMI" 28*03831d35Sstevel 29*03831d35Sstevel /* 30*03831d35Sstevel * xsem.c: to provide a semaphore system (used by the smq routines) 31*03831d35Sstevel * 32*03831d35Sstevel * these routines come from the libxposix library. 33*03831d35Sstevel */ 34*03831d35Sstevel 35*03831d35Sstevel #include <pthread.h> 36*03831d35Sstevel #include <time.h> 37*03831d35Sstevel 38*03831d35Sstevel #include "xsem.h" 39*03831d35Sstevel 40*03831d35Sstevel 41*03831d35Sstevel int 42*03831d35Sstevel xsem_init(xsem_t *sem, int pshared, unsigned int value) 43*03831d35Sstevel { 44*03831d35Sstevel if (pshared != 0) 45*03831d35Sstevel return (-1); 46*03831d35Sstevel 47*03831d35Sstevel pthread_mutex_init(&sem->semMutex, NULL); 48*03831d35Sstevel pthread_cond_init(&sem->semCV, NULL); 49*03831d35Sstevel sem->semaphore = value; 50*03831d35Sstevel 51*03831d35Sstevel return (0); 52*03831d35Sstevel } 53*03831d35Sstevel 54*03831d35Sstevel void 55*03831d35Sstevel xsem_destroy(xsem_t *sem) 56*03831d35Sstevel { 57*03831d35Sstevel pthread_mutex_destroy(&sem->semMutex); 58*03831d35Sstevel pthread_cond_destroy(&sem->semCV); 59*03831d35Sstevel sem->semaphore = 0; 60*03831d35Sstevel } 61*03831d35Sstevel 62*03831d35Sstevel int 63*03831d35Sstevel xsem_wait(xsem_t *sem) 64*03831d35Sstevel { 65*03831d35Sstevel pthread_mutex_lock(&sem->semMutex); 66*03831d35Sstevel 67*03831d35Sstevel if (sem->semaphore < 0) { 68*03831d35Sstevel sem->semaphore = 0; 69*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 70*03831d35Sstevel return (XSEM_ERROR); 71*03831d35Sstevel } 72*03831d35Sstevel 73*03831d35Sstevel if (sem->semaphore > 0) { 74*03831d35Sstevel sem->semaphore--; 75*03831d35Sstevel } else { 76*03831d35Sstevel while (sem->semaphore == 0) 77*03831d35Sstevel pthread_cond_wait(&sem->semCV, &sem->semMutex); 78*03831d35Sstevel 79*03831d35Sstevel if (sem->semaphore != 0) { 80*03831d35Sstevel sem->semaphore--; 81*03831d35Sstevel } else { 82*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 83*03831d35Sstevel return (XSEM_ERROR); 84*03831d35Sstevel } 85*03831d35Sstevel } 86*03831d35Sstevel 87*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 88*03831d35Sstevel return (0); 89*03831d35Sstevel } 90*03831d35Sstevel 91*03831d35Sstevel 92*03831d35Sstevel int 93*03831d35Sstevel xsem_trywait(xsem_t *sem) 94*03831d35Sstevel { 95*03831d35Sstevel pthread_mutex_lock(&sem->semMutex); 96*03831d35Sstevel 97*03831d35Sstevel if (sem->semaphore < 0) { 98*03831d35Sstevel sem->semaphore = 0; 99*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 100*03831d35Sstevel return (XSEM_ERROR); 101*03831d35Sstevel } 102*03831d35Sstevel 103*03831d35Sstevel if (sem->semaphore == 0) { 104*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 105*03831d35Sstevel return (XSEM_EBUSY); 106*03831d35Sstevel } else { 107*03831d35Sstevel sem->semaphore--; 108*03831d35Sstevel } 109*03831d35Sstevel 110*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 111*03831d35Sstevel return (0); 112*03831d35Sstevel } 113*03831d35Sstevel 114*03831d35Sstevel 115*03831d35Sstevel int 116*03831d35Sstevel xsem_post(xsem_t *sem) 117*03831d35Sstevel { 118*03831d35Sstevel pthread_mutex_lock(&sem->semMutex); 119*03831d35Sstevel sem->semaphore++; 120*03831d35Sstevel pthread_cond_signal(&sem->semCV); 121*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 122*03831d35Sstevel 123*03831d35Sstevel return (0); 124*03831d35Sstevel } 125*03831d35Sstevel 126*03831d35Sstevel 127*03831d35Sstevel void 128*03831d35Sstevel xsem_getvalue(xsem_t *sem, int *sval) 129*03831d35Sstevel { 130*03831d35Sstevel *sval = sem->semaphore; 131*03831d35Sstevel } 132*03831d35Sstevel 133*03831d35Sstevel 134*03831d35Sstevel 135*03831d35Sstevel int 136*03831d35Sstevel xsem_xwait(xsem_t *sem, int timeout, timestruc_t *mytime) 137*03831d35Sstevel { 138*03831d35Sstevel int status; 139*03831d35Sstevel timestruc_t delay; 140*03831d35Sstevel 141*03831d35Sstevel if (timeout == 0) 142*03831d35Sstevel return (xsem_wait(sem)); 143*03831d35Sstevel else { 144*03831d35Sstevel pthread_mutex_lock(&sem->semMutex); 145*03831d35Sstevel 146*03831d35Sstevel if (sem->semaphore < 0) { 147*03831d35Sstevel sem->semaphore = 0; 148*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 149*03831d35Sstevel return (XSEM_ERROR); 150*03831d35Sstevel } 151*03831d35Sstevel 152*03831d35Sstevel if (sem->semaphore > 0) { 153*03831d35Sstevel sem->semaphore--; 154*03831d35Sstevel } else { 155*03831d35Sstevel status = 0; 156*03831d35Sstevel 157*03831d35Sstevel delay = *mytime; 158*03831d35Sstevel delay.tv_sec = delay.tv_sec + time(NULL); 159*03831d35Sstevel while ((sem->semaphore == 0) && (status == 0)) { 160*03831d35Sstevel status = pthread_cond_timedwait(&sem->semCV, 161*03831d35Sstevel &sem->semMutex, &delay); 162*03831d35Sstevel } 163*03831d35Sstevel 164*03831d35Sstevel /* 165*03831d35Sstevel * Check one more time in case thread didn't have a 166*03831d35Sstevel * chance to check before timeout ??? TBD 167*03831d35Sstevel */ 168*03831d35Sstevel 169*03831d35Sstevel if (status != 0) { 170*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 171*03831d35Sstevel return (XSEM_ETIME); 172*03831d35Sstevel } else if (sem->semaphore != 0) { 173*03831d35Sstevel sem->semaphore--; 174*03831d35Sstevel } else { 175*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 176*03831d35Sstevel return (XSEM_ERROR); 177*03831d35Sstevel } 178*03831d35Sstevel } 179*03831d35Sstevel 180*03831d35Sstevel pthread_mutex_unlock(&sem->semMutex); 181*03831d35Sstevel } 182*03831d35Sstevel 183*03831d35Sstevel return (0); 184*03831d35Sstevel } 185