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