1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/include/md/_pth.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,270 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nspr_pth_defs_h_ 1.10 +#define nspr_pth_defs_h_ 1.11 + 1.12 +/* 1.13 +** Appropriate definitions of entry points not used in a pthreads world 1.14 +*/ 1.15 +#define _PR_MD_BLOCK_CLOCK_INTERRUPTS() 1.16 +#define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS() 1.17 +#define _PR_MD_DISABLE_CLOCK_INTERRUPTS() 1.18 +#define _PR_MD_ENABLE_CLOCK_INTERRUPTS() 1.19 + 1.20 +/* In good standards fashion, the DCE threads (based on posix-4) are not 1.21 + * quite the same as newer posix implementations. These are mostly name 1.22 + * changes and small differences, so macros usually do the trick 1.23 + */ 1.24 +#ifdef _PR_DCETHREADS 1.25 +#define _PT_PTHREAD_MUTEXATTR_INIT pthread_mutexattr_create 1.26 +#define _PT_PTHREAD_MUTEXATTR_DESTROY pthread_mutexattr_delete 1.27 +#define _PT_PTHREAD_MUTEX_INIT(m, a) pthread_mutex_init(&(m), a) 1.28 +#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) (0 == pthread_mutex_trylock(&(m))) 1.29 +#define _PT_PTHREAD_CONDATTR_INIT pthread_condattr_create 1.30 +#define _PT_PTHREAD_COND_INIT(m, a) pthread_cond_init(&(m), a) 1.31 +#define _PT_PTHREAD_CONDATTR_DESTROY pthread_condattr_delete 1.32 + 1.33 +/* Notes about differences between DCE threads and pthreads 10: 1.34 + * 1. pthread_mutex_trylock returns 1 when it locks the mutex 1.35 + * 0 when it does not. The latest pthreads has a set of errno-like 1.36 + * return values. 1.37 + * 2. return values from pthread_cond_timedwait are different. 1.38 + * 1.39 + * 1.40 + * 1.41 + */ 1.42 +#elif defined(BSDI) 1.43 +/* 1.44 + * Mutex and condition attributes are not supported. The attr 1.45 + * argument to pthread_mutex_init() and pthread_cond_init() must 1.46 + * be passed as NULL. 1.47 + * 1.48 + * The memset calls in _PT_PTHREAD_MUTEX_INIT and _PT_PTHREAD_COND_INIT 1.49 + * are to work around BSDI's using a single bit to indicate a mutex 1.50 + * or condition variable is initialized. This entire BSDI section 1.51 + * will go away when BSDI releases updated threads libraries for 1.52 + * BSD/OS 3.1 and 4.0. 1.53 + */ 1.54 +#define _PT_PTHREAD_MUTEXATTR_INIT(x) 0 1.55 +#define _PT_PTHREAD_MUTEXATTR_DESTROY(x) /* */ 1.56 +#define _PT_PTHREAD_MUTEX_INIT(m, a) (memset(&(m), 0, sizeof(m)), \ 1.57 + pthread_mutex_init(&(m), NULL)) 1.58 +#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) (EBUSY == pthread_mutex_trylock(&(m))) 1.59 +#define _PT_PTHREAD_CONDATTR_INIT(x) 0 1.60 +#define _PT_PTHREAD_CONDATTR_DESTROY(x) /* */ 1.61 +#define _PT_PTHREAD_COND_INIT(m, a) (memset(&(m), 0, sizeof(m)), \ 1.62 + pthread_cond_init(&(m), NULL)) 1.63 +#else 1.64 +#define _PT_PTHREAD_MUTEXATTR_INIT pthread_mutexattr_init 1.65 +#define _PT_PTHREAD_MUTEXATTR_DESTROY pthread_mutexattr_destroy 1.66 +#define _PT_PTHREAD_MUTEX_INIT(m, a) pthread_mutex_init(&(m), &(a)) 1.67 +#if defined(FREEBSD) 1.68 +#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) pt_pthread_mutex_is_locked(&(m)) 1.69 +#else 1.70 +#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) (EBUSY == pthread_mutex_trylock(&(m))) 1.71 +#endif 1.72 +#if defined(ANDROID) 1.73 +/* Conditional attribute init and destroy aren't implemented in bionic. */ 1.74 +#define _PT_PTHREAD_CONDATTR_INIT(x) 0 1.75 +#define _PT_PTHREAD_CONDATTR_DESTROY(x) /* */ 1.76 +#else 1.77 +#define _PT_PTHREAD_CONDATTR_INIT pthread_condattr_init 1.78 +#define _PT_PTHREAD_CONDATTR_DESTROY pthread_condattr_destroy 1.79 +#endif 1.80 +#define _PT_PTHREAD_COND_INIT(m, a) pthread_cond_init(&(m), &(a)) 1.81 +#endif 1.82 + 1.83 +/* The pthreads standard does not specify an invalid value for the 1.84 + * pthread_t handle. (0 is usually an invalid pthread identifier 1.85 + * but there are exceptions, for example, DG/UX.) These macros 1.86 + * define a way to set the handle to or compare the handle with an 1.87 + * invalid identifier. These macros are not portable and may be 1.88 + * more of a problem as we adapt to more pthreads implementations. 1.89 + * They are only used in the PRMonitor functions. Do not use them 1.90 + * in new code. 1.91 + * 1.92 + * Unfortunately some of our clients depend on certain properties 1.93 + * of our PRMonitor implementation, preventing us from replacing 1.94 + * it by a portable implementation. 1.95 + * - High-performance servers like the fact that PR_EnterMonitor 1.96 + * only calls PR_Lock and PR_ExitMonitor only calls PR_Unlock. 1.97 + * (A portable implementation would use a PRLock and a PRCondVar 1.98 + * to implement the recursive lock in a monitor and call both 1.99 + * PR_Lock and PR_Unlock in PR_EnterMonitor and PR_ExitMonitor.) 1.100 + * Unfortunately this forces us to read the monitor owner field 1.101 + * without holding a lock. 1.102 + * - One way to make it safe to read the monitor owner field 1.103 + * without holding a lock is to make that field a PRThread* 1.104 + * (one should be able to read a pointer with a single machine 1.105 + * instruction). However, PR_GetCurrentThread calls calloc if 1.106 + * it is called by a thread that was not created by NSPR. The 1.107 + * malloc tracing tools in the Mozilla client use PRMonitor for 1.108 + * locking in their malloc, calloc, and free functions. If 1.109 + * PR_EnterMonitor calls any of these functions, infinite 1.110 + * recursion ensues. 1.111 + */ 1.112 +#if defined(_PR_DCETHREADS) 1.113 +#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) \ 1.114 + memset(&(t), 0, sizeof(pthread_t)) 1.115 +#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) \ 1.116 + (!memcmp(&(t), &pt_zero_tid, sizeof(pthread_t))) 1.117 +#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt) (dt) = (st) 1.118 +#elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(SOLARIS) \ 1.119 + || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ 1.120 + || defined(HPUX) || defined(FREEBSD) \ 1.121 + || defined(NETBSD) || defined(OPENBSD) || defined(BSDI) \ 1.122 + || defined(NTO) || defined(DARWIN) \ 1.123 + || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN) 1.124 +#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) (t) = 0 1.125 +#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) (t) == 0 1.126 +#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt) (dt) = (st) 1.127 +#else 1.128 +#error "pthreads is not supported for this architecture" 1.129 +#endif 1.130 + 1.131 +#if defined(_PR_DCETHREADS) 1.132 +#define _PT_PTHREAD_ATTR_INIT pthread_attr_create 1.133 +#define _PT_PTHREAD_ATTR_DESTROY pthread_attr_delete 1.134 +#define _PT_PTHREAD_CREATE(t, a, f, r) pthread_create(t, a, f, r) 1.135 +#define _PT_PTHREAD_KEY_CREATE pthread_keycreate 1.136 +#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY pthread_attr_setsched 1.137 +#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) \ 1.138 + (*(s) = pthread_attr_getstacksize(*(a)), 0) 1.139 +#define _PT_PTHREAD_GETSPECIFIC(k, r) \ 1.140 + pthread_getspecific((k), (pthread_addr_t *) &(r)) 1.141 +#elif defined(_PR_PTHREADS) 1.142 +#define _PT_PTHREAD_ATTR_INIT pthread_attr_init 1.143 +#define _PT_PTHREAD_ATTR_DESTROY pthread_attr_destroy 1.144 +#define _PT_PTHREAD_CREATE(t, a, f, r) pthread_create(t, &a, f, r) 1.145 +#define _PT_PTHREAD_KEY_CREATE pthread_key_create 1.146 +#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY pthread_attr_setschedpolicy 1.147 +#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) pthread_attr_getstacksize(a, s) 1.148 +#define _PT_PTHREAD_GETSPECIFIC(k, r) (r) = pthread_getspecific(k) 1.149 +#else 1.150 +#error "Cannot determine pthread strategy" 1.151 +#endif 1.152 + 1.153 +#if defined(_PR_DCETHREADS) 1.154 +#define _PT_PTHREAD_EXPLICIT_SCHED _PT_PTHREAD_DEFAULT_SCHED 1.155 +#endif 1.156 + 1.157 +/* 1.158 + * pthread_mutex_trylock returns different values in DCE threads and 1.159 + * pthreads. 1.160 + */ 1.161 +#if defined(_PR_DCETHREADS) 1.162 +#define PT_TRYLOCK_SUCCESS 1 1.163 +#define PT_TRYLOCK_BUSY 0 1.164 +#else 1.165 +#define PT_TRYLOCK_SUCCESS 0 1.166 +#define PT_TRYLOCK_BUSY EBUSY 1.167 +#endif 1.168 + 1.169 +/* 1.170 + * These platforms don't have sigtimedwait() 1.171 + */ 1.172 +#if (defined(AIX) && !defined(AIX4_3_PLUS)) \ 1.173 + || defined(LINUX) || defined(__GNU__)|| defined(__GLIBC__) \ 1.174 + || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \ 1.175 + || defined(BSDI) || defined(UNIXWARE) \ 1.176 + || defined(DARWIN) || defined(SYMBIAN) 1.177 +#define PT_NO_SIGTIMEDWAIT 1.178 +#endif 1.179 + 1.180 +#if defined(OSF1) 1.181 +#define PT_PRIO_MIN PRI_OTHER_MIN 1.182 +#define PT_PRIO_MAX PRI_OTHER_MAX 1.183 +#elif defined(IRIX) 1.184 +#include <sys/sched.h> 1.185 +#define PT_PRIO_MIN PX_PRIO_MIN 1.186 +#define PT_PRIO_MAX PX_PRIO_MAX 1.187 +#elif defined(AIX) 1.188 +#include <sys/priv.h> 1.189 +#include <sys/sched.h> 1.190 +#ifndef PTHREAD_CREATE_JOINABLE 1.191 +#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED 1.192 +#endif 1.193 +#define PT_PRIO_MIN DEFAULT_PRIO 1.194 +#define PT_PRIO_MAX DEFAULT_PRIO 1.195 +#elif defined(HPUX) 1.196 + 1.197 +#if defined(_PR_DCETHREADS) 1.198 +#define PT_PRIO_MIN PRI_OTHER_MIN 1.199 +#define PT_PRIO_MAX PRI_OTHER_MAX 1.200 +#else /* defined(_PR_DCETHREADS) */ 1.201 +#include <sys/sched.h> 1.202 +#define PT_PRIO_MIN sched_get_priority_min(SCHED_OTHER) 1.203 +#define PT_PRIO_MAX sched_get_priority_max(SCHED_OTHER) 1.204 +#endif /* defined(_PR_DCETHREADS) */ 1.205 + 1.206 +#elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ 1.207 + || defined(FREEBSD) || defined(SYMBIAN) 1.208 +#define PT_PRIO_MIN sched_get_priority_min(SCHED_OTHER) 1.209 +#define PT_PRIO_MAX sched_get_priority_max(SCHED_OTHER) 1.210 +#elif defined(NTO) 1.211 +/* 1.212 + * Neutrino has functions that return the priority range but 1.213 + * they return invalid numbers, so I just hard coded these here 1.214 + * for now. Jerry.Kirk@Nexarecorp.com 1.215 + */ 1.216 +#define PT_PRIO_MIN 0 1.217 +#define PT_PRIO_MAX 30 1.218 +#elif defined(SOLARIS) 1.219 +/* 1.220 + * Solaris doesn't seem to have macros for the min/max priorities. 1.221 + * The range of 0-127 is mentioned in the pthread_setschedparam(3T) 1.222 + * man pages, and pthread_setschedparam indeed allows 0-127. However, 1.223 + * pthread_attr_setschedparam does not allow 0; it allows 1-127. 1.224 + */ 1.225 +#define PT_PRIO_MIN 1 1.226 +#define PT_PRIO_MAX 127 1.227 +#elif defined(OPENBSD) 1.228 +#define PT_PRIO_MIN 0 1.229 +#define PT_PRIO_MAX 31 1.230 +#elif defined(NETBSD) \ 1.231 + || defined(BSDI) || defined(DARWIN) || defined(UNIXWARE) \ 1.232 + || defined(RISCOS) /* XXX */ 1.233 +#define PT_PRIO_MIN 0 1.234 +#define PT_PRIO_MAX 126 1.235 +#else 1.236 +#error "pthreads is not supported for this architecture" 1.237 +#endif 1.238 + 1.239 +/* 1.240 + * The _PT_PTHREAD_YIELD function is called from a signal handler. 1.241 + * Needed for garbage collection -- Look at PR_Suspend/PR_Resume 1.242 + * implementation. 1.243 + */ 1.244 +#if defined(_PR_DCETHREADS) 1.245 +#define _PT_PTHREAD_YIELD() pthread_yield() 1.246 +#elif defined(OSF1) 1.247 +/* 1.248 + * sched_yield can't be called from a signal handler. Must use 1.249 + * the _np version. 1.250 + */ 1.251 +#define _PT_PTHREAD_YIELD() pthread_yield_np() 1.252 +#elif defined(AIX) 1.253 +extern int (*_PT_aix_yield_fcn)(); 1.254 +#define _PT_PTHREAD_YIELD() (*_PT_aix_yield_fcn)() 1.255 +#elif defined(IRIX) 1.256 +#include <time.h> 1.257 +#define _PT_PTHREAD_YIELD() \ 1.258 + PR_BEGIN_MACRO \ 1.259 + struct timespec onemillisec = {0}; \ 1.260 + onemillisec.tv_nsec = 1000000L; \ 1.261 + nanosleep(&onemillisec,NULL); \ 1.262 + PR_END_MACRO 1.263 +#elif defined(HPUX) || defined(SOLARIS) \ 1.264 + || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ 1.265 + || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \ 1.266 + || defined(BSDI) || defined(NTO) || defined(DARWIN) \ 1.267 + || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN) 1.268 +#define _PT_PTHREAD_YIELD() sched_yield() 1.269 +#else 1.270 +#error "Need to define _PT_PTHREAD_YIELD for this platform" 1.271 +#endif 1.272 + 1.273 +#endif /* nspr_pth_defs_h_ */