nsprpub/pr/include/private/primpl.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     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/. */
     6 #ifndef primpl_h___
     7 #define primpl_h___
     9 /*
    10  * HP-UX 10.10's pthread.h (DCE threads) includes dce/cma.h, which
    11  * has:
    12  *     #define sigaction _sigaction_sys
    13  * This macro causes chaos if signal.h gets included before pthread.h.
    14  * To be safe, we include pthread.h first.
    15  */
    17 #if defined(_PR_PTHREADS)
    18 #include <pthread.h>
    19 #endif
    21 #if defined(_PR_BTHREADS)
    22 #include <kernel/OS.h>
    23 #endif
    25 #ifdef WIN32
    26 /*
    27  * Allow use of functions and symbols first defined in Win2k.
    28  */
    29 #if !defined(WINVER) || (WINVER < 0x0500)
    30 #undef WINVER
    31 #define WINVER 0x0500
    32 #endif
    33 #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
    34 #undef _WIN32_WINNT
    35 #define _WIN32_WINNT 0x0500
    36 #endif
    37 #endif /* WIN32 */
    39 #include "nspr.h"
    40 #include "prpriv.h"
    42 typedef struct PRSegment PRSegment;
    44 #include "md/prosdep.h"
    45 #include "obsolete/probslet.h"
    47 #ifdef _PR_HAVE_POSIX_SEMAPHORES
    48 #include <semaphore.h>
    49 #elif defined(_PR_HAVE_SYSV_SEMAPHORES)
    50 #include <sys/sem.h>
    51 #endif
    53 #ifdef HAVE_SYSCALL
    54 #include <sys/syscall.h>
    55 #endif
    57 /*************************************************************************
    58 *****  A Word about Model Dependent Function Naming Convention ***********
    59 *************************************************************************/
    61 /*
    62 NSPR 2.0 must implement its function across a range of platforms 
    63 including: MAC, Windows/16, Windows/95, Windows/NT, and several
    64 variants of Unix. Each implementation shares common code as well 
    65 as having platform dependent portions. This standard describes how
    66 the model dependent portions are to be implemented.
    68 In header file pr/include/primpl.h, each publicly declared 
    69 platform dependent function is declared as:
    71 NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 );
    72 #define _PR_MD_FUNCTION _MD_FUNCTION
    74 In header file pr/include/md/<platform>/_<platform>.h, 
    75 each #define'd macro is redefined as one of:
    77 #define _MD_FUNCTION <blanks>
    78 #define _MD_FUNCTION <expanded macro>
    79 #define _MD_FUNCTION <osFunction>
    80 #define _MD_FUNCTION <_MD_Function>
    82 Where:
    84 <blanks> is no definition at all. In this case, the function is not implemented 
    85 and is never called for this platform. 
    86 For example: 
    87 #define _MD_INIT_CPUS()
    89 <expanded macro> is a C language macro expansion. 
    90 For example: 
    91 #define        _MD_CLEAN_THREAD(_thread) \
    92     PR_BEGIN_MACRO \
    93         PR_DestroyCondVar(_thread->md.asyncIOCVar); \
    94         PR_DestroyLock(_thread->md.asyncIOLock); \
    95     PR_END_MACRO
    97 <osFunction> is some function implemented by the host operating system. 
    98 For example: 
    99 #define _MD_EXIT        exit
   101 <_MD_function> is the name of a function implemented for this platform in 
   102 pr/src/md/<platform>/<soruce>.c file. 
   103 For example: 
   104 #define        _MD_GETFILEINFO         _MD_GetFileInfo
   106 In <source>.c, the implementation is:
   107 PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info);
   108 */
   110 PR_BEGIN_EXTERN_C
   112 typedef struct _MDLock _MDLock;
   113 typedef struct _MDCVar _MDCVar;
   114 typedef struct _MDSegment _MDSegment;
   115 typedef struct _MDThread _MDThread;
   116 typedef struct _MDThreadStack _MDThreadStack;
   117 typedef struct _MDSemaphore _MDSemaphore;
   118 typedef struct _MDDir _MDDir;
   119 #ifdef MOZ_UNICODE
   120 typedef struct _MDDirUTF16 _MDDirUTF16;
   121 #endif /* MOZ_UNICODE */
   122 typedef struct _MDFileDesc _MDFileDesc;
   123 typedef struct _MDProcess _MDProcess;
   124 typedef struct _MDFileMap _MDFileMap;
   126 #if defined(_PR_PTHREADS)
   128 /*
   129 ** The following definitions are unique to implementing NSPR using pthreads.
   130 ** Since pthreads defines most of the thread and thread synchronization
   131 ** stuff, this is a pretty small set.
   132 */
   134 #define PT_CV_NOTIFIED_LENGTH 6
   135 typedef struct _PT_Notified _PT_Notified;
   136 struct _PT_Notified
   137 {
   138     PRIntn length;              /* # of used entries in this structure */
   139     struct
   140     {
   141         PRCondVar *cv;          /* the condition variable notified */
   142         PRIntn times;           /* and the number of times notified */
   143     } cv[PT_CV_NOTIFIED_LENGTH];
   144     _PT_Notified *link;         /* link to another of these | NULL */
   145 };
   147 /*
   148  * bits defined for pthreads 'state' field 
   149  */
   150 #define PT_THREAD_DETACHED  0x01    /* thread can't be joined */
   151 #define PT_THREAD_GLOBAL    0x02    /* a global thread (unlikely) */
   152 #define PT_THREAD_SYSTEM    0x04    /* system (not user) thread */
   153 #define PT_THREAD_PRIMORD   0x08    /* this is the primordial thread */
   154 #define PT_THREAD_ABORTED   0x10    /* thread has been interrupted */
   155 #define PT_THREAD_GCABLE    0x20    /* thread is garbage collectible */
   156 #define PT_THREAD_SUSPENDED 0x40    /* thread has been suspended */
   157 #define PT_THREAD_FOREIGN   0x80    /* thread is not one of ours */
   158 #define PT_THREAD_BOUND     0x100    /* a bound-global thread */
   160 #define _PT_THREAD_INTERRUPTED(thr)					\
   161 		(!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED))
   162 #define _PT_THREAD_BLOCK_INTERRUPT(thr)				\
   163 		(thr->interrupt_blocked = 1)
   164 #define _PT_THREAD_UNBLOCK_INTERRUPT(thr)			\
   165 		(thr->interrupt_blocked = 0)
   167 #define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE)
   169 /* 
   170 ** Possible values for thread's suspend field
   171 ** Note that the first two can be the same as they are really mutually exclusive,
   172 ** i.e. both cannot be happening at the same time. We have two symbolic names
   173 ** just as a mnemonic.
   174 **/
   175 #define PT_THREAD_RESUMED   0x80    /* thread has been resumed */
   176 #define PT_THREAD_SETGCABLE 0x100   /* set the GCAble flag */
   178 #if defined(DEBUG)
   180 typedef struct PTDebug
   181 {
   182     PRTime timeStarted;
   183     PRUintn locks_created, locks_destroyed;
   184     PRUintn locks_acquired, locks_released;
   185     PRUintn cvars_created, cvars_destroyed;
   186     PRUintn cvars_notified, delayed_cv_deletes;
   187 } PTDebug;
   189 #endif /* defined(DEBUG) */
   191 NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
   193 /*
   194  * On Linux and its derivatives POSIX priority scheduling works only for
   195  * real-time threads. On those platforms we set thread's nice values
   196  * instead which requires us to track kernel thread IDs for each POSIX
   197  * thread we create.
   198  */
   199 #if defined(LINUX) && defined(HAVE_SETPRIORITY) && \
   200     ((defined(HAVE_SYSCALL) && defined(SYS_gettid)) || defined(HAVE_GETTID))
   201 #define _PR_NICE_PRIORITY_SCHEDULING
   202 #endif
   204 #else /* defined(_PR_PTHREADS) */
   206 NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
   208 /*
   209 ** This section is contains those parts needed to implement NSPR on
   210 ** platforms in general. One would assume that the pthreads implementation
   211 ** included lots of the same types, at least conceptually.
   212 */
   214 /*
   215  * Local threads only.  No multiple CPU support and hence all the
   216  * following routines are no-op.
   217  */
   218 #ifdef _PR_LOCAL_THREADS_ONLY
   220 #define        _PR_MD_SUSPEND_THREAD(thread)        
   221 #define        _PR_MD_RESUME_THREAD(thread)        
   222 #define        _PR_MD_SUSPEND_CPU(cpu)        
   223 #define        _PR_MD_RESUME_CPU(cpu)        
   224 #define        _PR_MD_BEGIN_SUSPEND_ALL()        
   225 #define        _PR_MD_END_SUSPEND_ALL()        
   226 #define        _PR_MD_BEGIN_RESUME_ALL()        
   227 #define        _PR_MD_END_RESUME_ALL()
   228 #define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE
   230 #endif
   232 typedef struct _PRCPUQueue _PRCPUQueue;
   233 typedef struct _PRCPU _PRCPU;
   234 typedef struct _MDCPU _MDCPU;
   236 struct _PRCPUQueue {
   237     _MDLock  runQLock;          /* lock for the run + wait queues */
   238     _MDLock  sleepQLock;        /* lock for the run + wait queues */
   239     _MDLock  miscQLock;         /* lock for the run + wait queues */
   241     PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */
   242     PRUint32  runQReadyMask;
   243     PRCList sleepQ;
   244     PRIntervalTime sleepQmax;
   245     PRCList pauseQ;
   246     PRCList suspendQ;
   247     PRCList waitingToJoinQ;
   249     PRUintn   numCPUs;          /* number of CPUs using this Q */
   250 };
   252 struct _PRCPU {
   253     PRCList links;              /* link list of CPUs */
   254     PRUint32 id;                /* id for this CPU */
   256     union {
   257         PRInt32 bits;
   258         PRUint8 missed[4];
   259     } u;
   260     PRIntn where;               /* index into u.missed */
   261     PRPackedBool paused;        /* cpu is paused */
   262     PRPackedBool exit;          /* cpu should exit */
   264     PRThread *thread;           /* native thread for this CPUThread */
   265     PRThread *idle_thread;      /* user-level idle thread for this CPUThread */
   267     PRIntervalTime last_clock;  /* the last time we went into 
   268                                  * _PR_ClockInterrupt() on this CPU
   269                                  */
   271     _PRCPUQueue *queue;
   273     _MDCPU md;
   274 };
   276 typedef struct _PRInterruptTable {
   277     const char *name;
   278     PRUintn missed_bit;
   279     void (*handler)(void);
   280 } _PRInterruptTable;
   282 #define _PR_CPU_PTR(_qp) \
   283     ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links)))
   285 #if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \
   286         && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY))
   287 #define _MD_GET_ATTACHED_THREAD()        (_PR_MD_CURRENT_THREAD())
   288 #endif
   290 #ifdef _PR_LOCAL_THREADS_ONLY 
   292 NSPR_API(struct _PRCPU *)              _pr_currentCPU;
   293 NSPR_API(PRThread *)                   _pr_currentThread;
   294 NSPR_API(PRThread *)                   _pr_lastThread;
   295 NSPR_API(PRInt32)                      _pr_intsOff;
   297 #define _MD_CURRENT_CPU()               (_pr_currentCPU)
   298 #define _MD_SET_CURRENT_CPU(_cpu)       (_pr_currentCPU = (_cpu))
   299 #define _MD_CURRENT_THREAD()            (_pr_currentThread)
   300 #define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
   301 #define _MD_LAST_THREAD()               (_pr_lastThread)
   302 #define _MD_SET_LAST_THREAD(t)          (_pr_lastThread = t)
   304 #define _MD_GET_INTSOFF()               (_pr_intsOff)
   305 #define _MD_SET_INTSOFF(_val)           (_pr_intsOff = _val)
   308 /* The unbalanced curly braces in these two macros are intentional */
   309 #define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is);
   310 #define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); }
   312 #endif /* _PR_LOCAL_THREADS_ONLY */
   314 extern PRInt32                  _native_threads_only;
   316 #if defined(_PR_GLOBAL_THREADS_ONLY)
   318 #define _MD_GET_INTSOFF() 0
   319 #define _MD_SET_INTSOFF(_val)
   320 #define _PR_INTSOFF(_is)
   321 #define _PR_FAST_INTSON(_is)
   322 #define _PR_INTSON(_is)
   323 #define _PR_THREAD_LOCK(_thread)
   324 #define _PR_THREAD_UNLOCK(_thread)
   325 #define _PR_RUNQ_LOCK(cpu)
   326 #define _PR_RUNQ_UNLOCK(cpu)
   327 #define _PR_SLEEPQ_LOCK(thread)
   328 #define _PR_SLEEPQ_UNLOCK(thread)
   329 #define _PR_MISCQ_LOCK(thread)
   330 #define _PR_MISCQ_UNLOCK(thread)
   331 #define _PR_CPU_LIST_LOCK()
   332 #define _PR_CPU_LIST_UNLOCK()
   334 #define _PR_ADD_RUNQ(_thread, _cpu, _pri)
   335 #define _PR_DEL_RUNQ(_thread)
   336 #define _PR_ADD_SLEEPQ(_thread, _timeout)
   337 #define _PR_DEL_SLEEPQ(_thread, _propogate)
   338 #define _PR_ADD_JOINQ(_thread, _cpu)
   339 #define _PR_DEL_JOINQ(_thread)
   340 #define _PR_ADD_SUSPENDQ(_thread, _cpu)
   341 #define _PR_DEL_SUSPENDQ(_thread)
   343 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
   345 #define _PR_IS_NATIVE_THREAD(thread) 1
   346 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
   348 #else
   350 #define _PR_INTSOFF(_is) \
   351     PR_BEGIN_MACRO \
   352         (_is) = _PR_MD_GET_INTSOFF(); \
   353         _PR_MD_SET_INTSOFF(1); \
   354     PR_END_MACRO
   356 #define _PR_FAST_INTSON(_is) \
   357     PR_BEGIN_MACRO \
   358         _PR_MD_SET_INTSOFF(_is); \
   359     PR_END_MACRO
   361 #define _PR_INTSON(_is) \
   362     PR_BEGIN_MACRO \
   363         if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \
   364                 _PR_IntsOn((_PR_MD_CURRENT_CPU())); \
   365         _PR_MD_SET_INTSOFF(_is); \
   366     PR_END_MACRO
   368 #ifdef _PR_LOCAL_THREADS_ONLY 
   370 #define _PR_IS_NATIVE_THREAD(thread) 0
   371 #define _PR_THREAD_LOCK(_thread)
   372 #define _PR_THREAD_UNLOCK(_thread)
   373 #define _PR_RUNQ_LOCK(cpu)
   374 #define _PR_RUNQ_UNLOCK(cpu)
   375 #define _PR_SLEEPQ_LOCK(thread)
   376 #define _PR_SLEEPQ_UNLOCK(thread)
   377 #define _PR_MISCQ_LOCK(thread)
   378 #define _PR_MISCQ_UNLOCK(thread)
   379 #define _PR_CPU_LIST_LOCK()
   380 #define _PR_CPU_LIST_UNLOCK()
   382 #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
   383     PR_BEGIN_MACRO \
   384     PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
   385     _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
   386     PR_END_MACRO
   388 #define _PR_DEL_RUNQ(_thread) \
   389     PR_BEGIN_MACRO \
   390     _PRCPU *_cpu = _thread->cpu; \
   391     PRInt32 _pri = _thread->priority; \
   392     PR_REMOVE_LINK(&(_thread)->links); \
   393     if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
   394         _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
   395     PR_END_MACRO
   397 #define _PR_ADD_SLEEPQ(_thread, _timeout) \
   398     _PR_AddSleepQ(_thread, _timeout);   
   400 #define _PR_DEL_SLEEPQ(_thread, _propogate) \
   401     _PR_DelSleepQ(_thread, _propogate);  
   403 #define _PR_ADD_JOINQ(_thread, _cpu) \
   404     PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
   406 #define _PR_DEL_JOINQ(_thread) \
   407     PR_REMOVE_LINK(&(_thread)->links);
   409 #define _PR_ADD_SUSPENDQ(_thread, _cpu) \
   410     PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
   412 #define _PR_DEL_SUSPENDQ(_thread) \
   413     PR_REMOVE_LINK(&(_thread)->links);
   415 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
   417 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 0
   419 #else        /* _PR_LOCAL_THREADS_ONLY */
   421 /* These are for the "combined" thread model */
   423 #define _PR_THREAD_LOCK(_thread) \
   424     _PR_MD_LOCK(&(_thread)->threadLock);
   426 #define _PR_THREAD_UNLOCK(_thread) \
   427     _PR_MD_UNLOCK(&(_thread)->threadLock);
   429 #define _PR_RUNQ_LOCK(_cpu) \
   430     PR_BEGIN_MACRO \
   431     _PR_MD_LOCK(&(_cpu)->queue->runQLock );\
   432     PR_END_MACRO
   434 #define _PR_RUNQ_UNLOCK(_cpu) \
   435     PR_BEGIN_MACRO \
   436     _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\
   437     PR_END_MACRO
   439 #define _PR_SLEEPQ_LOCK(_cpu) \
   440     _PR_MD_LOCK(&(_cpu)->queue->sleepQLock );
   442 #define _PR_SLEEPQ_UNLOCK(_cpu) \
   443     _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock );
   445 #define _PR_MISCQ_LOCK(_cpu) \
   446     _PR_MD_LOCK(&(_cpu)->queue->miscQLock );
   448 #define _PR_MISCQ_UNLOCK(_cpu) \
   449     _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock );
   451 #define _PR_CPU_LIST_LOCK()                 _PR_MD_LOCK(&_pr_cpuLock)
   452 #define _PR_CPU_LIST_UNLOCK()               _PR_MD_UNLOCK(&_pr_cpuLock)
   454 #define QUEUE_RUN           0x1
   455 #define QUEUE_SLEEP         0x2
   456 #define QUEUE_JOIN          0x4
   457 #define QUEUE_SUSPEND       0x8
   458 #define QUEUE_LOCK          0x10
   460 #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
   461     PR_BEGIN_MACRO \
   462     PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
   463     _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
   464     PR_ASSERT((_thread)->queueCount == 0); \
   465     (_thread)->queueCount = QUEUE_RUN; \
   466     PR_END_MACRO
   468 #define _PR_DEL_RUNQ(_thread) \
   469     PR_BEGIN_MACRO \
   470     _PRCPU *_cpu = _thread->cpu; \
   471     PRInt32 _pri = _thread->priority; \
   472     PR_REMOVE_LINK(&(_thread)->links); \
   473     if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
   474         _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
   475     PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\
   476     (_thread)->queueCount = 0; \
   477     PR_END_MACRO
   479 #define _PR_ADD_SLEEPQ(_thread, _timeout) \
   480     PR_ASSERT((_thread)->queueCount == 0); \
   481     (_thread)->queueCount = QUEUE_SLEEP; \
   482     _PR_AddSleepQ(_thread, _timeout);  
   484 #define _PR_DEL_SLEEPQ(_thread, _propogate) \
   485     PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\
   486     (_thread)->queueCount = 0; \
   487     _PR_DelSleepQ(_thread, _propogate);  
   489 #define _PR_ADD_JOINQ(_thread, _cpu) \
   490     PR_ASSERT((_thread)->queueCount == 0); \
   491     (_thread)->queueCount = QUEUE_JOIN; \
   492     PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
   494 #define _PR_DEL_JOINQ(_thread) \
   495     PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\
   496     (_thread)->queueCount = 0; \
   497     PR_REMOVE_LINK(&(_thread)->links);
   499 #define _PR_ADD_SUSPENDQ(_thread, _cpu) \
   500     PR_ASSERT((_thread)->queueCount == 0); \
   501     (_thread)->queueCount = QUEUE_SUSPEND; \
   502     PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
   504 #define _PR_DEL_SUSPENDQ(_thread) \
   505     PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\
   506     (_thread)->queueCount = 0; \
   507     PR_REMOVE_LINK(&(_thread)->links);
   509 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \
   510     (_thread)->cpu = (_newCPU);
   512 #define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE)
   513 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
   515 #endif /* _PR_LOCAL_THREADS_ONLY */
   517 #endif /* _PR_GLOBAL_THREADS_ONLY */
   519 #define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1
   520 #define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0
   522 extern _PRInterruptTable _pr_interruptTable[];
   524 /* Bits for _pr_interruptState.u.missed[0,1] */
   525 #define _PR_MISSED_CLOCK    0x1
   526 #define _PR_MISSED_IO        0x2
   527 #define _PR_MISSED_CHILD    0x4
   529 extern void _PR_IntsOn(_PRCPU *cpu);
   531 NSPR_API(void) _PR_WakeupCPU(void);
   532 NSPR_API(void) _PR_PauseCPU(void);
   534 /************************************************************************/
   536 #define _PR_LOCK_LOCK(_lock) \
   537     _PR_MD_LOCK(&(_lock)->ilock);
   538 #define _PR_LOCK_UNLOCK(_lock) \
   539     _PR_MD_UNLOCK(&(_lock)->ilock);
   541 extern void _PR_UnblockLockWaiter(PRLock *lock);
   542 extern PRStatus _PR_InitLock(PRLock *lock);
   543 extern void _PR_FreeLock(PRLock *lock);
   545 #define _PR_LOCK_PTR(_qp) \
   546     ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links)))
   548 /************************************************************************/
   550 #define _PR_CVAR_LOCK(_cvar) \
   551     _PR_MD_LOCK(&(_cvar)->ilock); 
   552 #define _PR_CVAR_UNLOCK(_cvar) \
   553     _PR_MD_UNLOCK(&(_cvar)->ilock);
   555 extern PRStatus _PR_InitCondVar(PRCondVar *cvar, PRLock *lock);
   556 extern void _PR_FreeCondVar(PRCondVar *cvar);
   557 extern PRStatus _PR_WaitCondVar(
   558     PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
   559 extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me);
   560 extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
   562 NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky);
   564 /* PRThread.flags */
   565 #define _PR_SYSTEM          0x01
   566 #define _PR_INTERRUPT       0x02
   567 #define _PR_ATTACHED        0x04        /* created via PR_AttachThread */
   568 #define _PR_PRIMORDIAL      0x08        /* the thread that called PR_Init */
   569 #define _PR_ON_SLEEPQ       0x10        /* thread is on the sleepQ */
   570 #define _PR_ON_PAUSEQ       0x20        /* thread is on the pauseQ */
   571 #define _PR_SUSPENDING      0x40        /* thread wants to suspend */
   572 #define _PR_GLOBAL_SCOPE    0x80        /* thread is global scope */
   573 #define _PR_IDLE_THREAD     0x200       /* this is an idle thread        */
   574 #define _PR_GCABLE_THREAD   0x400       /* this is a collectable thread */
   575 #define _PR_BOUND_THREAD    0x800       /* a bound thread */
   576 #define _PR_INTERRUPT_BLOCKED	0x1000	/* interrupts blocked */
   578 /* PRThread.state */
   579 #define _PR_UNBORN       0
   580 #define _PR_RUNNABLE     1
   581 #define _PR_RUNNING      2
   582 #define _PR_LOCK_WAIT    3
   583 #define _PR_COND_WAIT    4
   584 #define _PR_JOIN_WAIT    5
   585 #define _PR_IO_WAIT      6
   586 #define _PR_SUSPENDED    7
   587 #define _PR_DEAD_STATE   8  /* for debugging */
   589 /* PRThreadStack.flags */
   590 #define _PR_STACK_VM            0x1    /* using vm instead of malloc */
   591 #define _PR_STACK_MAPPED        0x2    /* vm is mapped */
   592 #define _PR_STACK_PRIMORDIAL    0x4    /* stack for primordial thread */
   594 /* 
   595 ** If the default stcksize from the client is zero, we need to pick a machine
   596 ** dependent value.  This is only for standard user threads.  For custom threads,
   597 ** 0 has a special meaning.
   598 ** Adjust stackSize. Round up to a page boundary.
   599 */
   601 #ifndef _MD_MINIMUM_STACK_SIZE
   602 #define _MD_MINIMUM_STACK_SIZE	0
   603 #endif
   605 #if (!defined(HAVE_CUSTOM_USER_THREADS))
   606 #define        _PR_ADJUST_STACKSIZE(stackSize) \
   607         PR_BEGIN_MACRO \
   608     if (stackSize == 0) \
   609                 stackSize = _MD_DEFAULT_STACK_SIZE; \
   610     if (stackSize < _MD_MINIMUM_STACK_SIZE) \
   611                 stackSize = _MD_MINIMUM_STACK_SIZE; \
   612     stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \
   613     stackSize <<= _pr_pageShift; \
   614         PR_END_MACRO
   615 #else
   616 #define        _PR_ADJUST_STACKSIZE(stackSize)
   617 #endif
   619 #define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD)
   621 #define _PR_PENDING_INTERRUPT(thr)					\
   622 		(!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_INTERRUPT))
   623 #define _PR_THREAD_BLOCK_INTERRUPT(thr)			\
   624 		(thr->flags |= _PR_INTERRUPT_BLOCKED)
   625 #define _PR_THREAD_UNBLOCK_INTERRUPT(thr)			\
   626 		(thr->flags &= ~_PR_INTERRUPT_BLOCKED)
   628 #define _PR_THREAD_PTR(_qp) \
   629     ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links)))
   631 #define _PR_ACTIVE_THREAD_PTR(_qp) \
   632     ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active)))
   634 #define _PR_THREAD_CONDQ_PTR(_qp) \
   635     ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks)))
   637 #define _PR_THREAD_MD_TO_PTR(_md) \
   638     ((PRThread*) ((char*) (_md) - offsetof(PRThread,md)))
   640 #define _PR_THREAD_STACK_TO_PTR(_stack) \
   641     ((PRThread*) (_stack->thr))
   643 extern PRCList _pr_active_local_threadQ;
   644 extern PRCList _pr_active_global_threadQ;
   645 extern PRCList _pr_cpuQ;
   646 extern _MDLock  _pr_cpuLock;
   647 extern PRInt32 _pr_md_idle_cpus;
   649 #define _PR_ACTIVE_LOCAL_THREADQ()          _pr_active_local_threadQ
   650 #define _PR_ACTIVE_GLOBAL_THREADQ()         _pr_active_global_threadQ
   651 #define _PR_CPUQ()                          _pr_cpuQ
   652 #define _PR_RUNQ(_cpu)                      ((_cpu)->queue->runQ)
   653 #define _PR_RUNQREADYMASK(_cpu)             ((_cpu)->queue->runQReadyMask)
   654 #define _PR_SLEEPQ(_cpu)                    ((_cpu)->queue->sleepQ)
   655 #define _PR_SLEEPQMAX(_cpu)                 ((_cpu)->queue->sleepQmax)
   656 #define _PR_PAUSEQ(_cpu)                    ((_cpu)->queue->pauseQ)
   657 #define _PR_SUSPENDQ(_cpu)                  ((_cpu)->queue->suspendQ)
   658 #define _PR_WAITINGTOJOINQ(_cpu)            ((_cpu)->queue->waitingToJoinQ)
   660 extern PRUint32 _pr_recycleThreads;   /* Flag for behavior on thread cleanup */
   661 extern PRLock *_pr_deadQLock;
   662 extern PRUint32 _pr_numNativeDead;
   663 extern PRUint32 _pr_numUserDead;
   664 extern PRCList _pr_deadNativeQ;
   665 extern PRCList _pr_deadUserQ;
   666 #define _PR_DEADNATIVEQ     _pr_deadNativeQ
   667 #define _PR_DEADUSERQ       _pr_deadUserQ
   668 #define _PR_DEADQ_LOCK      PR_Lock(_pr_deadQLock);
   669 #define _PR_DEADQ_UNLOCK    PR_Unlock(_pr_deadQLock);
   670 #define _PR_INC_DEADNATIVE  (_pr_numNativeDead++)
   671 #define _PR_DEC_DEADNATIVE  (_pr_numNativeDead--)
   672 #define _PR_NUM_DEADNATIVE  (_pr_numNativeDead)
   673 #define _PR_INC_DEADUSER    (_pr_numUserDead++)
   674 #define _PR_DEC_DEADUSER    (_pr_numUserDead--)
   675 #define _PR_NUM_DEADUSER    (_pr_numUserDead)
   677 extern PRUint32 _pr_utid;
   679 extern struct _PRCPU  *_pr_primordialCPU;
   681 extern PRLock *_pr_activeLock;          /* lock for userActive and systemActive */
   682 extern PRInt32 _pr_userActive;          /* number of active user threads */
   683 extern PRInt32 _pr_systemActive;        /* number of active system threads */
   684 extern PRInt32 _pr_primordialExitCount; /* number of user threads left
   685                                          * before the primordial thread
   686                                          * can exit.  */
   687 extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for
   688                                            * notifying the primordial thread
   689                                            * when all other user threads
   690                                            * have terminated.  */
   692 extern PRUintn _pr_maxPTDs;
   694 extern PRLock *_pr_terminationCVLock;
   696 /*************************************************************************
   697 * Internal routines either called by PR itself or from machine-dependent *
   698 * code.                                                                  *
   699 *************************************************************************/
   701 extern void _PR_ClockInterrupt(void);
   703 extern void _PR_Schedule(void);
   704 extern void _PR_SetThreadPriority(
   705     PRThread* thread, PRThreadPriority priority);
   707 /***********************************************************************
   708 ** FUNCTION:	_PR_NewSegment()
   709 ** DESCRIPTION:
   710 **   Allocate a memory segment. The "size" value is rounded up to the
   711 **   native system page size and a page aligned portion of memory is
   712 **   returned.  This memory is not part of the malloc heap. If "vaddr" is
   713 **   not NULL then PR tries to allocate the segment at the desired virtual
   714 **   address.
   715 ** INPUTS:	size:  size of the desired memory segment
   716 **          vaddr:  address at which the newly aquired segment is to be
   717 **                  mapped into memory.
   718 ** OUTPUTS:	a memory segment is allocated, a PRSegment is allocated
   719 ** RETURN:	pointer to PRSegment
   720 ***********************************************************************/
   721 extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr);
   723 /***********************************************************************
   724 ** FUNCTION:	_PR_DestroySegment()
   725 ** DESCRIPTION:
   726 **   The memory segment and the PRSegment are freed
   727 ** INPUTS:	seg:  pointer to PRSegment to be freed
   728 ** OUTPUTS:	the the PRSegment and its associated memory segment are freed
   729 ** RETURN:	void
   730 ***********************************************************************/
   731 extern void _PR_DestroySegment(PRSegment *seg);
   733 extern PRThreadStack * _PR_NewStack(PRUint32 stackSize);
   734 extern void _PR_FreeStack(PRThreadStack *stack);
   735 extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me);
   736 extern void _PR_NotifyLockedThread (PRThread *thread);
   738 NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout);
   739 NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time);
   741 extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread);
   743 NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type,
   744                                      void (*start)(void *arg),
   745                                      void *arg,
   746                                      PRThreadPriority priority,
   747                                      PRThreadScope scope,
   748                                      PRThreadState state,
   749                                      PRUint32 stackSize,
   750                      PRUint32 flags);
   752 extern void _PR_NativeDestroyThread(PRThread *thread);
   753 extern void _PR_UserDestroyThread(PRThread *thread);
   755 extern PRThread* _PRI_AttachThread(
   756     PRThreadType type, PRThreadPriority priority,
   757     PRThreadStack *stack, PRUint32 flags);
   759 extern void _PRI_DetachThread(void);
   762 #define _PR_IO_PENDING(_thread) ((_thread)->io_pending)
   764 NSPR_API(void) _PR_MD_INIT_CPUS();
   765 #define    _PR_MD_INIT_CPUS _MD_INIT_CPUS
   767 NSPR_API(void) _PR_MD_WAKEUP_CPUS();
   768 #define    _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS
   770 /* Interrupts related */
   772 NSPR_API(void) _PR_MD_START_INTERRUPTS(void);
   773 #define    _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS
   775 NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void);
   776 #define    _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS
   778 NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void);
   779 #define    _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS
   781 NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void);
   782 #define    _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS
   784 NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void);
   785 #define    _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS
   787 NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
   788 #define    _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS
   790 /* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
   791  * awaken a thread which is waiting on a lock or cvar.
   792  */
   793 extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
   794 #define    _PR_MD_WAIT _MD_WAIT
   796 extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *);
   797 #define    _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER
   799 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
   800 NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void);
   801 #define    _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT
   802 #endif
   804 /* Stack debugging */
   805 NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone);
   806 #define    _PR_MD_INIT_STACK _MD_INIT_STACK
   808 NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts);
   809 #define    _PR_MD_CLEAR_STACK _MD_CLEAR_STACK
   811 /* CPU related */
   812 NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void);
   813 #define    _PR_MD_GET_INTSOFF _MD_GET_INTSOFF
   815 NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val);
   816 #define    _PR_MD_SET_INTSOFF _MD_SET_INTSOFF
   818 NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void);
   819 #define    _PR_MD_CURRENT_CPU _MD_CURRENT_CPU
   821 NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu);
   822 #define    _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU
   824 NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
   825 #define    _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU
   827 /*
   828  * Returns the number of threads awoken or 0 if a timeout occurred;
   829  */
   830 extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
   831 #define    _PR_MD_PAUSE_CPU _MD_PAUSE_CPU
   833 extern void _PR_MD_CLEANUP_BEFORE_EXIT(void);
   834 #define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT
   836 extern void _PR_MD_EXIT(PRIntn status);
   837 #define    _PR_MD_EXIT _MD_EXIT
   839 /* Locks related */
   841 NSPR_API(void) _PR_MD_INIT_LOCKS(void);
   842 #define    _PR_MD_INIT_LOCKS _MD_INIT_LOCKS
   844 NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md);
   845 #define    _PR_MD_NEW_LOCK _MD_NEW_LOCK
   847 NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md);
   848 #define    _PR_MD_FREE_LOCK _MD_FREE_LOCK
   850 NSPR_API(void) _PR_MD_LOCK(_MDLock *md);
   851 #define    _PR_MD_LOCK _MD_LOCK
   853 /* Return 0 on success, a nonzero value on failure. */
   854 NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md);
   855 #define    _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK
   857 NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md);
   858 #define    _PR_MD_UNLOCK _MD_UNLOCK
   860 NSPR_API(void) _PR_MD_IOQ_LOCK(void);
   861 #define    _PR_MD_IOQ_LOCK _MD_IOQ_LOCK
   863 NSPR_API(void) _PR_MD_IOQ_UNLOCK(void);
   864 #define    _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK
   866 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
   867 /* Semaphore related -- only for native threads */
   868 #ifdef HAVE_CVAR_BUILT_ON_SEM
   869 NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value);
   870 #define _PR_MD_NEW_SEM _MD_NEW_SEM
   872 NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md);
   873 #define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM
   875 NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM(
   876     _MDSemaphore *md, PRIntervalTime timeout);
   877 #define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM
   879 NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md);
   880 #define _PR_MD_WAIT_SEM _MD_WAIT_SEM
   882 NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md);
   883 #define _PR_MD_POST_SEM _MD_POST_SEM
   884 #endif /* HAVE_CVAR_BUILT_ON_SEM */
   886 #endif
   888 /* Condition Variables related -- only for native threads */
   890 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
   891 NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md);
   892 #define    _PR_MD_NEW_CV _MD_NEW_CV
   894 NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md);
   895 #define    _PR_MD_FREE_CV _MD_FREE_CV
   897 NSPR_API(void) _PR_MD_WAIT_CV(
   898     _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout);
   899 #define    _PR_MD_WAIT_CV _MD_WAIT_CV
   901 NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock);
   902 #define    _PR_MD_NOTIFY_CV _MD_NOTIFY_CV
   904 NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock);
   905 #define    _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV
   906 #endif /* _PR_LOCAL_THREADS_ONLY */
   908 /* Threads related */
   909 NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void);
   910 #define    _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD
   912 NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void);
   913 #define    _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD
   915 NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void);
   916 #define    _PR_MD_LAST_THREAD _MD_LAST_THREAD
   918 NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread);
   919 #define    _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD
   921 NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread);
   922 #define    _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD
   924 extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread);
   925 #define    _PR_MD_INIT_THREAD _MD_INIT_THREAD
   927 extern void _PR_MD_EXIT_THREAD(PRThread *thread);
   928 #define    _PR_MD_EXIT_THREAD _MD_EXIT_THREAD
   930 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
   932 NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread);
   933 #define    _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD
   935 extern void _PR_MD_SUSPEND_THREAD(PRThread *thread);
   936 #define    _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD
   938 extern void _PR_MD_RESUME_THREAD(PRThread *thread);
   939 #define    _PR_MD_RESUME_THREAD _MD_RESUME_THREAD
   941 extern void _PR_MD_SUSPEND_CPU(_PRCPU  *cpu);
   942 #define    _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU
   944 extern void _PR_MD_RESUME_CPU(_PRCPU  *cpu);
   945 #define    _PR_MD_RESUME_CPU _MD_RESUME_CPU
   947 extern void _PR_MD_BEGIN_SUSPEND_ALL(void);
   948 #define    _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL
   950 extern void _PR_MD_END_SUSPEND_ALL(void);
   951 #define    _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL
   953 extern void _PR_MD_BEGIN_RESUME_ALL(void);
   954 #define    _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL
   956 extern void _PR_MD_END_RESUME_ALL(void);
   957 #define    _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL
   959 #if defined(IRIX) 
   960 NSPR_API(void) _PR_IRIX_CHILD_PROCESS(void);
   961 #endif        /* IRIX */
   963 #endif        /* !_PR_LOCAL_THREADS_ONLY */
   965 extern void _PR_MD_CLEAN_THREAD(PRThread *thread);
   966 #define    _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD
   968 #ifdef HAVE_CUSTOM_USER_THREADS
   969 extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
   970 #define    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD
   972 extern PRThread* _PR_MD_CREATE_USER_THREAD(
   973                         PRUint32 stacksize,
   974                         void (*start)(void *),
   975                         void *arg);
   976 #define    _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
   977 #endif
   979 extern PRStatus _PR_MD_CREATE_THREAD(
   980                         PRThread *thread, 
   981                         void (*start) (void *), 
   982                         PRThreadPriority priority,                      
   983                         PRThreadScope scope,
   984                         PRThreadState state,
   985                         PRUint32 stackSize);
   986 #define    _PR_MD_CREATE_THREAD _MD_CREATE_THREAD
   988 extern void _PR_MD_JOIN_THREAD(_MDThread *md);
   989 #define    _PR_MD_JOIN_THREAD _MD_JOIN_THREAD
   991 extern void _PR_MD_END_THREAD(void);
   992 #define    _PR_MD_END_THREAD _MD_END_THREAD
   994 extern void _PR_MD_YIELD(void);
   995 #define    _PR_MD_YIELD _MD_YIELD
   997 extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
   998 #define    _PR_MD_SET_PRIORITY _MD_SET_PRIORITY
  1000 extern void _PR_MD_SET_CURRENT_THREAD_NAME(const char *name);
  1001 #define    _PR_MD_SET_CURRENT_THREAD_NAME _MD_SET_CURRENT_THREAD_NAME
  1003 NSPR_API(void) _PR_MD_SUSPENDALL(void);
  1004 #define    _PR_MD_SUSPENDALL _MD_SUSPENDALL
  1006 NSPR_API(void) _PR_MD_RESUMEALL(void);
  1007 #define    _PR_MD_RESUMEALL _MD_RESUMEALL
  1009 extern void _PR_MD_INIT_CONTEXT(
  1010     PRThread *thread, char *top, void (*start) (void), PRBool *status);
  1011 #define    _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT
  1013 extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread);
  1014 #define    _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT
  1016 extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread);
  1017 #define    _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT
  1019 /* Segment related */
  1020 extern void _PR_MD_INIT_SEGS(void);
  1021 #define    _PR_MD_INIT_SEGS _MD_INIT_SEGS
  1023 extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr);
  1024 #define    _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT
  1026 extern void _PR_MD_FREE_SEGMENT(PRSegment *seg);
  1027 #define    _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT
  1029 /* Directory enumeration related */
  1030 extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name);
  1031 #define    _PR_MD_OPEN_DIR _MD_OPEN_DIR
  1033 extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags);
  1034 #define    _PR_MD_READ_DIR _MD_READ_DIR
  1036 extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md);
  1037 #define    _PR_MD_CLOSE_DIR _MD_CLOSE_DIR
  1039 /* Named semaphores related */
  1040 extern PRSem * _PR_MD_OPEN_SEMAPHORE(
  1041     const char *osname, PRIntn flags, PRIntn mode, PRUintn value);
  1042 #define    _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE
  1044 extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem);
  1045 #define    _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE
  1047 extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem);
  1048 #define    _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE
  1050 extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem);
  1051 #define    _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE
  1053 extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname);
  1054 #define    _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE
  1056 /* I/O related */
  1057 extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd);
  1058 #define    _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC
  1060 extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
  1061 #define    _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK
  1063 /* File I/O related */
  1064 extern PROsfd _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode);
  1065 #define    _PR_MD_OPEN _MD_OPEN
  1067 extern PROsfd _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode);
  1068 #define    _PR_MD_OPEN_FILE _MD_OPEN_FILE
  1070 extern PRInt32 _PR_MD_CLOSE_FILE(PROsfd osfd);
  1071 #define    _PR_MD_CLOSE_FILE _MD_CLOSE_FILE
  1073 extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount);
  1074 #define    _PR_MD_READ _MD_READ
  1076 extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount);
  1077 #define    _PR_MD_WRITE _MD_WRITE
  1079 extern PRInt32 _PR_MD_WRITEV(
  1080     PRFileDesc *fd, const struct PRIOVec *iov,
  1081     PRInt32 iov_size, PRIntervalTime timeout);
  1082 #define    _PR_MD_WRITEV _MD_WRITEV
  1084 extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd);
  1085 #define    _PR_MD_FSYNC _MD_FSYNC
  1087 extern PRInt32 _PR_MD_DELETE(const char *name);
  1088 #define        _PR_MD_DELETE _MD_DELETE
  1090 extern PRInt32 _PR_MD_RENAME(const char *from, const char *to);
  1091 #define _PR_MD_RENAME _MD_RENAME
  1093 extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how);
  1094 #define _PR_MD_ACCESS _MD_ACCESS
  1096 extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf);
  1097 #define _PR_MD_STAT _MD_STAT
  1099 extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode);
  1100 #define _PR_MD_MKDIR _MD_MKDIR
  1102 extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode);
  1103 #define _PR_MD_MAKE_DIR _MD_MAKE_DIR
  1105 extern PRInt32 _PR_MD_RMDIR(const char *name);
  1106 #define _PR_MD_RMDIR _MD_RMDIR
  1108 #ifdef MOZ_UNICODE
  1109 /* UTF16 File I/O related */
  1110 extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name);
  1111 #define    _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16
  1113 extern PROsfd _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode);
  1114 #define    _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16
  1116 extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags);
  1117 #define    _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16
  1119 extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md);
  1120 #define    _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16
  1122 extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info);
  1123 #define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16
  1124 #endif /* MOZ_UNICODE */
  1126 /* Socket I/O related */
  1127 extern void _PR_MD_INIT_IO(void);
  1128 #define    _PR_MD_INIT_IO _MD_INIT_IO
  1130 extern PRInt32 _PR_MD_CLOSE_SOCKET(PROsfd osfd);
  1131 #define    _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET
  1133 extern PRInt32 _PR_MD_CONNECT(
  1134     PRFileDesc *fd, const PRNetAddr *addr,
  1135     PRUint32 addrlen, PRIntervalTime timeout);
  1136 #define    _PR_MD_CONNECT _MD_CONNECT
  1138 extern PROsfd _PR_MD_ACCEPT(
  1139     PRFileDesc *fd, PRNetAddr *addr,
  1140     PRUint32 *addrlen, PRIntervalTime timeout);
  1141 #define    _PR_MD_ACCEPT _MD_ACCEPT
  1143 extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
  1144 #define    _PR_MD_BIND _MD_BIND
  1146 extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog);
  1147 #define    _PR_MD_LISTEN _MD_LISTEN
  1149 extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how);
  1150 #define    _PR_MD_SHUTDOWN _MD_SHUTDOWN
  1152 extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, 
  1153                                PRIntn flags, PRIntervalTime timeout);
  1154 #define    _PR_MD_RECV _MD_RECV
  1156 extern PRInt32 _PR_MD_SEND(
  1157     PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, 
  1158     PRIntervalTime timeout);
  1159 #define    _PR_MD_SEND _MD_SEND
  1161 extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, 
  1162                                 PRNetAddr **raddr, void *buf, PRInt32 amount,
  1163                                 PRIntervalTime timeout);
  1164 #define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ
  1166 #ifdef WIN32
  1167 extern PROsfd _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, 
  1168                                 PRUint32 *addrlen, PRIntervalTime timeout,
  1169                                 PRBool fast,
  1170                                 _PR_AcceptTimeoutCallback callback,
  1171                                 void *callbackArg);
  1173 extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, 
  1174                                 PRNetAddr **raddr, void *buf, PRInt32 amount,
  1175                                 PRIntervalTime timeout, PRBool fast,
  1176                                 _PR_AcceptTimeoutCallback callback,
  1177                                 void *callbackArg);
  1179 extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd s, PROsfd ls);
  1180 #define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT
  1181 /*
  1182  * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
  1183  * We store the value in a PRTime variable for convenience.
  1184  * This constant is used by _PR_FileTimeToPRTime().
  1185  * This is defined in ntmisc.c
  1186  */
  1187 extern const PRTime _pr_filetime_offset;
  1188 #endif /* WIN32 */
  1190 extern PRInt32 _PR_MD_SENDFILE(
  1191     PRFileDesc *sock, PRSendFileData *sfd, 
  1192 	PRInt32 flags, PRIntervalTime timeout);
  1193 #define _PR_MD_SENDFILE _MD_SENDFILE
  1195 extern PRStatus _PR_MD_GETSOCKNAME(
  1196     PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
  1197 #define    _PR_MD_GETSOCKNAME _MD_GETSOCKNAME
  1199 extern PRStatus _PR_MD_GETPEERNAME(
  1200     PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
  1201 #define    _PR_MD_GETPEERNAME _MD_GETPEERNAME
  1203 extern PRStatus _PR_MD_GETSOCKOPT(
  1204     PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
  1205 #define    _PR_MD_GETSOCKOPT _MD_GETSOCKOPT
  1207 extern PRStatus _PR_MD_SETSOCKOPT(
  1208     PRFileDesc *fd, PRInt32 level, PRInt32 optname,
  1209     const char* optval, PRInt32 optlen);
  1210 #define    _PR_MD_SETSOCKOPT _MD_SETSOCKOPT
  1212 extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption(
  1213     PRFileDesc *fd, PRSocketOptionData *data);
  1215 extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption(
  1216     PRFileDesc *fd, const PRSocketOptionData *data);
  1218 extern PRInt32 _PR_MD_RECVFROM(
  1219     PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
  1220     PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
  1221 #define    _PR_MD_RECVFROM _MD_RECVFROM
  1223 extern PRInt32 _PR_MD_SENDTO(
  1224     PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
  1225     const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
  1226 #define    _PR_MD_SENDTO _MD_SENDTO
  1228 extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd);
  1229 #define    _PR_MD_SOCKETPAIR _MD_SOCKETPAIR
  1231 extern PROsfd _PR_MD_SOCKET(int af, int type, int flags);
  1232 #define    _PR_MD_SOCKET _MD_SOCKET
  1234 extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd);
  1235 #define    _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE
  1237 extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd);
  1238 #define    _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE
  1240 extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds,
  1241                                                                                         PRIntervalTime timeout);
  1242 #define    _PR_MD_PR_POLL _MD_PR_POLL
  1244 /*
  1245  * Initialize fd->secret->inheritable for a newly created fd.
  1246  * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd)
  1247  * was created by NSPR and hence has the OS-dependent default
  1248  * inheritable attribute.  If 'imported' is true, the osfd was
  1249  * not created by NSPR and hence a system call is required to
  1250  * query its inheritable attribute.  Since we may never need to
  1251  * know the inheritable attribute of a fd, a platform may choose
  1252  * to initialize fd->secret->inheritable of an imported fd to
  1253  * _PR_TRI_UNKNOWN and only pay the cost of the system call
  1254  * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary.
  1255  */
  1256 extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported);
  1257 #define    _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE
  1259 extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable);
  1260 #define    _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE
  1263 #define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \
  1264         if (_PR_PENDING_INTERRUPT(me)) { \
  1265                 me->flags &= ~_PR_INTERRUPT; \
  1266                 PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \
  1267         } else { \
  1268                 PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \
  1271 extern void *_PR_MD_GET_SP(PRThread *thread);
  1272 #define    _PR_MD_GET_SP _MD_GET_SP
  1274 #endif /* defined(_PR_PTHREADS) */
  1276 /************************************************************************/
  1277 /*************************************************************************
  1278 ** The remainder of the definitions are shared by pthreads and the classic
  1279 ** NSPR code. These too may be conditionalized.
  1280 *************************************************************************/
  1281 /************************************************************************/
  1283 extern PROffset32 _PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence);
  1284 #define    _PR_MD_LSEEK _MD_LSEEK
  1286 extern PROffset64 _PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence);
  1287 #define    _PR_MD_LSEEK64 _MD_LSEEK64
  1289 extern PRInt32 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info);
  1290 #define _PR_MD_GETFILEINFO _MD_GETFILEINFO
  1292 extern PRInt32 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info);
  1293 #define _PR_MD_GETFILEINFO64 _MD_GETFILEINFO64
  1295 extern PRInt32 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info);
  1296 #define _PR_MD_GETOPENFILEINFO _MD_GETOPENFILEINFO
  1298 extern PRInt32 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info);
  1299 #define _PR_MD_GETOPENFILEINFO64 _MD_GETOPENFILEINFO64
  1302 /*****************************************************************************/
  1303 /************************** File descriptor caching **************************/
  1304 /*****************************************************************************/
  1305 extern void _PR_InitFdCache(void);
  1306 extern void _PR_CleanupFdCache(void);
  1307 extern PRFileDesc *_PR_Getfd(void);
  1308 extern void _PR_Putfd(PRFileDesc *fd);
  1310 /*
  1311  * These flags are used by NSPR temporarily in the poll
  1312  * descriptor's out_flags field to record the mapping of
  1313  * NSPR's poll flags to the system poll flags.
  1315  * If _PR_POLL_READ_SYS_WRITE bit is set, it means the
  1316  * PR_POLL_READ flag specified by the topmost layer is
  1317  * mapped to the WRITE flag at the system layer.  Similarly
  1318  * for the other three _PR_POLL_XXX_SYS_YYY flags.  It is
  1319  * assumed that the PR_POLL_EXCEPT flag doesn't get mapped
  1320  * to other flags.
  1321  */
  1322 #define _PR_POLL_READ_SYS_READ     0x1
  1323 #define _PR_POLL_READ_SYS_WRITE    0x2
  1324 #define _PR_POLL_WRITE_SYS_READ    0x4
  1325 #define _PR_POLL_WRITE_SYS_WRITE   0x8
  1327 /*
  1328 ** These methods are coerced into file descriptor methods table
  1329 ** when the intended service is inappropriate for the particular
  1330 ** type of file descriptor.
  1331 */
  1332 extern PRIntn _PR_InvalidInt(void);
  1333 extern PRInt16 _PR_InvalidInt16(void);
  1334 extern PRInt64 _PR_InvalidInt64(void);
  1335 extern PRStatus _PR_InvalidStatus(void);
  1336 extern PRFileDesc *_PR_InvalidDesc(void);
  1338 extern PRIOMethods _pr_faulty_methods;
  1340 /*
  1341 ** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union
  1342 ** whose 'family' field is set.  It returns the size of the union
  1343 ** member corresponding to the specified address family.
  1344 */
  1346 extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr);
  1348 #if defined(_PR_INET6)
  1350 #define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr)
  1352 #elif defined(_PR_HAVE_MD_SOCKADDR_IN6)
  1354 /*
  1355 ** Under the following conditions:
  1356 ** 1. _PR_INET6 is not defined;
  1357 ** 2. _PR_INET6_PROBE is defined;
  1358 ** 3. struct sockaddr_in6 has nonstandard fields at the end
  1359 **    (e.g., on Solaris 8),
  1360 ** (_addr)->ipv6 is smaller than struct sockaddr_in6, and
  1361 ** hence we can't pass sizeof((_addr)->ipv6) to socket
  1362 ** functions such as connect because they would fail with
  1363 ** EINVAL.
  1364 **
  1365 ** To pass the correct socket address length to socket
  1366 ** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and
  1367 ** define struct _md_sockaddr_in6 to be isomorphic to
  1368 ** struct sockaddr_in6.
  1369 */
  1371 #if defined(XP_UNIX) || defined(XP_OS2)
  1372 #define PR_NETADDR_SIZE(_addr) 					\
  1373         ((_addr)->raw.family == PR_AF_INET		\
  1374         ? sizeof((_addr)->inet)					\
  1375         : ((_addr)->raw.family == PR_AF_INET6	\
  1376         ? sizeof(struct _md_sockaddr_in6)		\
  1377         : sizeof((_addr)->local)))
  1378 #else
  1379 #define PR_NETADDR_SIZE(_addr) 					\
  1380         ((_addr)->raw.family == PR_AF_INET		\
  1381         ? sizeof((_addr)->inet)					\
  1382         : sizeof(struct _md_sockaddr_in6))
  1383 #endif /* defined(XP_UNIX) */
  1385 #else
  1387 #if defined(XP_UNIX) || defined(XP_OS2)
  1388 #define PR_NETADDR_SIZE(_addr) 					\
  1389         ((_addr)->raw.family == PR_AF_INET		\
  1390         ? sizeof((_addr)->inet)					\
  1391         : ((_addr)->raw.family == PR_AF_INET6	\
  1392         ? sizeof((_addr)->ipv6)					\
  1393         : sizeof((_addr)->local)))
  1394 #else
  1395 #define PR_NETADDR_SIZE(_addr) 					\
  1396         ((_addr)->raw.family == PR_AF_INET		\
  1397         ? sizeof((_addr)->inet)					\
  1398         : sizeof((_addr)->ipv6))
  1399 #endif /* defined(XP_UNIX) */
  1401 #endif /* defined(_PR_INET6) */
  1403 extern PRStatus _PR_MapOptionName(
  1404     PRSockOption optname, PRInt32 *level, PRInt32 *name);
  1405 extern void _PR_InitThreads(
  1406     PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs);
  1408 struct PRLock {
  1409 #if defined(_PR_PTHREADS)
  1410     pthread_mutex_t mutex;          /* the underlying lock */
  1411     _PT_Notified notified;          /* array of conditions notified */
  1412     PRBool locked;                  /* whether the mutex is locked */
  1413     pthread_t owner;                /* if locked, current lock owner */
  1414 #elif defined(_PR_BTHREADS)
  1415     sem_id	semaphoreID;	    /* the underlying lock */
  1416     int32	benaphoreCount;	    /* number of people in lock */
  1417     thread_id	owner;		    /* current lock owner */
  1418 #else /* not pthreads or Be threads */
  1419     PRCList links;                  /* linkage for PRThread.lockList */
  1420     struct PRThread *owner;         /* current lock owner */
  1421     PRCList waitQ;                  /* list of threads waiting for lock */
  1422     PRThreadPriority priority;      /* priority of lock */ 
  1423     PRThreadPriority boostPriority; /* boosted priority of lock owner */
  1424     _MDLock ilock;                  /* Internal Lock to protect user-level fields */
  1425 #endif
  1426 };
  1428 struct PRCondVar {
  1429     PRLock *lock;               /* associated lock that protects the condition */
  1430 #if defined(_PR_PTHREADS)
  1431     pthread_cond_t cv;          /* underlying pthreads condition */
  1432     PRInt32 notify_pending;     /* CV has destroy pending notification */
  1433 #elif defined(_PR_BTHREADS)
  1434     sem_id    sem;              /* the underlying lock */
  1435     sem_id    handshakeSem;     /* the lock for 'notify'-threads waiting for confirmation */
  1436     sem_id    signalSem;        /* the lock for threads waiting for someone to notify */
  1437     volatile int32    nw;       /* the number waiting */
  1438     volatile int32    ns;       /* the number signalling */
  1439     long signalBenCount;        /* the number waiting on the underlying sem */
  1440 #else /* not pthreads or Be threads */
  1441     PRCList condQ;              /* Condition variable wait Q */
  1442     _MDLock ilock;              /* Internal Lock to protect condQ */
  1443     _MDCVar md;
  1444 #endif
  1445 };
  1447 /************************************************************************/
  1449 struct PRMonitor {
  1450     const char* name;           /* monitor name for debugging */
  1451 #if defined(_PR_PTHREADS)
  1452     pthread_mutex_t lock;       /* lock is only held when accessing fields
  1453                                  * of the PRMonitor, instead of being held
  1454                                  * while the monitor is entered. The only
  1455                                  * exception is notifyTimes, which is
  1456                                  * protected by the monitor. */
  1457     pthread_t owner;            /* the owner of the monitor or invalid */
  1458     pthread_cond_t entryCV;     /* for threads waiting to enter the monitor */
  1460     pthread_cond_t waitCV;      /* for threads waiting on the monitor */
  1461     PRInt32 refCount;           /* reference count, an atomic variable.
  1462                                  * PR_NewMonitor adds a reference to the
  1463                                  * newly created PRMonitor, and
  1464                                  * PR_DestroyMonitor releases that reference.
  1465                                  * PR_ExitMonitor adds a reference before
  1466                                  * unlocking the internal lock if it needs to
  1467                                  * signal entryCV, and releases the reference
  1468                                  * after signaling entryCV. */
  1469 #else  /* defined(_PR_PTHREADS) */
  1470     PRLock lock;                /* lock is only held when accessing fields
  1471                                  * of the PRMonitor, instead of being held
  1472                                  * while the monitor is entered. The only
  1473                                  * exception is notifyTimes, which is
  1474                                  * protected by the monitor. */
  1475     PRThread *owner;            /* the owner of the monitor or invalid */
  1476     PRCondVar entryCV;          /* for threads waiting to enter the monitor */
  1478     PRCondVar waitCV;           /* for threads waiting on the monitor */
  1479 #endif /* defined(_PR_PTHREADS) */
  1480     PRUint32 entryCount;        /* # of times re-entered */
  1481     PRIntn notifyTimes;         /* number of pending notifies for waitCV.
  1482                                  * The special value -1 means a broadcast
  1483                                  * (PR_NotifyAll). */
  1484 };
  1486 /************************************************************************/
  1488 struct PRSemaphore {
  1489 #if defined(_PR_BTHREADS)
  1490     sem_id  sem;
  1491     int32   benaphoreCount;
  1492 #else
  1493     PRCondVar *cvar;        /* associated lock and condition variable queue */
  1494     PRUintn count;            /* the value of the counting semaphore */
  1495     PRUint32 waiters;            /* threads waiting on the semaphore */
  1496 #if defined(_PR_PTHREADS)
  1497 #else  /* defined(_PR_PTHREADS) */
  1498     _MDSemaphore md;
  1499 #endif /* defined(_PR_PTHREADS) */
  1500 #endif /* defined(_PR_BTHREADS) */
  1501 };
  1503 /*************************************************************************/
  1505 struct PRSem {
  1506 #ifdef _PR_HAVE_POSIX_SEMAPHORES
  1507     sem_t *sem;
  1508 #elif defined(_PR_HAVE_SYSV_SEMAPHORES)
  1509     int semid;
  1510 #elif defined(WIN32)
  1511     HANDLE sem;
  1512 #else
  1513     PRInt8 notused;
  1514 #endif
  1515 };
  1517 /*************************************************************************/
  1519 struct PRStackStr {
  1520     /* head MUST be at offset 0; assembly language code relies on this */
  1521 #if defined(AIX)
  1522     volatile PRStackElem prstk_head;
  1523 #else
  1524     PRStackElem prstk_head;
  1525 #endif
  1527     PRLock *prstk_lock;
  1528     char *prstk_name;
  1529 };
  1531 /************************************************************************/
  1533 /* XXX this needs to be exported (sigh) */
  1534 struct PRThreadStack {
  1535     PRCList links;
  1536     PRUintn flags;
  1538     char *allocBase;            /* base of stack's allocated memory */
  1539     PRUint32 allocSize;         /* size of stack's allocated memory */
  1540     char *stackBottom;          /* bottom of stack from C's point of view */
  1541     char *stackTop;             /* top of stack from C's point of view */
  1542     PRUint32 stackSize;         /* size of usable portion of the stack */
  1544     PRSegment *seg;
  1545         PRThread* thr;          /* back pointer to thread owning this stack */
  1547 #if defined(_PR_PTHREADS)
  1548 #else /* defined(_PR_PTHREADS) */
  1549     _MDThreadStack md;
  1550 #endif /* defined(_PR_PTHREADS) */
  1551 };
  1553 extern void _PR_DestroyThreadPrivate(PRThread*);
  1555 typedef void (PR_CALLBACK *_PRStartFn)(void *);
  1557 struct PRThread {
  1558     PRUint32 state;                 /* thread's creation state */
  1559     PRThreadPriority priority;      /* apparent priority, loosly defined */
  1561     void *arg;                      /* argument to the client's entry point */
  1562     _PRStartFn startFunc;           /* the root of the client's thread */
  1564     PRThreadStack *stack;           /* info about thread's stack (for GC) */
  1565     void *environment;              /* pointer to execution environment */
  1567     PRThreadDumpProc dump;          /* dump thread info out */
  1568     void *dumpArg;                  /* argument for the dump function */
  1570     /*
  1571     ** Per thread private data
  1572     */
  1573     PRUint32 tpdLength;             /* thread's current vector length */
  1574     void **privateData;             /* private data vector or NULL */
  1575     PRErrorCode errorCode;          /* current NSPR error code | zero */
  1576     PRInt32 osErrorCode;            /* mapping of errorCode | zero */
  1577     PRIntn  errorStringLength;      /* textLength from last call to PR_SetErrorText() */
  1578     PRInt32 errorStringSize;        /* malloc()'d size of buffer | zero */
  1579     char *errorString;              /* current error string | NULL */
  1580     char *name;                     /* thread's name */
  1582 #if defined(_PR_PTHREADS)
  1583     pthread_t id;                   /* pthread identifier for the thread */
  1584     PRBool idSet;                   /* whether 'id' has been set. Protected by
  1585                                      * pt_book.ml. */
  1586 #ifdef _PR_NICE_PRIORITY_SCHEDULING
  1587     pid_t tid;                      /* Linux-specific kernel thread ID */
  1588 #endif
  1589     PRBool okToDelete;              /* ok to delete the PRThread struct? */
  1590     PRCondVar *waiting;             /* where the thread is waiting | NULL */
  1591     void *sp;                       /* recorded sp for garbage collection */
  1592     PRThread *next, *prev;          /* simple linked list of all threads */
  1593     PRUint32 suspend;               /* used to store suspend and resume flags */
  1594 #ifdef PT_NO_SIGTIMEDWAIT
  1595     pthread_mutex_t suspendResumeMutex;
  1596     pthread_cond_t suspendResumeCV;
  1597 #endif
  1598     PRUint32 interrupt_blocked;     /* interrupt blocked */
  1599     struct pollfd *syspoll_list;    /* Unix polling list used by PR_Poll */
  1600     PRUint32 syspoll_count;         /* number of elements in syspoll_list */
  1601 #if defined(_PR_POLL_WITH_SELECT)
  1602     int *selectfd_list;             /* Unix fd's that PR_Poll selects on */
  1603     PRUint32 selectfd_count;        /* number of elements in selectfd_list */
  1604 #endif
  1605 #elif defined(_PR_BTHREADS)
  1606     PRUint32 flags;
  1607     _MDThread md;
  1608     PRBool io_pending;
  1609     PRInt32 io_fd;
  1610     PRBool io_suspended;
  1611 #else /* not pthreads or Be threads */
  1612     _MDLock threadLock;             /* Lock to protect thread state variables.
  1613                                      * Protects the following fields:
  1614                                      *     state
  1615                                      *     priority
  1616                                      *     links
  1617                                      *     wait
  1618                                      *     cpu
  1619                                      */
  1620     PRUint32 queueCount;
  1621     PRUint32 waitCount;
  1623     PRCList active;                 /* on list of all active threads        */
  1624     PRCList links;
  1625     PRCList waitQLinks;             /* when thread is PR_Wait'ing */
  1626     PRCList lockList;               /* list of locks currently holding */
  1627     PRIntervalTime sleep;           /* sleep time when thread is sleeping */
  1628     struct _wait {
  1629         struct PRLock *lock;
  1630         struct PRCondVar *cvar;
  1631     } wait;
  1633     PRUint32 id;
  1634     PRUint32 flags;
  1635     PRUint32 no_sched;              /* Don't schedule the thread to run.
  1636                                      * This flag has relevance only when
  1637                                      * multiple NSPR CPUs are created.
  1638                                      * When a thread is de-scheduled, there
  1639                                      * is a narrow window of time in which
  1640                                      * the thread is put on the run queue
  1641                                      * but the scheduler is actually using
  1642                                      * the stack of this thread.  It is safe
  1643                                      * to run this thread on a different CPU
  1644                                      * only when its stack is not in use on
  1645                                      * any other CPU.  The no_sched flag is
  1646                                      * set during this interval to prevent
  1647                                      * the thread from being scheduled on a
  1648                                      * different CPU.
  1649                                      */
  1651     /* thread termination condition variable for join */
  1652     PRCondVar *term;
  1654     _PRCPU *cpu;                    /* cpu to which this thread is bound    */
  1655     PRUint32 threadAllocatedOnStack;/* boolean */
  1657     /* When an async IO is in progress and a second async IO cannot be 
  1658      * initiated, the io_pending flag is set to true.  Some platforms will
  1659      * not use the io_pending flag.  If the io_pending flag is true, then
  1660      * io_fd is the OS-file descriptor on which IO is pending.
  1661      */
  1662     PRBool io_pending;
  1663     PRInt32 io_fd;
  1665     /* If a timeout occurs or if an outstanding IO is interrupted and the
  1666      * OS doesn't support a real cancellation (NT or MAC), then the 
  1667      * io_suspended flag will be set to true.  The thread will be resumed
  1668      * but may run into trouble issuing additional IOs until the io_pending
  1669      * flag can be cleared 
  1670      */
  1671     PRBool io_suspended;
  1673     _MDThread md;
  1674 #endif
  1675 };
  1677 struct PRProcessAttr {
  1678     PRFileDesc *stdinFd;
  1679     PRFileDesc *stdoutFd;
  1680     PRFileDesc *stderrFd;
  1681     char *currentDirectory;
  1682     char *fdInheritBuffer;
  1683     PRSize fdInheritBufferSize;
  1684     PRSize fdInheritBufferUsed;
  1685 };
  1687 struct PRProcess {
  1688     _MDProcess md;
  1689 };
  1691 struct PRFileMap {
  1692     PRFileDesc *fd;
  1693     PRFileMapProtect prot;
  1694     _MDFileMap md;
  1695 };
  1697 /************************************************************************/
  1699 /*
  1700 ** File descriptors of the NSPR layer can be in one of the
  1701 ** following states (stored in the 'state' field of struct
  1702 ** PRFilePrivate):
  1703 ** - _PR_FILEDESC_OPEN: The OS fd is open.
  1704 ** - _PR_FILEDESC_CLOSED: The OS fd is closed.  The PRFileDesc
  1705 **   is still open but is unusable.  The only operation allowed
  1706 **   on the PRFileDesc is PR_Close().
  1707 ** - _PR_FILEDESC_FREED: The OS fd is closed and the PRFileDesc
  1708 **   structure is freed.
  1709 */
  1711 #define _PR_FILEDESC_OPEN       0xaaaaaaaa    /* 1010101... */
  1712 #define _PR_FILEDESC_CLOSED     0x55555555    /* 0101010... */
  1713 #define _PR_FILEDESC_FREED      0x11111111
  1715 /*
  1716 ** A boolean type with an additional "unknown" state
  1717 */
  1719 typedef enum {
  1720     _PR_TRI_TRUE = 1,
  1721     _PR_TRI_FALSE = 0,
  1722     _PR_TRI_UNKNOWN = -1
  1723 } _PRTriStateBool;
  1725 struct PRFilePrivate {
  1726     PRInt32 state;
  1727     PRBool nonblocking;
  1728     _PRTriStateBool inheritable;
  1729     PRFileDesc *next;
  1730     PRIntn lockCount;   /*   0: not locked
  1731                          *  -1: a native lockfile call is in progress
  1732                          * > 0: # times the file is locked */
  1733 #ifdef _PR_HAVE_PEEK_BUFFER
  1734     char *peekBuffer;
  1735     PRInt32 peekBufSize;
  1736     PRInt32 peekBytes;
  1737 #endif
  1738 #if !defined(_PR_HAVE_O_APPEND)
  1739     PRBool  appendMode; /* Some platforms don't have O_APPEND or its
  1740                          * equivalent, so they have to seek to end of
  1741                          * file on write if the file was opened in
  1742                          * append mode.  See Bugzilla 4090, 276330. */
  1743 #endif
  1744     _MDFileDesc md;
  1745 #ifdef _PR_NEED_SECRET_AF
  1746     PRUint16 af;        /* If the platform's implementation of accept()
  1747                          * requires knowing the address family of the 
  1748 			 * socket, we save the address family here. */
  1749 #endif
  1750 };
  1752 #ifdef _WIN64
  1753 #define PR_PRIdOSFD "lld"       /* for printing PROsfd */
  1754 #define PR_PRIxOSFD "llx"
  1755 #define PR_SCNdOSFD "lld"       /* for scanning PROsfd */
  1756 #define PR_SCNxOSFD "llx"
  1757 #else
  1758 #define PR_PRIdOSFD "ld"        /* for printing PROsfd */
  1759 #define PR_PRIxOSFD "lx"
  1760 #define PR_SCNdOSFD "ld"        /* for scanning PROsfd */
  1761 #define PR_SCNxOSFD "lx"
  1762 #endif
  1764 struct PRDir {
  1765     PRDirEntry d;
  1766     _MDDir md;
  1767 };
  1769 #ifdef MOZ_UNICODE
  1770 struct PRDirUTF16 { 
  1771     PRDirEntry d; 
  1772     _MDDirUTF16 md; 
  1773 }; 
  1774 #endif /* MOZ_UNICODE */
  1776 extern void _PR_InitLocks(void);
  1777 extern void _PR_InitSegs(void);
  1778 extern void _PR_InitStacks(void);
  1779 extern void _PR_InitTPD(void);
  1780 extern void _PR_InitMem(void);
  1781 extern void _PR_InitEnv(void);
  1782 extern void _PR_InitCMon(void);
  1783 extern void _PR_InitIO(void);
  1784 extern void _PR_InitLog(void);
  1785 extern void _PR_InitNet(void);
  1786 extern void _PR_InitClock(void);
  1787 extern void _PR_InitLinker(void);
  1788 extern void _PR_InitAtomic(void);
  1789 extern void _PR_InitCPUs(void);
  1790 extern void _PR_InitDtoa(void);
  1791 extern void _PR_InitTime(void);
  1792 extern void _PR_InitMW(void);
  1793 extern void _PR_InitRWLocks(void);
  1794 extern void _PR_CleanupThread(PRThread *thread);
  1795 extern void _PR_CleanupCallOnce(void);
  1796 extern void _PR_CleanupMW(void);
  1797 extern void _PR_CleanupTime(void);
  1798 extern void _PR_CleanupDtoa(void);
  1799 extern void _PR_ShutdownLinker(void);
  1800 extern void _PR_CleanupEnv(void);
  1801 extern void _PR_CleanupIO(void);
  1802 extern void _PR_CleanupCMon(void);
  1803 extern void _PR_CleanupNet(void);
  1804 extern void _PR_CleanupLayerCache(void);
  1805 extern void _PR_CleanupStacks(void);
  1806 #ifdef WINNT
  1807 extern void _PR_CleanupCPUs(void);
  1808 #endif
  1809 extern void _PR_CleanupThreads(void);
  1810 extern void _PR_CleanupTPD(void);
  1811 extern void _PR_Cleanup(void);
  1812 extern void _PR_LogCleanup(void);
  1813 extern void _PR_InitLayerCache(void);
  1815 extern PRBool _pr_initialized;
  1816 extern void _PR_ImplicitInitialization(void);
  1817 extern PRBool _PR_Obsolete(const char *obsolete, const char *preferred);
  1819 /************************************************************************/
  1821 struct PRSegment {
  1822     void *vaddr;
  1823     PRUint32 size;
  1824     PRUintn flags;
  1825 #if defined(_PR_PTHREADS)
  1826 #else  /* defined(_PR_PTHREADS) */
  1827     _MDSegment md;
  1828 #endif /* defined(_PR_PTHREADS) */
  1829 };
  1831 /* PRSegment.flags */
  1832 #define _PR_SEG_VM    0x1
  1834 /************************************************************************/
  1836 extern PRInt32 _pr_pageSize;
  1837 extern PRInt32 _pr_pageShift;
  1839 extern PRLogModuleInfo *_pr_clock_lm;
  1840 extern PRLogModuleInfo *_pr_cmon_lm;
  1841 extern PRLogModuleInfo *_pr_io_lm;
  1842 extern PRLogModuleInfo *_pr_cvar_lm;
  1843 extern PRLogModuleInfo *_pr_mon_lm;
  1844 extern PRLogModuleInfo *_pr_linker_lm;
  1845 extern PRLogModuleInfo *_pr_sched_lm;
  1846 extern PRLogModuleInfo *_pr_thread_lm;
  1847 extern PRLogModuleInfo *_pr_gc_lm;
  1849 extern PRFileDesc *_pr_stdin;
  1850 extern PRFileDesc *_pr_stdout;
  1851 extern PRFileDesc *_pr_stderr;
  1853 /* Zone allocator */
  1854 /*
  1855 ** The zone allocator code has hardcoded pthread types and
  1856 ** functions, so it can only be used in the pthreads version.
  1857 ** This can be fixed by replacing the hardcoded pthread types
  1858 ** and functions with macros that expand to the native thread
  1859 ** types and functions on each platform.
  1860 */
  1861 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
  1862 #define _PR_ZONE_ALLOCATOR
  1863 #endif
  1865 #ifdef _PR_ZONE_ALLOCATOR
  1866 extern void _PR_InitZones(void);
  1867 extern void _PR_DestroyZones(void);
  1868 #endif
  1870 /* Overriding malloc, free, etc. */
  1871 #if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \
  1872         && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \
  1873         && !defined(PURIFY) \
  1874         && !defined(DARWIN) \
  1875         && !defined(QNX) \
  1876         && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS))
  1877 #define _PR_OVERRIDE_MALLOC
  1878 #endif
  1880 /*************************************************************************
  1881 * External machine-dependent code provided by each OS.                     *                                                                     *
  1882 *************************************************************************/
  1884 /* Initialization related */
  1885 extern void _PR_MD_EARLY_INIT(void);
  1886 #define    _PR_MD_EARLY_INIT _MD_EARLY_INIT
  1888 extern void _PR_MD_INTERVAL_INIT(void);
  1889 #define    _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT
  1891 NSPR_API(void) _PR_MD_FINAL_INIT(void);
  1892 #define    _PR_MD_FINAL_INIT _MD_FINAL_INIT
  1894 extern void _PR_MD_EARLY_CLEANUP(void);
  1895 #define    _PR_MD_EARLY_CLEANUP _MD_EARLY_CLEANUP
  1897 /* Process control */
  1899 extern PRProcess * _PR_MD_CREATE_PROCESS(
  1900     const char *path,
  1901     char *const *argv,
  1902     char *const *envp,
  1903     const PRProcessAttr *attr);
  1904 #define    _PR_MD_CREATE_PROCESS _MD_CREATE_PROCESS
  1906 extern PRStatus _PR_MD_DETACH_PROCESS(PRProcess *process);
  1907 #define    _PR_MD_DETACH_PROCESS _MD_DETACH_PROCESS
  1909 extern PRStatus _PR_MD_WAIT_PROCESS(PRProcess *process, PRInt32 *exitCode);
  1910 #define    _PR_MD_WAIT_PROCESS _MD_WAIT_PROCESS
  1912 extern PRStatus _PR_MD_KILL_PROCESS(PRProcess *process);
  1913 #define    _PR_MD_KILL_PROCESS _MD_KILL_PROCESS        
  1915 /* Current Time */
  1916 NSPR_API(PRTime) _PR_MD_NOW(void);
  1917 #define    _PR_MD_NOW _MD_NOW
  1919 /* Environment related */
  1920 extern char* _PR_MD_GET_ENV(const char *name);
  1921 #define    _PR_MD_GET_ENV _MD_GET_ENV
  1923 extern PRIntn _PR_MD_PUT_ENV(const char *name);
  1924 #define    _PR_MD_PUT_ENV _MD_PUT_ENV
  1926 /* Atomic operations */
  1928 extern void _PR_MD_INIT_ATOMIC(void);
  1929 #define    _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC
  1931 extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *);
  1932 #define    _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT
  1934 extern PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *, PRInt32);
  1935 #define    _PR_MD_ATOMIC_ADD _MD_ATOMIC_ADD
  1937 extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *);
  1938 #define    _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT
  1940 extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32);
  1941 #define    _PR_MD_ATOMIC_SET _MD_ATOMIC_SET
  1943 /* Garbage collection */
  1945 /*
  1946 ** Save the registers that the GC would find interesting into the thread
  1947 ** "t". isCurrent will be non-zero if the thread state that is being
  1948 ** saved is the currently executing thread. Return the address of the
  1949 ** first register to be scanned as well as the number of registers to
  1950 ** scan in "np".
  1951 **
  1952 ** If "isCurrent" is non-zero then it is allowed for the thread context
  1953 ** area to be used as scratch storage to hold just the registers
  1954 ** necessary for scanning.
  1955 */
  1956 extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np);
  1958 /* Time intervals */
  1960 extern PRIntervalTime _PR_MD_GET_INTERVAL(void);
  1961 #define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL
  1963 extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void);
  1964 #define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC
  1966 /* Affinity masks */
  1968 extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask );
  1969 #define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK
  1971 extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask);
  1972 #define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK
  1974 /* File locking */
  1976 extern PRStatus _PR_MD_LOCKFILE(PROsfd osfd);
  1977 #define    _PR_MD_LOCKFILE _MD_LOCKFILE
  1979 extern PRStatus _PR_MD_TLOCKFILE(PROsfd osfd);
  1980 #define    _PR_MD_TLOCKFILE _MD_TLOCKFILE
  1982 extern PRStatus _PR_MD_UNLOCKFILE(PROsfd osfd);
  1983 #define    _PR_MD_UNLOCKFILE _MD_UNLOCKFILE
  1985 /* Memory-mapped files */
  1987 extern PRStatus _PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size);
  1988 #define _PR_MD_CREATE_FILE_MAP _MD_CREATE_FILE_MAP
  1990 extern PRInt32 _PR_MD_GET_MEM_MAP_ALIGNMENT(void);
  1991 #define _PR_MD_GET_MEM_MAP_ALIGNMENT _MD_GET_MEM_MAP_ALIGNMENT
  1993 extern void * _PR_MD_MEM_MAP(
  1994     PRFileMap *fmap,
  1995     PROffset64 offset,
  1996     PRUint32 len);
  1997 #define _PR_MD_MEM_MAP _MD_MEM_MAP
  1999 extern PRStatus _PR_MD_MEM_UNMAP(void *addr, PRUint32 size);
  2000 #define _PR_MD_MEM_UNMAP _MD_MEM_UNMAP
  2002 extern PRStatus _PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap);
  2003 #define _PR_MD_CLOSE_FILE_MAP _MD_CLOSE_FILE_MAP
  2005 extern PRStatus _PR_MD_SYNC_MEM_MAP(
  2006     PRFileDesc *fd,
  2007     void *addr,
  2008     PRUint32 len);
  2009 #define _PR_MD_SYNC_MEM_MAP _MD_SYNC_MEM_MAP
  2011 /* Named Shared Memory */
  2013 /*
  2014 ** Declare PRSharedMemory.
  2015 */
  2016 struct PRSharedMemory 
  2018     char        *ipcname; /* after conversion to native */
  2019     PRSize      size;  /* from open */
  2020     PRIntn      mode;  /* from open */
  2021     PRIntn      flags; /* from open */
  2022 #if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY)
  2023     int         id;
  2024 #elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY)
  2025     int         id;
  2026 #elif defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)
  2027     HANDLE      handle;
  2028 #else
  2029     PRUint32    nothing; /* placeholder, nothing behind here */
  2030 #endif
  2031     PRUint32    ident; /* guard word at end of struct */
  2032 #define _PR_SHM_IDENT 0xdeadbad
  2033 };
  2035 extern PRSharedMemory * _MD_OpenSharedMemory( 
  2036     const char *name,
  2037     PRSize      size,
  2038     PRIntn      flags,
  2039     PRIntn      mode
  2040 );
  2041 #define _PR_MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
  2043 extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags );
  2044 #define _PR_MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
  2046 extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr );
  2047 #define _PR_MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
  2049 extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm );
  2050 #define _PR_MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
  2052 extern PRStatus _MD_DeleteSharedMemory( const char *name );
  2053 #define _PR_MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
  2055 extern PRFileMap* _md_OpenAnonFileMap( 
  2056     const char *dirName,
  2057     PRSize      size,
  2058     PRFileMapProtect prot
  2059 );
  2060 #define _PR_MD_OPEN_ANON_FILE_MAP _md_OpenAnonFileMap
  2062 extern PRStatus _md_ExportFileMapAsString(
  2063     PRFileMap *fm,
  2064     PRSize    bufSize,
  2065     char      *buf
  2066 );
  2067 #define _PR_MD_EXPORT_FILE_MAP_AS_STRING _md_ExportFileMapAsString
  2069 extern PRFileMap * _md_ImportFileMapFromString(
  2070     const char *fmstring
  2071 );
  2072 #define _PR_MD_IMPORT_FILE_MAP_FROM_STRING _md_ImportFileMapFromString
  2076 /* Interprocess communications (IPC) */
  2078 /*
  2079  * The maximum length of an NSPR IPC name, including the
  2080  * terminating null byte.
  2081  */
  2082 #define PR_IPC_NAME_SIZE 1024
  2084 /*
  2085  * Types of NSPR IPC objects
  2086  */
  2087 typedef enum {
  2088     _PRIPCSem,  /* semaphores */
  2089     _PRIPCShm   /* shared memory segments */
  2090 } _PRIPCType;
  2092 /*
  2093  * Make a native IPC name from an NSPR IPC name.
  2094  */
  2095 extern PRStatus _PR_MakeNativeIPCName(
  2096     const char *name,  /* NSPR IPC name */
  2097     char *result,      /* result buffer */
  2098     PRIntn size,       /* size of result buffer */
  2099     _PRIPCType type    /* type of IPC object */
  2100 );
  2102 /* Socket call error code */
  2104 NSPR_API(PRInt32) _PR_MD_GET_SOCKET_ERROR(void);
  2105 #define    _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR
  2107 /* Get name of current host */
  2108 extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
  2109 #define    _PR_MD_GETHOSTNAME _MD_GETHOSTNAME
  2111 extern PRStatus _PR_MD_GETSYSINFO(PRSysInfo cmd, char *name, PRUint32 namelen);
  2112 #define    _PR_MD_GETSYSINFO _MD_GETSYSINFO
  2114 /* File descriptor inheritance */
  2116 /*
  2117  * If fd->secret->inheritable is _PR_TRI_UNKNOWN and we need to
  2118  * know the inheritable attribute of the fd, call this function
  2119  * to find that out.  This typically requires a system call.
  2120  */
  2121 extern void _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd);
  2122 #define    _PR_MD_QUERY_FD_INHERITABLE _MD_QUERY_FD_INHERITABLE
  2124 /* --- PR_GetRandomNoise() related things --- */
  2126 extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size );
  2127 #define _PR_MD_GET_RANDOM_NOISE(buf,size) _PR_MD_GetRandomNoise((buf),(size))
  2128 extern PRSize _pr_CopyLowBits( void *dest, PRSize dstlen, void *src, PRSize srclen );
  2130 /* end PR_GetRandomNoise() related */
  2132 #ifdef XP_BEOS
  2134 extern PRLock *_connectLock;
  2136 typedef struct _ConnectListNode {
  2137 	PRInt32		osfd;
  2138 	PRNetAddr	addr;
  2139 	PRUint32	addrlen;
  2140 	PRIntervalTime	timeout;
  2141 } ConnectListNode;
  2143 extern ConnectListNode connectList[64];
  2145 extern PRUint32 connectCount;
  2147 #endif /* XP_BEOS */
  2149 PR_END_EXTERN_C
  2151 #endif /* primpl_h___ */

mercurial