nsprpub/pr/include/md/_pth.h

changeset 0
6474c204b198
     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_ */

mercurial