1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef nspr_pth_defs_h_
7 #define nspr_pth_defs_h_
8 
9 /*
10 ** Appropriate definitions of entry points not used in a pthreads world
11 */
12 #define _PR_MD_BLOCK_CLOCK_INTERRUPTS()
13 #define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS()
14 #define _PR_MD_DISABLE_CLOCK_INTERRUPTS()
15 #define _PR_MD_ENABLE_CLOCK_INTERRUPTS()
16 
17 #if defined(BSDI)
18 /*
19  * Mutex and condition attributes are not supported.  The attr
20  * argument to pthread_mutex_init() and pthread_cond_init() must
21  * be passed as NULL.
22  *
23  * The memset calls in _PT_PTHREAD_MUTEX_INIT and _PT_PTHREAD_COND_INIT
24  * are to work around BSDI's using a single bit to indicate a mutex
25  * or condition variable is initialized.  This entire BSDI section
26  * will go away when BSDI releases updated threads libraries for
27  * BSD/OS 3.1 and 4.0.
28  */
29 #define _PT_PTHREAD_MUTEXATTR_INIT(x)     0
30 #define _PT_PTHREAD_MUTEXATTR_DESTROY(x)  /* */
31 #define _PT_PTHREAD_MUTEX_INIT(m, a)      (memset(&(m), 0, sizeof(m)), \
32                                       pthread_mutex_init(&(m), NULL))
33 #define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (EBUSY == pthread_mutex_trylock(&(m)))
34 #define _PT_PTHREAD_CONDATTR_INIT(x)      0
35 #define _PT_PTHREAD_CONDATTR_DESTROY(x)   /* */
36 #define _PT_PTHREAD_COND_INIT(m, a)       (memset(&(m), 0, sizeof(m)), \
37                                       pthread_cond_init(&(m), NULL))
38 #else
39 #define _PT_PTHREAD_MUTEXATTR_INIT        pthread_mutexattr_init
40 #define _PT_PTHREAD_MUTEXATTR_DESTROY     pthread_mutexattr_destroy
41 #define _PT_PTHREAD_MUTEX_INIT(m, a)      pthread_mutex_init(&(m), &(a))
42 #if defined(FREEBSD)
43 #define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    pt_pthread_mutex_is_locked(&(m))
44 #else
45 #define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (EBUSY == pthread_mutex_trylock(&(m)))
46 #endif
47 #if defined(ANDROID)
48 /* Conditional attribute init and destroy aren't implemented in bionic. */
49 #define _PT_PTHREAD_CONDATTR_INIT(x)      0
50 #define _PT_PTHREAD_CONDATTR_DESTROY(x)   /* */
51 #else
52 #define _PT_PTHREAD_CONDATTR_INIT         pthread_condattr_init
53 #define _PT_PTHREAD_CONDATTR_DESTROY      pthread_condattr_destroy
54 #endif
55 #define _PT_PTHREAD_COND_INIT(m, a)       pthread_cond_init(&(m), &(a))
56 #endif
57 
58 /* The pthreads standard does not specify an invalid value for the
59  * pthread_t handle.  (0 is usually an invalid pthread identifier
60  * but there are exceptions, for example, DG/UX.)  These macros
61  * define a way to set the handle to or compare the handle with an
62  * invalid identifier.  These macros are not portable and may be
63  * more of a problem as we adapt to more pthreads implementations.
64  * They are only used in the PRMonitor functions.  Do not use them
65  * in new code.
66  *
67  * Unfortunately some of our clients depend on certain properties
68  * of our PRMonitor implementation, preventing us from replacing
69  * it by a portable implementation.
70  * - High-performance servers like the fact that PR_EnterMonitor
71  *   only calls PR_Lock and PR_ExitMonitor only calls PR_Unlock.
72  *   (A portable implementation would use a PRLock and a PRCondVar
73  *   to implement the recursive lock in a monitor and call both
74  *   PR_Lock and PR_Unlock in PR_EnterMonitor and PR_ExitMonitor.)
75  *   Unfortunately this forces us to read the monitor owner field
76  *   without holding a lock.
77  * - One way to make it safe to read the monitor owner field
78  *   without holding a lock is to make that field a PRThread*
79  *   (one should be able to read a pointer with a single machine
80  *   instruction).  However, PR_GetCurrentThread calls calloc if
81  *   it is called by a thread that was not created by NSPR.  The
82  *   malloc tracing tools in the Mozilla client use PRMonitor for
83  *   locking in their malloc, calloc, and free functions.  If
84  *   PR_EnterMonitor calls any of these functions, infinite
85  *   recursion ensues.
86  */
87 #if defined(AIX) || defined(SOLARIS) \
88     || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
89     || defined(HPUX) || defined(FREEBSD) \
90     || defined(NETBSD) || defined(OPENBSD) || defined(BSDI) \
91     || defined(NTO) || defined(DARWIN) \
92     || defined(UNIXWARE) || defined(RISCOS)
93 #define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t)  (t) = 0
94 #define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t)  (t) == 0
95 #define _PT_PTHREAD_COPY_THR_HANDLE(st, dt)   (dt) = (st)
96 #else
97 #error "pthreads is not supported for this architecture"
98 #endif
99 
100 #if defined(_PR_PTHREADS)
101 #define _PT_PTHREAD_ATTR_INIT            pthread_attr_init
102 #define _PT_PTHREAD_ATTR_DESTROY         pthread_attr_destroy
103 #define _PT_PTHREAD_CREATE(t, a, f, r)   pthread_create(t, &a, f, r)
104 #define _PT_PTHREAD_KEY_CREATE           pthread_key_create
105 #define _PT_PTHREAD_ATTR_SETSCHEDPOLICY  pthread_attr_setschedpolicy
106 #define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) pthread_attr_getstacksize(a, s)
107 #define _PT_PTHREAD_GETSPECIFIC(k, r)    (r) = pthread_getspecific(k)
108 #else
109 #error "Cannot determine pthread strategy"
110 #endif
111 
112 /*
113  * These platforms don't have sigtimedwait()
114  */
115 #if (defined(AIX) && !defined(AIX4_3_PLUS)) \
116     || defined(LINUX) || defined(__GNU__)|| defined(__GLIBC__) \
117     || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
118     || defined(BSDI) || defined(UNIXWARE) \
119     || defined(DARWIN)
120 #define PT_NO_SIGTIMEDWAIT
121 #endif
122 
123 #if defined(AIX)
124 #include <sys/priv.h>
125 #include <sys/sched.h>
126 #ifndef PTHREAD_CREATE_JOINABLE
127 #define PTHREAD_CREATE_JOINABLE     PTHREAD_CREATE_UNDETACHED
128 #endif
129 #define PT_PRIO_MIN            DEFAULT_PRIO
130 #define PT_PRIO_MAX            DEFAULT_PRIO
131 #elif defined(HPUX)
132 #include <sys/sched.h>
133 #define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
134 #define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
135 #elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
136     || defined(FREEBSD)
137 #define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
138 #define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
139 #elif defined(NTO)
140 /*
141  * Neutrino has functions that return the priority range but
142  * they return invalid numbers, so I just hard coded these here
143  * for now.  Jerry.Kirk@Nexarecorp.com
144  */
145 #define PT_PRIO_MIN            0
146 #define PT_PRIO_MAX            30
147 #elif defined(SOLARIS)
148 /*
149  * Solaris doesn't seem to have macros for the min/max priorities.
150  * The range of 0-127 is mentioned in the pthread_setschedparam(3T)
151  * man pages, and pthread_setschedparam indeed allows 0-127.  However,
152  * pthread_attr_setschedparam does not allow 0; it allows 1-127.
153  */
154 #define PT_PRIO_MIN            1
155 #define PT_PRIO_MAX            127
156 #elif defined(OPENBSD)
157 #define PT_PRIO_MIN            0
158 #define PT_PRIO_MAX            31
159 #elif defined(NETBSD) \
160     || defined(BSDI) || defined(DARWIN) || defined(UNIXWARE) \
161     || defined(RISCOS) /* XXX */
162 #define PT_PRIO_MIN            0
163 #define PT_PRIO_MAX            126
164 #else
165 #error "pthreads is not supported for this architecture"
166 #endif
167 
168 /*
169  * The _PT_PTHREAD_YIELD function is called from a signal handler.
170  * Needed for garbage collection -- Look at PR_Suspend/PR_Resume
171  * implementation.
172  */
173 #if defined(AIX)
174 extern int (*_PT_aix_yield_fcn)();
175 #define _PT_PTHREAD_YIELD()         (*_PT_aix_yield_fcn)()
176 #elif defined(HPUX) || defined(SOLARIS) \
177     || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
178     || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
179     || defined(BSDI) || defined(NTO) || defined(DARWIN) \
180     || defined(UNIXWARE) || defined(RISCOS)
181 #define _PT_PTHREAD_YIELD()             sched_yield()
182 #else
183 #error "Need to define _PT_PTHREAD_YIELD for this platform"
184 #endif
185 
186 #endif /* nspr_pth_defs_h_ */
187