1 |
/* |
2 |
* CDDL HEADER START |
3 |
* |
4 |
* The contents of this file are subject to the terms of the |
5 |
* Common Development and Distribution License, Version 1.0 only |
6 |
* (the "License"). You may not use this file except in compliance |
7 |
* with the License. |
8 |
* |
9 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
10 |
* or http://www.opensolaris.org/os/licensing. |
11 |
* See the License for the specific language governing permissions |
12 |
* and limitations under the License. |
13 |
* |
14 |
* When distributing Covered Code, include this CDDL HEADER in each |
15 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
16 |
* If applicable, add the following below this CDDL HEADER, with the |
17 |
* fields enclosed by brackets "[]" replaced with your own identifying |
18 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
19 |
* |
20 |
* CDDL HEADER END |
21 |
*/ |
22 |
/* |
23 |
* Copyright 2003 Sun Microsystems, Inc. All rights reserved. |
24 |
* Use is subject to license terms. |
25 |
*/ |
26 |
|
27 |
#ifndef _SYNCH_H |
28 |
#define _SYNCH_H |
29 |
|
30 |
#pragma ident "%Z%%M% %I% %E% SMI" |
31 |
|
32 |
/* |
33 |
* synch.h: |
34 |
* definitions needed to use the thread synchronization interface |
35 |
*/ |
36 |
|
37 |
#ifndef _ASM |
38 |
#include <sys/machlock.h> |
39 |
#include <sys/time_impl.h> |
40 |
#include <sys/synch.h> |
41 |
#endif /* _ASM */ |
42 |
|
43 |
#ifdef __cplusplus |
44 |
extern "C" { |
45 |
#endif |
46 |
|
47 |
#ifndef _ASM |
48 |
|
49 |
/* |
50 |
* Semaphores |
51 |
*/ |
52 |
typedef struct _sema { |
53 |
/* this structure must be the same as sem_t in <semaphore.h> */ |
54 |
uint32_t count; /* semaphore count */ |
55 |
uint16_t type; |
56 |
uint16_t magic; |
57 |
upad64_t pad1[3]; /* reserved for a mutex_t */ |
58 |
upad64_t pad2[2]; /* reserved for a cond_t */ |
59 |
} sema_t; |
60 |
|
61 |
/* |
62 |
* POSIX.1c Note: |
63 |
* POSIX.1c requires that <pthread.h> define the structures pthread_mutex_t |
64 |
* and pthread_cond_t. These structures are identical to mutex_t (lwp_mutex_t) |
65 |
* and cond_t (lwp_cond_t) which are defined in <synch.h>. A nested included |
66 |
* of <synch.h> (to allow a "#typedef mutex_t pthread_mutex_t") would pull in |
67 |
* non-posix symbols/constants violating the namespace restrictions. Hence, |
68 |
* pthread_mutex_t/pthread_cond_t have been redefined in <pthread.h> (actually |
69 |
* in <sys/types.h>). Any modifications done to mutex_t/lwp_mutex_t or |
70 |
* cond_t/lwp_cond_t should also be done to pthread_mutex_t/pthread_cond_t. |
71 |
*/ |
72 |
typedef lwp_mutex_t mutex_t; |
73 |
typedef lwp_cond_t cond_t; |
74 |
|
75 |
/* |
76 |
* Readers/writer locks |
77 |
* |
78 |
* NOTE: The layout of this structure should be kept in sync with the layout |
79 |
* of the correponding structure of pthread_rwlock_t in sys/types.h. |
80 |
* Also, there is an identical structure for lwp_rwlock_t in <sys/synch.h>. |
81 |
* Because we have to deal with C++, we cannot redefine this one as that one. |
82 |
*/ |
83 |
typedef struct _rwlock { |
84 |
int32_t readers; /* -1 == writer else # of readers */ |
85 |
uint16_t type; |
86 |
uint16_t magic; |
87 |
mutex_t mutex; /* used to indicate ownership */ |
88 |
cond_t readercv; /* unused */ |
89 |
cond_t writercv; /* unused */ |
90 |
} rwlock_t; |
91 |
|
92 |
#ifdef __STDC__ |
93 |
int _lwp_mutex_lock(lwp_mutex_t *); |
94 |
int _lwp_mutex_unlock(lwp_mutex_t *); |
95 |
int _lwp_mutex_trylock(lwp_mutex_t *); |
96 |
int _lwp_cond_wait(lwp_cond_t *, lwp_mutex_t *); |
97 |
int _lwp_cond_timedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *); |
98 |
int _lwp_cond_reltimedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *); |
99 |
int _lwp_cond_signal(lwp_cond_t *); |
100 |
int _lwp_cond_broadcast(lwp_cond_t *); |
101 |
int _lwp_sema_init(lwp_sema_t *, int); |
102 |
int _lwp_sema_wait(lwp_sema_t *); |
103 |
int _lwp_sema_trywait(lwp_sema_t *); |
104 |
int _lwp_sema_post(lwp_sema_t *); |
105 |
int cond_init(cond_t *, int, void *); |
106 |
int cond_destroy(cond_t *); |
107 |
int cond_wait(cond_t *, mutex_t *); |
108 |
int cond_timedwait(cond_t *, mutex_t *, const timespec_t *); |
109 |
int cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *); |
110 |
int cond_signal(cond_t *); |
111 |
int cond_broadcast(cond_t *); |
112 |
int mutex_init(mutex_t *, int, void *); |
113 |
int mutex_destroy(mutex_t *); |
114 |
int mutex_lock(mutex_t *); |
115 |
int mutex_trylock(mutex_t *); |
116 |
int mutex_unlock(mutex_t *); |
117 |
int rwlock_init(rwlock_t *, int, void *); |
118 |
int rwlock_destroy(rwlock_t *); |
119 |
int rw_rdlock(rwlock_t *); |
120 |
int rw_wrlock(rwlock_t *); |
121 |
int rw_unlock(rwlock_t *); |
122 |
int rw_tryrdlock(rwlock_t *); |
123 |
int rw_trywrlock(rwlock_t *); |
124 |
int sema_init(sema_t *, unsigned int, int, void *); |
125 |
int sema_destroy(sema_t *); |
126 |
int sema_wait(sema_t *); |
127 |
int sema_timedwait(sema_t *, const timespec_t *); |
128 |
int sema_reltimedwait(sema_t *, const timespec_t *); |
129 |
int sema_post(sema_t *); |
130 |
int sema_trywait(sema_t *); |
131 |
|
132 |
#else /* __STDC__ */ |
133 |
|
134 |
int _lwp_mutex_lock(); |
135 |
int _lwp_mutex_unlock(); |
136 |
int _lwp_mutex_trylock(); |
137 |
int _lwp_cond_wait(); |
138 |
int _lwp_cond_timedwait(); |
139 |
int _lwp_cond_reltimedwait(); |
140 |
int _lwp_cond_signal(); |
141 |
int _lwp_cond_broadcast(); |
142 |
int _lwp_sema_init(); |
143 |
int _lwp_sema_wait(); |
144 |
int _lwp_sema_trywait(); |
145 |
int _lwp_sema_post(); |
146 |
int cond_init(); |
147 |
int cond_destroy(); |
148 |
int cond_wait(); |
149 |
int cond_timedwait(); |
150 |
int cond_reltimedwait(); |
151 |
int cond_signal(); |
152 |
int cond_broadcast(); |
153 |
int mutex_init(); |
154 |
int mutex_destroy(); |
155 |
int mutex_lock(); |
156 |
int mutex_trylock(); |
157 |
int mutex_unlock(); |
158 |
int rwlock_init(); |
159 |
int rwlock_destroy(); |
160 |
int rw_rdlock(); |
161 |
int rw_wrlock(); |
162 |
int rw_unlock(); |
163 |
int rw_tryrdlock(); |
164 |
int rw_trywrlock(); |
165 |
int sema_init(); |
166 |
int sema_destroy(); |
167 |
int sema_wait(); |
168 |
int sema_timedwait(); |
169 |
int sema_reltimedwait(); |
170 |
int sema_post(); |
171 |
int sema_trywait(); |
172 |
|
173 |
#endif /* __STDC__ */ |
174 |
|
175 |
#endif /* _ASM */ |
176 |
|
177 |
/* "Magic numbers" tagging synchronization object types */ |
178 |
#define MUTEX_MAGIC _MUTEX_MAGIC |
179 |
#define SEMA_MAGIC _SEMA_MAGIC |
180 |
#define COND_MAGIC _COND_MAGIC |
181 |
#define RWL_MAGIC _RWL_MAGIC |
182 |
|
183 |
/* |
184 |
* POSIX.1c Note: |
185 |
* DEFAULTMUTEX is defined same as PTHREAD_MUTEX_INITIALIZER in <pthread.h>. |
186 |
* DEFAULTCV is defined same as PTHREAD_COND_INITIALIZER in <pthread.h>. |
187 |
* DEFAULTRWLOCK is defined same as PTHREAD_RWLOCK_INITIALIZER in <pthread.h>. |
188 |
* Any changes to these macros should be reflected in <pthread.h> |
189 |
*/ |
190 |
#define DEFAULTMUTEX \ |
191 |
{{0, 0, 0, {USYNC_THREAD}, MUTEX_MAGIC}, \ |
192 |
{{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} |
193 |
#define SHAREDMUTEX \ |
194 |
{{0, 0, 0, {USYNC_PROCESS}, MUTEX_MAGIC}, \ |
195 |
{{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} |
196 |
#define RECURSIVEMUTEX \ |
197 |
{{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE}, MUTEX_MAGIC}, \ |
198 |
{{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} |
199 |
#define ERRORCHECKMUTEX \ |
200 |
{{0, 0, 0, {USYNC_THREAD|LOCK_ERRORCHECK}, MUTEX_MAGIC}, \ |
201 |
{{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} |
202 |
#define RECURSIVE_ERRORCHECKMUTEX \ |
203 |
{{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE|LOCK_ERRORCHECK}, \ |
204 |
MUTEX_MAGIC}, {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} |
205 |
#define DEFAULTCV \ |
206 |
{{{0, 0, 0, 0}, USYNC_THREAD, COND_MAGIC}, 0} |
207 |
#define SHAREDCV \ |
208 |
{{{0, 0, 0, 0}, USYNC_PROCESS, COND_MAGIC}, 0} |
209 |
#define DEFAULTSEMA \ |
210 |
{0, USYNC_THREAD, SEMA_MAGIC, {0, 0, 0}, {0, 0}} |
211 |
#define SHAREDSEMA \ |
212 |
{0, USYNC_PROCESS, SEMA_MAGIC, {0, 0, 0}, {0, 0}} |
213 |
#define DEFAULTRWLOCK \ |
214 |
{0, USYNC_THREAD, RWL_MAGIC, DEFAULTMUTEX, DEFAULTCV, DEFAULTCV} |
215 |
#define SHAREDRWLOCK \ |
216 |
{0, USYNC_PROCESS, RWL_MAGIC, SHAREDMUTEX, SHAREDCV, SHAREDCV} |
217 |
|
218 |
/* |
219 |
* Tests on lock states. |
220 |
*/ |
221 |
#define SEMA_HELD(x) _sema_held(x) |
222 |
#define RW_READ_HELD(x) _rw_read_held(x) |
223 |
#define RW_WRITE_HELD(x) _rw_write_held(x) |
224 |
#define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x)) |
225 |
#define MUTEX_HELD(x) _mutex_held(x) |
226 |
|
227 |
/* |
228 |
* The following definitions are for assertions which can be checked |
229 |
* statically by tools like lock_lint. You can also define your own |
230 |
* run-time test for each. If you don't, we define them to 1 so that |
231 |
* such assertions simply pass. |
232 |
*/ |
233 |
#ifndef NO_LOCKS_HELD |
234 |
#define NO_LOCKS_HELD 1 |
235 |
#endif |
236 |
#ifndef NO_COMPETING_THREADS |
237 |
#define NO_COMPETING_THREADS 1 |
238 |
#endif |
239 |
|
240 |
#ifndef _ASM |
241 |
|
242 |
#ifdef __STDC__ |
243 |
|
244 |
int _sema_held(sema_t *); |
245 |
int _rw_read_held(rwlock_t *); |
246 |
int _rw_write_held(rwlock_t *); |
247 |
int _mutex_held(mutex_t *); |
248 |
|
249 |
#else /* __STDC__ */ |
250 |
|
251 |
int _sema_held(); |
252 |
int _rw_read_held(); |
253 |
int _rw_write_held(); |
254 |
int _mutex_held(); |
255 |
|
256 |
#endif /* __STDC__ */ |
257 |
|
258 |
#endif /* _ASM */ |
259 |
|
260 |
#ifdef __cplusplus |
261 |
} |
262 |
#endif |
263 |
|
264 |
#endif /* _SYNCH_H */ |