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
xsem_init(xsem_t * sem,int pshared,unsigned int value)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
xsem_destroy(xsem_t * sem)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
xsem_wait(xsem_t * sem)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
xsem_trywait(xsem_t * sem)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
xsem_post(xsem_t * sem)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
xsem_getvalue(xsem_t * sem,int * sval)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
xsem_xwait(xsem_t * sem,int timeout,timestruc_t * mytime)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