Back to index

lightning-sunbird  0.9+nobinonly
_pth.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nspr_pth_defs_h_
00039 #define nspr_pth_defs_h_
00040 
00041 /*
00042 ** Appropriate definitions of entry points not used in a pthreads world
00043 */
00044 #define _PR_MD_BLOCK_CLOCK_INTERRUPTS()
00045 #define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS()
00046 #define _PR_MD_DISABLE_CLOCK_INTERRUPTS()
00047 #define _PR_MD_ENABLE_CLOCK_INTERRUPTS()
00048 
00049 /* In good standards fashion, the DCE threads (based on posix-4) are not
00050  * quite the same as newer posix implementations.  These are mostly name
00051  * changes and small differences, so macros usually do the trick
00052  */
00053 #ifdef _PR_DCETHREADS
00054 #define _PT_PTHREAD_MUTEXATTR_INIT        pthread_mutexattr_create
00055 #define _PT_PTHREAD_MUTEXATTR_DESTROY     pthread_mutexattr_delete
00056 #define _PT_PTHREAD_MUTEX_INIT(m, a)      pthread_mutex_init(&(m), a)
00057 #define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (0 == pthread_mutex_trylock(&(m)))
00058 #define _PT_PTHREAD_CONDATTR_INIT         pthread_condattr_create
00059 #define _PT_PTHREAD_COND_INIT(m, a)       pthread_cond_init(&(m), a)
00060 #define _PT_PTHREAD_CONDATTR_DESTROY      pthread_condattr_delete
00061 
00062 /* Notes about differences between DCE threads and pthreads 10:
00063  *   1. pthread_mutex_trylock returns 1 when it locks the mutex
00064  *      0 when it does not.  The latest pthreads has a set of errno-like
00065  *      return values.
00066  *   2. return values from pthread_cond_timedwait are different.
00067  *
00068  *
00069  *
00070  */
00071 #elif defined(BSDI)
00072 /*
00073  * Mutex and condition attributes are not supported.  The attr
00074  * argument to pthread_mutex_init() and pthread_cond_init() must
00075  * be passed as NULL.
00076  *
00077  * The memset calls in _PT_PTHREAD_MUTEX_INIT and _PT_PTHREAD_COND_INIT
00078  * are to work around BSDI's using a single bit to indicate a mutex
00079  * or condition variable is initialized.  This entire BSDI section
00080  * will go away when BSDI releases updated threads libraries for
00081  * BSD/OS 3.1 and 4.0.
00082  */
00083 #define _PT_PTHREAD_MUTEXATTR_INIT(x)     0
00084 #define _PT_PTHREAD_MUTEXATTR_DESTROY(x)  /* */
00085 #define _PT_PTHREAD_MUTEX_INIT(m, a)      (memset(&(m), 0, sizeof(m)), \
00086                                       pthread_mutex_init(&(m), NULL))
00087 #define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (EBUSY == pthread_mutex_trylock(&(m)))
00088 #define _PT_PTHREAD_CONDATTR_INIT(x)      0
00089 #define _PT_PTHREAD_CONDATTR_DESTROY(x)   /* */
00090 #define _PT_PTHREAD_COND_INIT(m, a)       (memset(&(m), 0, sizeof(m)), \
00091                                       pthread_cond_init(&(m), NULL))
00092 #else
00093 #define _PT_PTHREAD_MUTEXATTR_INIT        pthread_mutexattr_init
00094 #define _PT_PTHREAD_MUTEXATTR_DESTROY     pthread_mutexattr_destroy
00095 #define _PT_PTHREAD_MUTEX_INIT(m, a)      pthread_mutex_init(&(m), &(a))
00096 #if defined(FREEBSD)
00097 #define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    pt_pthread_mutex_is_locked(&(m))
00098 #else
00099 #define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (EBUSY == pthread_mutex_trylock(&(m)))
00100 #endif
00101 #if defined(DARWIN)
00102 #define _PT_PTHREAD_CONDATTR_INIT(x)      0
00103 #else
00104 #define _PT_PTHREAD_CONDATTR_INIT         pthread_condattr_init
00105 #endif
00106 #define _PT_PTHREAD_CONDATTR_DESTROY      pthread_condattr_destroy
00107 #define _PT_PTHREAD_COND_INIT(m, a)       pthread_cond_init(&(m), &(a))
00108 #endif
00109 
00110 /* The pthreads standard does not specify an invalid value for the
00111  * pthread_t handle.  (0 is usually an invalid pthread identifier
00112  * but there are exceptions, for example, DG/UX.)  These macros
00113  * define a way to set the handle to or compare the handle with an
00114  * invalid identifier.  These macros are not portable and may be
00115  * more of a problem as we adapt to more pthreads implementations.
00116  * They are only used in the PRMonitor functions.  Do not use them
00117  * in new code.
00118  *
00119  * Unfortunately some of our clients depend on certain properties
00120  * of our PRMonitor implementation, preventing us from replacing
00121  * it by a portable implementation.
00122  * - High-performance servers like the fact that PR_EnterMonitor
00123  *   only calls PR_Lock and PR_ExitMonitor only calls PR_Unlock.
00124  *   (A portable implementation would use a PRLock and a PRCondVar
00125  *   to implement the recursive lock in a monitor and call both
00126  *   PR_Lock and PR_Unlock in PR_EnterMonitor and PR_ExitMonitor.)
00127  *   Unfortunately this forces us to read the monitor owner field
00128  *   without holding a lock.
00129  * - One way to make it safe to read the monitor owner field
00130  *   without holding a lock is to make that field a PRThread*
00131  *   (one should be able to read a pointer with a single machine
00132  *   instruction).  However, PR_GetCurrentThread calls calloc if
00133  *   it is called by a thread that was not created by NSPR.  The
00134  *   malloc tracing tools in the Mozilla client use PRMonitor for
00135  *   locking in their malloc, calloc, and free functions.  If
00136  *   PR_EnterMonitor calls any of these functions, infinite
00137  *   recursion ensues.
00138  */
00139 #if defined(_PR_DCETHREADS)
00140 #define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) \
00141        memset(&(t), 0, sizeof(pthread_t))
00142 #define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) \
00143        (!memcmp(&(t), &pt_zero_tid, sizeof(pthread_t)))
00144 #define _PT_PTHREAD_COPY_THR_HANDLE(st, dt)   (dt) = (st)
00145 #elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(SOLARIS) \
00146        || defined(HPUX) || defined(LINUX) || defined(FREEBSD) \
00147        || defined(NETBSD) || defined(OPENBSD) || defined(BSDI) \
00148        || defined(VMS) || defined(NTO) || defined(DARWIN) \
00149        || defined(UNIXWARE) || defined(RISCOS)
00150 #define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t)  (t) = 0
00151 #define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t)  (t) == 0
00152 #define _PT_PTHREAD_COPY_THR_HANDLE(st, dt)   (dt) = (st)
00153 #else 
00154 #error "pthreads is not supported for this architecture"
00155 #endif
00156 
00157 #if defined(_PR_DCETHREADS)
00158 #define _PT_PTHREAD_ATTR_INIT            pthread_attr_create
00159 #define _PT_PTHREAD_ATTR_DESTROY         pthread_attr_delete
00160 #define _PT_PTHREAD_CREATE(t, a, f, r)   pthread_create(t, a, f, r) 
00161 #define _PT_PTHREAD_KEY_CREATE           pthread_keycreate
00162 #define _PT_PTHREAD_ATTR_SETSCHEDPOLICY  pthread_attr_setsched
00163 #define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) \
00164                                      (*(s) = pthread_attr_getstacksize(*(a)), 0)
00165 #define _PT_PTHREAD_GETSPECIFIC(k, r) \
00166               pthread_getspecific((k), (pthread_addr_t *) &(r))
00167 #elif defined(_PR_PTHREADS)
00168 #define _PT_PTHREAD_ATTR_INIT            pthread_attr_init
00169 #define _PT_PTHREAD_ATTR_DESTROY         pthread_attr_destroy
00170 #define _PT_PTHREAD_CREATE(t, a, f, r)   pthread_create(t, &a, f, r) 
00171 #define _PT_PTHREAD_KEY_CREATE           pthread_key_create
00172 #define _PT_PTHREAD_ATTR_SETSCHEDPOLICY  pthread_attr_setschedpolicy
00173 #define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) pthread_attr_getstacksize(a, s)
00174 #define _PT_PTHREAD_GETSPECIFIC(k, r)    (r) = pthread_getspecific(k)
00175 #else
00176 #error "Cannot determine pthread strategy"
00177 #endif
00178 
00179 #if defined(_PR_DCETHREADS)
00180 #define _PT_PTHREAD_EXPLICIT_SCHED      _PT_PTHREAD_DEFAULT_SCHED
00181 #endif
00182 
00183 /*
00184  * pthread_mutex_trylock returns different values in DCE threads and
00185  * pthreads.
00186  */
00187 #if defined(_PR_DCETHREADS)
00188 #define PT_TRYLOCK_SUCCESS 1
00189 #define PT_TRYLOCK_BUSY    0
00190 #else
00191 #define PT_TRYLOCK_SUCCESS 0
00192 #define PT_TRYLOCK_BUSY    EBUSY
00193 #endif
00194 
00195 /*
00196  * These platforms don't have sigtimedwait()
00197  */
00198 #if (defined(AIX) && !defined(AIX4_3_PLUS)) || defined(LINUX) \
00199        || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
00200        || defined(BSDI) || defined(VMS) || defined(UNIXWARE) \
00201        || defined(DARWIN)
00202 #define PT_NO_SIGTIMEDWAIT
00203 #endif
00204 
00205 #if defined(OSF1) || defined(VMS)
00206 #define PT_PRIO_MIN            PRI_OTHER_MIN
00207 #define PT_PRIO_MAX            PRI_OTHER_MAX
00208 #elif defined(IRIX)
00209 #include <sys/sched.h>
00210 #define PT_PRIO_MIN            PX_PRIO_MIN
00211 #define PT_PRIO_MAX            PX_PRIO_MAX
00212 #elif defined(AIX)
00213 #include <sys/priv.h>
00214 #include <sys/sched.h>
00215 #ifndef PTHREAD_CREATE_JOINABLE
00216 #define PTHREAD_CREATE_JOINABLE     PTHREAD_CREATE_UNDETACHED
00217 #endif
00218 #define PT_PRIO_MIN            DEFAULT_PRIO
00219 #define PT_PRIO_MAX            DEFAULT_PRIO
00220 #elif defined(HPUX)
00221 
00222 #if defined(_PR_DCETHREADS)
00223 #define PT_PRIO_MIN            PRI_OTHER_MIN
00224 #define PT_PRIO_MAX            PRI_OTHER_MAX
00225 #else /* defined(_PR_DCETHREADS) */
00226 #include <sys/sched.h>
00227 #define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
00228 #define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
00229 #endif /* defined(_PR_DCETHREADS) */
00230 
00231 #elif defined(LINUX) || defined(FREEBSD)
00232 #define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
00233 #define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
00234 #elif defined(NTO)
00235 /*
00236  * Neutrino has functions that return the priority range but
00237  * they return invalid numbers, so I just hard coded these here
00238  * for now.  Jerry.Kirk@Nexarecorp.com
00239  */
00240 #define PT_PRIO_MIN            0
00241 #define PT_PRIO_MAX            30
00242 #elif defined(SOLARIS)
00243 /*
00244  * Solaris doesn't seem to have macros for the min/max priorities.
00245  * The range of 0-127 is mentioned in the pthread_setschedparam(3T)
00246  * man pages, and pthread_setschedparam indeed allows 0-127.  However,
00247  * pthread_attr_setschedparam does not allow 0; it allows 1-127.
00248  */
00249 #define PT_PRIO_MIN            1
00250 #define PT_PRIO_MAX            127
00251 #elif defined(OPENBSD)
00252 #define PT_PRIO_MIN            0
00253 #define PT_PRIO_MAX            31
00254 #elif defined(NETBSD) \
00255        || defined(BSDI) || defined(DARWIN) || defined(UNIXWARE) \
00256        || defined(RISCOS) /* XXX */
00257 #define PT_PRIO_MIN            0
00258 #define PT_PRIO_MAX            126
00259 #else
00260 #error "pthreads is not supported for this architecture"
00261 #endif
00262 
00263 /*
00264  * The _PT_PTHREAD_YIELD function is called from a signal handler.
00265  * Needed for garbage collection -- Look at PR_Suspend/PR_Resume
00266  * implementation.
00267  */
00268 #if defined(_PR_DCETHREADS)
00269 #define _PT_PTHREAD_YIELD()               pthread_yield()
00270 #elif defined(OSF1) || defined(VMS)
00271 /*
00272  * sched_yield can't be called from a signal handler.  Must use
00273  * the _np version.
00274  */
00275 #define _PT_PTHREAD_YIELD()               pthread_yield_np()
00276 #elif defined(AIX)
00277 extern int (*_PT_aix_yield_fcn)();
00278 #define _PT_PTHREAD_YIELD()               (*_PT_aix_yield_fcn)()
00279 #elif defined(IRIX)
00280 #include <time.h>
00281 #define _PT_PTHREAD_YIELD() \
00282     PR_BEGIN_MACRO                                      \
00283               struct timespec onemillisec = {0};        \
00284               onemillisec.tv_nsec = 1000000L;                  \
00285         nanosleep(&onemillisec,NULL);                   \
00286     PR_END_MACRO
00287 #elif defined(HPUX) || defined(LINUX) || defined(SOLARIS) \
00288        || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
00289        || defined(BSDI) || defined(NTO) || defined(DARWIN) \
00290        || defined(UNIXWARE) || defined(RISCOS)
00291 #define _PT_PTHREAD_YIELD()               sched_yield()
00292 #else
00293 #error "Need to define _PT_PTHREAD_YIELD for this platform"
00294 #endif
00295 
00296 #endif /* nspr_pth_defs_h_ */