| 1 | /* |
| 2 | * |
| 3 | Copyright 1993, 1998 The Open Group |
| 4 | |
| 5 | Permission to use, copy, modify, distribute, and sell this software and its |
| 6 | documentation for any purpose is hereby granted without fee, provided that |
| 7 | the above copyright notice appear in all copies and that both that |
| 8 | copyright notice and this permission notice appear in supporting |
| 9 | documentation. |
| 10 | |
| 11 | The above copyright notice and this permission notice shall be included in |
| 12 | all copies or substantial portions of the Software. |
| 13 | |
| 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 17 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| 18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 20 | |
| 21 | Except as contained in this notice, the name of The Open Group shall not be |
| 22 | used in advertising or otherwise to promote the sale, use or other dealings |
| 23 | in this Software without prior written authorization from The Open Group. |
| 24 | * * |
| 25 | */ |
| 26 | |
| 27 | #ifndef _XTHREADS_H_ |
| 28 | # define _XTHREADS_H_ |
| 29 | |
| 30 | /* Redefine these to XtMalloc/XtFree or whatever you want before including |
| 31 | * this header file. |
| 32 | */ |
| 33 | # ifndef xmalloc |
| 34 | # define xmalloc malloc |
| 35 | # endif |
| 36 | # ifndef xfree |
| 37 | # define xfree free |
| 38 | # endif |
| 39 | |
| 40 | # ifdef CTHREADS |
| 41 | # include <cthreads.h> |
| 42 | typedef cthread_t xthread_t; |
| 43 | typedef struct condition xcondition_rec; |
| 44 | typedef struct mutex xmutex_rec; |
| 45 | # define xthread_init() cthread_init() |
| 46 | # define xthread_self cthread_self |
| 47 | # define xthread_fork(func,closure) cthread_fork(func,closure) |
| 48 | # define xthread_yield() cthread_yield() |
| 49 | # define xthread_exit(v) cthread_exit(v) |
| 50 | # define xthread_set_name(t,str) cthread_set_name(t,str) |
| 51 | # define xmutex_init(m) mutex_init(m) |
| 52 | # define xmutex_clear(m) mutex_clear(m) |
| 53 | # define xmutex_lock(m) mutex_lock(m) |
| 54 | # define xmutex_unlock(m) mutex_unlock(m) |
| 55 | # define xmutex_set_name(m,str) mutex_set_name(m,str) |
| 56 | # define xcondition_init(cv) condition_init(cv) |
| 57 | # define xcondition_clear(cv) condition_clear(cv) |
| 58 | # define xcondition_wait(cv,m) condition_wait(cv,m) |
| 59 | # define xcondition_signal(cv) condition_signal(cv) |
| 60 | # define xcondition_broadcast(cv) condition_broadcast(cv) |
| 61 | # define xcondition_set_name(cv,str) condition_set_name(cv,str) |
| 62 | # else /* !CTHREADS */ |
| 63 | # if defined(SVR4) |
| 64 | # include <thread.h> |
| 65 | # include <synch.h> |
| 66 | typedef thread_t xthread_t; |
| 67 | typedef thread_key_t xthread_key_t; |
| 68 | typedef cond_t xcondition_rec; |
| 69 | typedef mutex_t xmutex_rec; |
| 70 | # if defined(__UNIXWARE__) |
| 71 | extern xthread_t (*_x11_thr_self)(); |
| 72 | # define xthread_self (_x11_thr_self) |
| 73 | # else |
| 74 | # define xthread_self thr_self |
| 75 | # endif |
| 76 | # define xthread_fork(func,closure) thr_create(NULL,0,func,closure,THR_NEW_LWP|THR_DETACHED,NULL) |
| 77 | # define xthread_yield() thr_yield() |
| 78 | # define xthread_exit(v) thr_exit(v) |
| 79 | # define xthread_key_create(kp,d) thr_keycreate(kp,d) |
| 80 | # ifdef __sun |
| 81 | # define xthread_key_delete(k) 0 |
| 82 | # else |
| 83 | # define xthread_key_delete(k) thr_keydelete(k) |
| 84 | # endif |
| 85 | # define xthread_set_specific(k,v) thr_setspecific(k,v) |
| 86 | # define xthread_get_specific(k,vp) thr_getspecific(k,vp) |
| 87 | # define xmutex_init(m) mutex_init(m,USYNC_THREAD,0) |
| 88 | # define xmutex_clear(m) mutex_destroy(m) |
| 89 | # define xmutex_lock(m) mutex_lock(m) |
| 90 | # define xmutex_unlock(m) mutex_unlock(m) |
| 91 | # define xcondition_init(cv) cond_init(cv,USYNC_THREAD,0) |
| 92 | # define xcondition_clear(cv) cond_destroy(cv) |
| 93 | # define xcondition_wait(cv,m) cond_wait(cv,m) |
| 94 | # define xcondition_signal(cv) cond_signal(cv) |
| 95 | # define xcondition_broadcast(cv) cond_broadcast(cv) |
| 96 | # else /* !SVR4 */ |
| 97 | # ifdef WIN32 |
| 98 | # include <X11/Xwindows.h> |
| 99 | typedef DWORD xthread_t; |
| 100 | typedef DWORD xthread_key_t; |
| 101 | struct _xthread_waiter { |
| 102 | HANDLE sem; |
| 103 | struct _xthread_waiter *next; |
| 104 | }; |
| 105 | typedef struct { |
| 106 | CRITICAL_SECTION cs; |
| 107 | struct _xthread_waiter *waiters; |
| 108 | } xcondition_rec; |
| 109 | typedef CRITICAL_SECTION xmutex_rec; |
| 110 | extern void _Xthread_init(void); |
| 111 | # define xthread_init() _Xthread_init() |
| 112 | # define xthread_self GetCurrentThreadId |
| 113 | # define xthread_fork(func,closure) { \ |
| 114 | DWORD _tmptid; \ |
| 115 | CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, (LPVOID)closure, 0, \ |
| 116 | &_tmptid); \ |
| 117 | } |
| 118 | # define xthread_yield() Sleep(0) |
| 119 | # define xthread_exit(v) ExitThread((DWORD)(v)) |
| 120 | # define xthread_key_create(kp,d) *(kp) = TlsAlloc() |
| 121 | # define xthread_key_delete(k) TlsFree(k) |
| 122 | # define xthread_set_specific(k,v) TlsSetValue(k,v) |
| 123 | # define xthread_get_specific(k,vp) TlsGetValue(k) |
| 124 | # define xmutex_init(m) InitializeCriticalSection(m) |
| 125 | # define xmutex_clear(m) DeleteCriticalSection(m) |
| 126 | # define _XMUTEX_NESTS |
| 127 | # define xmutex_lock(m) EnterCriticalSection(m) |
| 128 | # define xmutex_unlock(m) LeaveCriticalSection(m) |
| 129 | # define xcondition_init(cv) { \ |
| 130 | InitializeCriticalSection(&(cv)->cs); \ |
| 131 | (cv)->waiters = NULL; \ |
| 132 | } |
| 133 | # define xcondition_clear(cv) DeleteCriticalSection(&(cv)->cs) |
| 134 | extern struct _xthread_waiter *_Xthread_waiter(); |
| 135 | # define xcondition_wait(cv,m) { \ |
| 136 | struct _xthread_waiter *_tmpthr = _Xthread_waiter(); \ |
| 137 | EnterCriticalSection(&(cv)->cs); \ |
| 138 | _tmpthr->next = (cv)->waiters; \ |
| 139 | (cv)->waiters = _tmpthr; \ |
| 140 | LeaveCriticalSection(&(cv)->cs); \ |
| 141 | LeaveCriticalSection(m); \ |
| 142 | WaitForSingleObject(_tmpthr->sem, INFINITE); \ |
| 143 | EnterCriticalSection(m); \ |
| 144 | } |
| 145 | # define xcondition_signal(cv) { \ |
| 146 | EnterCriticalSection(&(cv)->cs); \ |
| 147 | if ((cv)->waiters) { \ |
| 148 | ReleaseSemaphore((cv)->waiters->sem, 1, NULL); \ |
| 149 | (cv)->waiters = (cv)->waiters->next; \ |
| 150 | } \ |
| 151 | LeaveCriticalSection(&(cv)->cs); \ |
| 152 | } |
| 153 | # define xcondition_broadcast(cv) { \ |
| 154 | struct _xthread_waiter *_tmpthr; \ |
| 155 | EnterCriticalSection(&(cv)->cs); \ |
| 156 | for (_tmpthr = (cv)->waiters; _tmpthr; _tmpthr = _tmpthr->next) \ |
| 157 | ReleaseSemaphore(_tmpthr->sem, 1, NULL); \ |
| 158 | (cv)->waiters = NULL; \ |
| 159 | LeaveCriticalSection(&(cv)->cs); \ |
| 160 | } |
| 161 | # else /* !WIN32 */ |
| 162 | # ifdef USE_TIS_SUPPORT |
| 163 | /* |
| 164 | * TIS support is intended for thread safe libraries. |
| 165 | * This should not be used for general client programming. |
| 166 | */ |
| 167 | # include <tis.h> |
| 168 | typedef pthread_t xthread_t; |
| 169 | typedef pthread_key_t xthread_key_t; |
| 170 | typedef pthread_cond_t xcondition_rec; |
| 171 | typedef pthread_mutex_t xmutex_rec; |
| 172 | # define xthread_self tis_self |
| 173 | # define xthread_fork(func,closure) { pthread_t _tmpxthr; \ |
| 174 | pthread_create(&_tmpxthr,NULL,func,closure); } |
| 175 | # define xthread_yield() pthread_yield_np() |
| 176 | # define xthread_exit(v) pthread_exit(v) |
| 177 | # define xthread_key_create(kp,d) tis_key_create(kp,d) |
| 178 | # define xthread_key_delete(k) tis_key_delete(k) |
| 179 | # define xthread_set_specific(k,v) tis_setspecific(k,v) |
| 180 | # define xthread_get_specific(k,vp) *(vp) = tis_getspecific(k) |
| 181 | # define XMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER |
| 182 | # define xmutex_init(m) tis_mutex_init(m) |
| 183 | # define xmutex_clear(m) tis_mutex_destroy(m) |
| 184 | # define xmutex_lock(m) tis_mutex_lock(m) |
| 185 | # define xmutex_unlock(m) tis_mutex_unlock(m) |
| 186 | # define xcondition_init(c) tis_cond_init(c) |
| 187 | # define xcondition_clear(c) tis_cond_destroy(c) |
| 188 | # define xcondition_wait(c,m) tis_cond_wait(c,m) |
| 189 | # define xcondition_signal(c) tis_cond_signal(c) |
| 190 | # define xcondition_broadcast(c) tis_cond_broadcast(c) |
| 191 | # else |
| 192 | # ifdef USE_NBSD_THREADLIB |
| 193 | /* |
| 194 | * NetBSD threadlib support is intended for thread safe libraries. |
| 195 | * This should not be used for general client programming. |
| 196 | */ |
| 197 | # include <threadlib.h> |
| 198 | typedef thr_t xthread_t; |
| 199 | typedef thread_key_t xthread_key_t; |
| 200 | typedef cond_t xcondition_rec; |
| 201 | typedef mutex_t xmutex_rec; |
| 202 | # define xthread_self thr_self |
| 203 | # define xthread_fork(func,closure) { thr_t _tmpxthr; \ |
| 204 | /* XXX Create it detached? --thorpej */ \ |
| 205 | thr_create(&_tmpxthr,NULL,func,closure); } |
| 206 | # define xthread_yield() thr_yield() |
| 207 | # define xthread_exit(v) thr_exit(v) |
| 208 | # define xthread_key_create(kp,d) thr_keycreate(kp,d) |
| 209 | # define xthread_key_delete(k) thr_keydelete(k) |
| 210 | # define xthread_set_specific(k,v) thr_setspecific(k,v) |
| 211 | # define xthread_get_specific(k,vp) *(vp) = thr_getspecific(k) |
| 212 | # define XMUTEX_INITIALIZER MUTEX_INITIALIZER |
| 213 | # define xmutex_init(m) mutex_init(m, 0) |
| 214 | # define xmutex_clear(m) mutex_destroy(m) |
| 215 | # define xmutex_lock(m) mutex_lock(m) |
| 216 | # define xmutex_unlock(m) mutex_unlock(m) |
| 217 | # define xcondition_init(c) cond_init(c, 0, 0) |
| 218 | # define xcondition_clear(c) cond_destroy(c) |
| 219 | # define xcondition_wait(c,m) cond_wait(c,m) |
| 220 | # define xcondition_signal(c) cond_signal(c) |
| 221 | # define xcondition_broadcast(c) cond_broadcast(c) |
| 222 | # else |
| 223 | # include <pthread.h> |
| 224 | typedef pthread_t xthread_t; |
| 225 | typedef pthread_key_t xthread_key_t; |
| 226 | typedef pthread_cond_t xcondition_rec; |
| 227 | typedef pthread_mutex_t xmutex_rec; |
| 228 | # define xthread_self pthread_self |
| 229 | # define xthread_yield() pthread_yield() |
| 230 | # define xthread_exit(v) pthread_exit(v) |
| 231 | # define xthread_set_specific(k,v) pthread_setspecific(k,v) |
| 232 | # define xmutex_clear(m) pthread_mutex_destroy(m) |
| 233 | # define xmutex_lock(m) pthread_mutex_lock(m) |
| 234 | # define xmutex_unlock(m) pthread_mutex_unlock(m) |
| 235 | # ifndef XPRE_STANDARD_API |
| 236 | # define xthread_key_create(kp,d) pthread_key_create(kp,d) |
| 237 | # define xthread_key_delete(k) pthread_key_delete(k) |
| 238 | # define xthread_get_specific(k,vp) *(vp) = pthread_getspecific(k) |
| 239 | # define xthread_fork(func,closure) { pthread_t _tmpxthr; \ |
| 240 | pthread_create(&_tmpxthr,NULL,func,closure); } |
| 241 | # define XMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER |
| 242 | # define xmutex_init(m) pthread_mutex_init(m, NULL) |
| 243 | # define xcondition_init(c) pthread_cond_init(c, NULL) |
| 244 | # else /* XPRE_STANDARD_API */ |
| 245 | # define xthread_key_create(kp,d) pthread_keycreate(kp,d) |
| 246 | # define xthread_key_delete(k) 0 |
| 247 | # define xthread_get_specific(k,vp) pthread_getspecific(k,vp) |
| 248 | # define xthread_fork(func,closure) { pthread_t _tmpxthr; \ |
| 249 | pthread_create(&_tmpxthr,pthread_attr_default,func,closure); } |
| 250 | # define xmutex_init(m) pthread_mutex_init(m, pthread_mutexattr_default) |
| 251 | # define xcondition_init(c) pthread_cond_init(c, pthread_condattr_default) |
| 252 | # endif /* XPRE_STANDARD_API */ |
| 253 | # define xcondition_clear(c) pthread_cond_destroy(c) |
| 254 | # define xcondition_wait(c,m) pthread_cond_wait(c,m) |
| 255 | # define xcondition_signal(c) pthread_cond_signal(c) |
| 256 | # define xcondition_broadcast(c) pthread_cond_broadcast(c) |
| 257 | # if defined(_DECTHREADS_) |
| 258 | static xthread_t _X_no_thread_id; |
| 259 | # define xthread_have_id(id) !pthread_equal(id, _X_no_thread_id) |
| 260 | # define xthread_clear_id(id) id = _X_no_thread_id |
| 261 | # define xthread_equal(id1,id2) pthread_equal(id1, id2) |
| 262 | # endif /* _DECTHREADS_ */ |
| 263 | # if defined(__linux__) |
| 264 | # define xthread_have_id(id) !pthread_equal(id, 0) |
| 265 | # define xthread_clear_id(id) id = 0 |
| 266 | # define xthread_equal(id1,id2) pthread_equal(id1, id2) |
| 267 | # endif /* linux */ |
| 268 | # if defined(_CMA_VENDOR_) && defined(_CMA__IBM) && (_CMA_VENDOR_ == _CMA__IBM) |
| 269 | # ifdef DEBUG /* too much of a hack to enable normally */ |
| 270 | /* see also cma__obj_set_name() */ |
| 271 | # define xmutex_set_name(m,str) ((char**)(m)->field1)[5] = (str) |
| 272 | # define xcondition_set_name(cv,str) ((char**)(cv)->field1)[5] = (str) |
| 273 | # endif /* DEBUG */ |
| 274 | # endif /* _CMA_VENDOR_ == _CMA__IBM */ |
| 275 | # endif /* USE_NBSD_THREADLIB */ |
| 276 | # endif /* USE_TIS_SUPPORT */ |
| 277 | # endif /* WIN32 */ |
| 278 | # endif /* SVR4 */ |
| 279 | # endif /* CTHREADS */ |
| 280 | typedef xcondition_rec *xcondition_t; |
| 281 | typedef xmutex_rec *xmutex_t; |
| 282 | # ifndef xcondition_malloc |
| 283 | # define xcondition_malloc() (xcondition_t)xmalloc(sizeof(xcondition_rec)) |
| 284 | # endif |
| 285 | # ifndef xcondition_free |
| 286 | # define xcondition_free(c) xfree((char *)c) |
| 287 | # endif |
| 288 | # ifndef xmutex_malloc |
| 289 | # define xmutex_malloc() (xmutex_t)xmalloc(sizeof(xmutex_rec)) |
| 290 | # endif |
| 291 | # ifndef xmutex_free |
| 292 | # define xmutex_free(m) xfree((char *)m) |
| 293 | # endif |
| 294 | # ifndef xthread_have_id |
| 295 | # define xthread_have_id(id) id |
| 296 | # endif |
| 297 | # ifndef xthread_clear_id |
| 298 | # define xthread_clear_id(id) id = 0 |
| 299 | # endif |
| 300 | # ifndef xthread_equal |
| 301 | # define xthread_equal(id1,id2) ((id1) == (id2)) |
| 302 | # endif |
| 303 | /* aids understood by some debuggers */ |
| 304 | # ifndef xthread_set_name |
| 305 | # define xthread_set_name(t,str) |
| 306 | # endif |
| 307 | # ifndef xmutex_set_name |
| 308 | # define xmutex_set_name(m,str) |
| 309 | # endif |
| 310 | # ifndef xcondition_set_name |
| 311 | # define xcondition_set_name(cv,str) |
| 312 | # endif |
| 313 | |
| 314 | #endif /* _XTHREADS_H_ */ |
| 315 | |