117ca54c3Smrg/* 217ca54c3Smrg * 317ca54c3SmrgCopyright 1993, 1998 The Open Group 417ca54c3Smrg 517ca54c3SmrgPermission to use, copy, modify, distribute, and sell this software and its 617ca54c3Smrgdocumentation for any purpose is hereby granted without fee, provided that 717ca54c3Smrgthe above copyright notice appear in all copies and that both that 817ca54c3Smrgcopyright notice and this permission notice appear in supporting 917ca54c3Smrgdocumentation. 1017ca54c3Smrg 1117ca54c3SmrgThe above copyright notice and this permission notice shall be included in 1217ca54c3Smrgall copies or substantial portions of the Software. 1317ca54c3Smrg 1417ca54c3SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1517ca54c3SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1617ca54c3SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1717ca54c3SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1817ca54c3SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1917ca54c3SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2017ca54c3Smrg 2117ca54c3SmrgExcept as contained in this notice, the name of The Open Group shall not be 2217ca54c3Smrgused in advertising or otherwise to promote the sale, use or other dealings 2317ca54c3Smrgin this Software without prior written authorization from The Open Group. 2417ca54c3Smrg * * 2517ca54c3Smrg */ 2617ca54c3Smrg 2717ca54c3Smrg#ifndef _XTHREADS_H_ 2817ca54c3Smrg# define _XTHREADS_H_ 2917ca54c3Smrg 3017ca54c3Smrg/* Redefine these to XtMalloc/XtFree or whatever you want before including 3117ca54c3Smrg * this header file. 3217ca54c3Smrg */ 3317ca54c3Smrg# ifndef xmalloc 3417ca54c3Smrg# define xmalloc malloc 3517ca54c3Smrg# endif 3617ca54c3Smrg# ifndef xfree 3717ca54c3Smrg# define xfree free 3817ca54c3Smrg# endif 3917ca54c3Smrg 4017ca54c3Smrg# ifdef CTHREADS 4117ca54c3Smrg# include <cthreads.h> 4217ca54c3Smrgtypedef cthread_t xthread_t; 4317ca54c3Smrgtypedef struct condition xcondition_rec; 4417ca54c3Smrgtypedef struct mutex xmutex_rec; 4517ca54c3Smrg# define xthread_init() cthread_init() 4617ca54c3Smrg# define xthread_self cthread_self 4717ca54c3Smrg# define xthread_fork(func,closure) cthread_fork(func,closure) 4817ca54c3Smrg# define xthread_yield() cthread_yield() 4917ca54c3Smrg# define xthread_exit(v) cthread_exit(v) 5017ca54c3Smrg# define xthread_set_name(t,str) cthread_set_name(t,str) 5117ca54c3Smrg# define xmutex_init(m) mutex_init(m) 5217ca54c3Smrg# define xmutex_clear(m) mutex_clear(m) 5317ca54c3Smrg# define xmutex_lock(m) mutex_lock(m) 5417ca54c3Smrg# define xmutex_unlock(m) mutex_unlock(m) 5517ca54c3Smrg# define xmutex_set_name(m,str) mutex_set_name(m,str) 5617ca54c3Smrg# define xcondition_init(cv) condition_init(cv) 5717ca54c3Smrg# define xcondition_clear(cv) condition_clear(cv) 5817ca54c3Smrg# define xcondition_wait(cv,m) condition_wait(cv,m) 5917ca54c3Smrg# define xcondition_signal(cv) condition_signal(cv) 6017ca54c3Smrg# define xcondition_broadcast(cv) condition_broadcast(cv) 6117ca54c3Smrg# define xcondition_set_name(cv,str) condition_set_name(cv,str) 6217ca54c3Smrg# else /* !CTHREADS */ 6317ca54c3Smrg# if defined(SVR4) 6417ca54c3Smrg# include <thread.h> 6517ca54c3Smrg# include <synch.h> 6617ca54c3Smrgtypedef thread_t xthread_t; 6717ca54c3Smrgtypedef thread_key_t xthread_key_t; 6817ca54c3Smrgtypedef cond_t xcondition_rec; 6917ca54c3Smrgtypedef mutex_t xmutex_rec; 7017ca54c3Smrg# if defined(__UNIXWARE__) 7117ca54c3Smrgextern xthread_t (*_x11_thr_self)(); 7217ca54c3Smrg# define xthread_self (_x11_thr_self) 7317ca54c3Smrg# else 7417ca54c3Smrg# define xthread_self thr_self 7517ca54c3Smrg# endif 7617ca54c3Smrg# define xthread_fork(func,closure) thr_create(NULL,0,func,closure,THR_NEW_LWP|THR_DETACHED,NULL) 7717ca54c3Smrg# define xthread_yield() thr_yield() 7817ca54c3Smrg# define xthread_exit(v) thr_exit(v) 7917ca54c3Smrg# define xthread_key_create(kp,d) thr_keycreate(kp,d) 8017ca54c3Smrg# ifdef __sun 8117ca54c3Smrg# define xthread_key_delete(k) 0 8217ca54c3Smrg# else 8317ca54c3Smrg# define xthread_key_delete(k) thr_keydelete(k) 8417ca54c3Smrg# endif 8517ca54c3Smrg# define xthread_set_specific(k,v) thr_setspecific(k,v) 8617ca54c3Smrg# define xthread_get_specific(k,vp) thr_getspecific(k,vp) 8717ca54c3Smrg# define xmutex_init(m) mutex_init(m,USYNC_THREAD,0) 8817ca54c3Smrg# define xmutex_clear(m) mutex_destroy(m) 8917ca54c3Smrg# define xmutex_lock(m) mutex_lock(m) 9017ca54c3Smrg# define xmutex_unlock(m) mutex_unlock(m) 9117ca54c3Smrg# define xcondition_init(cv) cond_init(cv,USYNC_THREAD,0) 9217ca54c3Smrg# define xcondition_clear(cv) cond_destroy(cv) 9317ca54c3Smrg# define xcondition_wait(cv,m) cond_wait(cv,m) 9417ca54c3Smrg# define xcondition_signal(cv) cond_signal(cv) 9517ca54c3Smrg# define xcondition_broadcast(cv) cond_broadcast(cv) 9617ca54c3Smrg# else /* !SVR4 */ 9717ca54c3Smrg# ifdef WIN32 9817ca54c3Smrg# include <X11/Xwindows.h> 9917ca54c3Smrgtypedef DWORD xthread_t; 10017ca54c3Smrgtypedef DWORD xthread_key_t; 10117ca54c3Smrgstruct _xthread_waiter { 10217ca54c3Smrg HANDLE sem; 10317ca54c3Smrg struct _xthread_waiter *next; 10417ca54c3Smrg}; 10517ca54c3Smrgtypedef struct { 10617ca54c3Smrg CRITICAL_SECTION cs; 10717ca54c3Smrg struct _xthread_waiter *waiters; 10817ca54c3Smrg} xcondition_rec; 10917ca54c3Smrgtypedef CRITICAL_SECTION xmutex_rec; 11017ca54c3Smrgextern void _Xthread_init(void); 11117ca54c3Smrg# define xthread_init() _Xthread_init() 11217ca54c3Smrg# define xthread_self GetCurrentThreadId 11317ca54c3Smrg# define xthread_fork(func,closure) { \ 11417ca54c3Smrg DWORD _tmptid; \ 11517ca54c3Smrg CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, (LPVOID)closure, 0, \ 11617ca54c3Smrg &_tmptid); \ 11717ca54c3Smrg} 11817ca54c3Smrg# define xthread_yield() Sleep(0) 11917ca54c3Smrg# define xthread_exit(v) ExitThread((DWORD)(v)) 12017ca54c3Smrg# define xthread_key_create(kp,d) *(kp) = TlsAlloc() 12117ca54c3Smrg# define xthread_key_delete(k) TlsFree(k) 12217ca54c3Smrg# define xthread_set_specific(k,v) TlsSetValue(k,v) 12317ca54c3Smrg# define xthread_get_specific(k,vp) TlsGetValue(k) 12417ca54c3Smrg# define xmutex_init(m) InitializeCriticalSection(m) 12517ca54c3Smrg# define xmutex_clear(m) DeleteCriticalSection(m) 12617ca54c3Smrg# define _XMUTEX_NESTS 12717ca54c3Smrg# define xmutex_lock(m) EnterCriticalSection(m) 12817ca54c3Smrg# define xmutex_unlock(m) LeaveCriticalSection(m) 12917ca54c3Smrg# define xcondition_init(cv) { \ 13017ca54c3Smrg InitializeCriticalSection(&(cv)->cs); \ 13117ca54c3Smrg (cv)->waiters = NULL; \ 13217ca54c3Smrg} 13317ca54c3Smrg# define xcondition_clear(cv) DeleteCriticalSection(&(cv)->cs) 13417ca54c3Smrgextern struct _xthread_waiter *_Xthread_waiter(); 13517ca54c3Smrg# define xcondition_wait(cv,m) { \ 13617ca54c3Smrg struct _xthread_waiter *_tmpthr = _Xthread_waiter(); \ 13717ca54c3Smrg EnterCriticalSection(&(cv)->cs); \ 13817ca54c3Smrg _tmpthr->next = (cv)->waiters; \ 13917ca54c3Smrg (cv)->waiters = _tmpthr; \ 14017ca54c3Smrg LeaveCriticalSection(&(cv)->cs); \ 14117ca54c3Smrg LeaveCriticalSection(m); \ 14217ca54c3Smrg WaitForSingleObject(_tmpthr->sem, INFINITE); \ 14317ca54c3Smrg EnterCriticalSection(m); \ 14417ca54c3Smrg} 14517ca54c3Smrg# define xcondition_signal(cv) { \ 14617ca54c3Smrg EnterCriticalSection(&(cv)->cs); \ 14717ca54c3Smrg if ((cv)->waiters) { \ 14817ca54c3Smrg ReleaseSemaphore((cv)->waiters->sem, 1, NULL); \ 14917ca54c3Smrg (cv)->waiters = (cv)->waiters->next; \ 15017ca54c3Smrg } \ 15117ca54c3Smrg LeaveCriticalSection(&(cv)->cs); \ 15217ca54c3Smrg} 15317ca54c3Smrg# define xcondition_broadcast(cv) { \ 15417ca54c3Smrg struct _xthread_waiter *_tmpthr; \ 15517ca54c3Smrg EnterCriticalSection(&(cv)->cs); \ 15617ca54c3Smrg for (_tmpthr = (cv)->waiters; _tmpthr; _tmpthr = _tmpthr->next) \ 15717ca54c3Smrg ReleaseSemaphore(_tmpthr->sem, 1, NULL); \ 15817ca54c3Smrg (cv)->waiters = NULL; \ 15917ca54c3Smrg LeaveCriticalSection(&(cv)->cs); \ 16017ca54c3Smrg} 16117ca54c3Smrg# else /* !WIN32 */ 16217ca54c3Smrg# ifdef USE_TIS_SUPPORT 16317ca54c3Smrg/* 16417ca54c3Smrg * TIS support is intended for thread safe libraries. 16517ca54c3Smrg * This should not be used for general client programming. 16617ca54c3Smrg */ 16717ca54c3Smrg# include <tis.h> 16817ca54c3Smrgtypedef pthread_t xthread_t; 16917ca54c3Smrgtypedef pthread_key_t xthread_key_t; 17017ca54c3Smrgtypedef pthread_cond_t xcondition_rec; 17117ca54c3Smrgtypedef pthread_mutex_t xmutex_rec; 17217ca54c3Smrg# define xthread_self tis_self 17317ca54c3Smrg# define xthread_fork(func,closure) { pthread_t _tmpxthr; \ 17417ca54c3Smrg pthread_create(&_tmpxthr,NULL,func,closure); } 17517ca54c3Smrg# define xthread_yield() pthread_yield_np() 17617ca54c3Smrg# define xthread_exit(v) pthread_exit(v) 17717ca54c3Smrg# define xthread_key_create(kp,d) tis_key_create(kp,d) 17817ca54c3Smrg# define xthread_key_delete(k) tis_key_delete(k) 17917ca54c3Smrg# define xthread_set_specific(k,v) tis_setspecific(k,v) 18017ca54c3Smrg# define xthread_get_specific(k,vp) *(vp) = tis_getspecific(k) 18117ca54c3Smrg# define XMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 18217ca54c3Smrg# define xmutex_init(m) tis_mutex_init(m) 18317ca54c3Smrg# define xmutex_clear(m) tis_mutex_destroy(m) 18417ca54c3Smrg# define xmutex_lock(m) tis_mutex_lock(m) 18517ca54c3Smrg# define xmutex_unlock(m) tis_mutex_unlock(m) 18617ca54c3Smrg# define xcondition_init(c) tis_cond_init(c) 18717ca54c3Smrg# define xcondition_clear(c) tis_cond_destroy(c) 18817ca54c3Smrg# define xcondition_wait(c,m) tis_cond_wait(c,m) 18917ca54c3Smrg# define xcondition_signal(c) tis_cond_signal(c) 19017ca54c3Smrg# define xcondition_broadcast(c) tis_cond_broadcast(c) 19117ca54c3Smrg# else 19217ca54c3Smrg# ifdef USE_NBSD_THREADLIB 19317ca54c3Smrg/* 19417ca54c3Smrg * NetBSD threadlib support is intended for thread safe libraries. 19517ca54c3Smrg * This should not be used for general client programming. 19617ca54c3Smrg */ 19717ca54c3Smrg# include <threadlib.h> 19817ca54c3Smrgtypedef thr_t xthread_t; 19917ca54c3Smrgtypedef thread_key_t xthread_key_t; 20017ca54c3Smrgtypedef cond_t xcondition_rec; 20117ca54c3Smrgtypedef mutex_t xmutex_rec; 20217ca54c3Smrg# define xthread_self thr_self 20317ca54c3Smrg# define xthread_fork(func,closure) { thr_t _tmpxthr; \ 20417ca54c3Smrg /* XXX Create it detached? --thorpej */ \ 20517ca54c3Smrg thr_create(&_tmpxthr,NULL,func,closure); } 20617ca54c3Smrg# define xthread_yield() thr_yield() 20717ca54c3Smrg# define xthread_exit(v) thr_exit(v) 20817ca54c3Smrg# define xthread_key_create(kp,d) thr_keycreate(kp,d) 20917ca54c3Smrg# define xthread_key_delete(k) thr_keydelete(k) 21017ca54c3Smrg# define xthread_set_specific(k,v) thr_setspecific(k,v) 21117ca54c3Smrg# define xthread_get_specific(k,vp) *(vp) = thr_getspecific(k) 21217ca54c3Smrg# define XMUTEX_INITIALIZER MUTEX_INITIALIZER 21317ca54c3Smrg# define xmutex_init(m) mutex_init(m, 0) 21417ca54c3Smrg# define xmutex_clear(m) mutex_destroy(m) 21517ca54c3Smrg# define xmutex_lock(m) mutex_lock(m) 21617ca54c3Smrg# define xmutex_unlock(m) mutex_unlock(m) 21717ca54c3Smrg# define xcondition_init(c) cond_init(c, 0, 0) 21817ca54c3Smrg# define xcondition_clear(c) cond_destroy(c) 21917ca54c3Smrg# define xcondition_wait(c,m) cond_wait(c,m) 22017ca54c3Smrg# define xcondition_signal(c) cond_signal(c) 22117ca54c3Smrg# define xcondition_broadcast(c) cond_broadcast(c) 22217ca54c3Smrg# else 22317ca54c3Smrg# include <pthread.h> 22417ca54c3Smrgtypedef pthread_t xthread_t; 22517ca54c3Smrgtypedef pthread_key_t xthread_key_t; 22617ca54c3Smrgtypedef pthread_cond_t xcondition_rec; 22717ca54c3Smrgtypedef pthread_mutex_t xmutex_rec; 22817ca54c3Smrg# define xthread_self pthread_self 22917ca54c3Smrg# define xthread_yield() pthread_yield() 23017ca54c3Smrg# define xthread_exit(v) pthread_exit(v) 23117ca54c3Smrg# define xthread_set_specific(k,v) pthread_setspecific(k,v) 23217ca54c3Smrg# define xmutex_clear(m) pthread_mutex_destroy(m) 23317ca54c3Smrg# define xmutex_lock(m) pthread_mutex_lock(m) 23417ca54c3Smrg# define xmutex_unlock(m) pthread_mutex_unlock(m) 23517ca54c3Smrg# ifndef XPRE_STANDARD_API 23617ca54c3Smrg# define xthread_key_create(kp,d) pthread_key_create(kp,d) 23717ca54c3Smrg# define xthread_key_delete(k) pthread_key_delete(k) 23817ca54c3Smrg# define xthread_get_specific(k,vp) *(vp) = pthread_getspecific(k) 23917ca54c3Smrg# define xthread_fork(func,closure) { pthread_t _tmpxthr; \ 24017ca54c3Smrg pthread_create(&_tmpxthr,NULL,func,closure); } 24117ca54c3Smrg# define XMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 24217ca54c3Smrg# define xmutex_init(m) pthread_mutex_init(m, NULL) 24317ca54c3Smrg# define xcondition_init(c) pthread_cond_init(c, NULL) 24417ca54c3Smrg# else /* XPRE_STANDARD_API */ 24517ca54c3Smrg# define xthread_key_create(kp,d) pthread_keycreate(kp,d) 24617ca54c3Smrg# define xthread_key_delete(k) 0 24717ca54c3Smrg# define xthread_get_specific(k,vp) pthread_getspecific(k,vp) 24817ca54c3Smrg# define xthread_fork(func,closure) { pthread_t _tmpxthr; \ 24917ca54c3Smrg pthread_create(&_tmpxthr,pthread_attr_default,func,closure); } 25017ca54c3Smrg# define xmutex_init(m) pthread_mutex_init(m, pthread_mutexattr_default) 25117ca54c3Smrg# define xcondition_init(c) pthread_cond_init(c, pthread_condattr_default) 25217ca54c3Smrg# endif /* XPRE_STANDARD_API */ 25317ca54c3Smrg# define xcondition_clear(c) pthread_cond_destroy(c) 25417ca54c3Smrg# define xcondition_wait(c,m) pthread_cond_wait(c,m) 25517ca54c3Smrg# define xcondition_signal(c) pthread_cond_signal(c) 25617ca54c3Smrg# define xcondition_broadcast(c) pthread_cond_broadcast(c) 25717ca54c3Smrg# if defined(_DECTHREADS_) 25817ca54c3Smrgstatic xthread_t _X_no_thread_id; 25917ca54c3Smrg# define xthread_have_id(id) !pthread_equal(id, _X_no_thread_id) 26017ca54c3Smrg# define xthread_clear_id(id) id = _X_no_thread_id 26117ca54c3Smrg# define xthread_equal(id1,id2) pthread_equal(id1, id2) 26217ca54c3Smrg# endif /* _DECTHREADS_ */ 26317ca54c3Smrg# if defined(__linux__) 26417ca54c3Smrg# define xthread_have_id(id) !pthread_equal(id, 0) 26517ca54c3Smrg# define xthread_clear_id(id) id = 0 26617ca54c3Smrg# define xthread_equal(id1,id2) pthread_equal(id1, id2) 26717ca54c3Smrg# endif /* linux */ 26817ca54c3Smrg# if defined(_CMA_VENDOR_) && defined(_CMA__IBM) && (_CMA_VENDOR_ == _CMA__IBM) 26917ca54c3Smrg# ifdef DEBUG /* too much of a hack to enable normally */ 27017ca54c3Smrg/* see also cma__obj_set_name() */ 27117ca54c3Smrg# define xmutex_set_name(m,str) ((char**)(m)->field1)[5] = (str) 27217ca54c3Smrg# define xcondition_set_name(cv,str) ((char**)(cv)->field1)[5] = (str) 27317ca54c3Smrg# endif /* DEBUG */ 27417ca54c3Smrg# endif /* _CMA_VENDOR_ == _CMA__IBM */ 27517ca54c3Smrg# endif /* USE_NBSD_THREADLIB */ 27617ca54c3Smrg# endif /* USE_TIS_SUPPORT */ 27717ca54c3Smrg# endif /* WIN32 */ 27817ca54c3Smrg# endif /* SVR4 */ 27917ca54c3Smrg# endif /* CTHREADS */ 28017ca54c3Smrgtypedef xcondition_rec *xcondition_t; 28117ca54c3Smrgtypedef xmutex_rec *xmutex_t; 28217ca54c3Smrg# ifndef xcondition_malloc 28317ca54c3Smrg# define xcondition_malloc() (xcondition_t)xmalloc(sizeof(xcondition_rec)) 28417ca54c3Smrg# endif 28517ca54c3Smrg# ifndef xcondition_free 28617ca54c3Smrg# define xcondition_free(c) xfree((char *)c) 28717ca54c3Smrg# endif 28817ca54c3Smrg# ifndef xmutex_malloc 28917ca54c3Smrg# define xmutex_malloc() (xmutex_t)xmalloc(sizeof(xmutex_rec)) 29017ca54c3Smrg# endif 29117ca54c3Smrg# ifndef xmutex_free 29217ca54c3Smrg# define xmutex_free(m) xfree((char *)m) 29317ca54c3Smrg# endif 29417ca54c3Smrg# ifndef xthread_have_id 29517ca54c3Smrg# define xthread_have_id(id) id 29617ca54c3Smrg# endif 29717ca54c3Smrg# ifndef xthread_clear_id 29817ca54c3Smrg# define xthread_clear_id(id) id = 0 29917ca54c3Smrg# endif 30017ca54c3Smrg# ifndef xthread_equal 30117ca54c3Smrg# define xthread_equal(id1,id2) ((id1) == (id2)) 30217ca54c3Smrg# endif 30317ca54c3Smrg/* aids understood by some debuggers */ 30417ca54c3Smrg# ifndef xthread_set_name 30517ca54c3Smrg# define xthread_set_name(t,str) 30617ca54c3Smrg# endif 30717ca54c3Smrg# ifndef xmutex_set_name 30817ca54c3Smrg# define xmutex_set_name(m,str) 30917ca54c3Smrg# endif 31017ca54c3Smrg# ifndef xcondition_set_name 31117ca54c3Smrg# define xcondition_set_name(cv,str) 31217ca54c3Smrg# endif 31317ca54c3Smrg 31417ca54c3Smrg#endif /* _XTHREADS_H_ */ 315