Back to index

lightning-sunbird  0.9+nobinonly
primpl.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 primpl_h___
00039 #define primpl_h___
00040 
00041 /*
00042  * HP-UX 10.10's pthread.h (DCE threads) includes dce/cma.h, which
00043  * has:
00044  *     #define sigaction _sigaction_sys
00045  * This macro causes chaos if signal.h gets included before pthread.h.
00046  * To be safe, we include pthread.h first.
00047  */
00048 
00049 #if defined(_PR_PTHREADS)
00050 #include <pthread.h>
00051 #endif
00052 
00053 #if defined(_PR_BTHREADS)
00054 #include <kernel/OS.h>
00055 #endif
00056 
00057 #ifdef WINNT
00058 /* Need to force service-pack 3 extensions to be defined by
00059 ** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h.
00060 */
00061 #ifndef  _WIN32_WINNT
00062     #define _WIN32_WINNT 0x0400
00063 #elif   (_WIN32_WINNT < 0x0400)
00064     #undef  _WIN32_WINNT
00065     #define _WIN32_WINNT 0x0400
00066 #endif /* _WIN32_WINNT */
00067 #endif /* WINNT */
00068 
00069 #include "nspr.h"
00070 #include "prpriv.h"
00071 
00072 typedef struct PRSegment PRSegment;
00073 
00074 #ifdef XP_MAC
00075 #include "prosdep.h"
00076 #include "probslet.h"
00077 #else
00078 #include "md/prosdep.h"
00079 #include "obsolete/probslet.h"
00080 #endif  /* XP_MAC */
00081 
00082 #ifdef _PR_HAVE_POSIX_SEMAPHORES
00083 #include <semaphore.h>
00084 #elif defined(_PR_HAVE_SYSV_SEMAPHORES)
00085 #include <sys/sem.h>
00086 #endif
00087 
00088 /*************************************************************************
00089 *****  A Word about Model Dependent Function Naming Convention ***********
00090 *************************************************************************/
00091 
00092 /*
00093 NSPR 2.0 must implement its function across a range of platforms 
00094 including: MAC, Windows/16, Windows/95, Windows/NT, and several
00095 variants of Unix. Each implementation shares common code as well 
00096 as having platform dependent portions. This standard describes how
00097 the model dependent portions are to be implemented.
00098 
00099 In header file pr/include/primpl.h, each publicly declared 
00100 platform dependent function is declared as:
00101 
00102 NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 );
00103 #define _PR_MD_FUNCTION _MD_FUNCTION
00104 
00105 In header file pr/include/md/<platform>/_<platform>.h, 
00106 each #define'd macro is redefined as one of:
00107 
00108 #define _MD_FUNCTION <blanks>
00109 #define _MD_FUNCTION <expanded macro>
00110 #define _MD_FUNCTION <osFunction>
00111 #define _MD_FUNCTION <_MD_Function>
00112 
00113 Where:
00114 
00115 <blanks> is no definition at all. In this case, the function is not implemented 
00116 and is never called for this platform. 
00117 For example: 
00118 #define _MD_INIT_CPUS()
00119 
00120 <expanded macro> is a C language macro expansion. 
00121 For example: 
00122 #define        _MD_CLEAN_THREAD(_thread) \
00123     PR_BEGIN_MACRO \
00124         PR_DestroyCondVar(_thread->md.asyncIOCVar); \
00125         PR_DestroyLock(_thread->md.asyncIOLock); \
00126     PR_END_MACRO
00127 
00128 <osFunction> is some function implemented by the host operating system. 
00129 For example: 
00130 #define _MD_EXIT        exit
00131 
00132 <_MD_function> is the name of a function implemented for this platform in 
00133 pr/src/md/<platform>/<soruce>.c file. 
00134 For example: 
00135 #define        _MD_GETFILEINFO         _MD_GetFileInfo
00136 
00137 In <source>.c, the implementation is:
00138 PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info);
00139 */
00140 
00141 PR_BEGIN_EXTERN_C
00142 
00143 typedef struct _MDLock _MDLock;
00144 typedef struct _MDCVar _MDCVar;
00145 typedef struct _MDSegment _MDSegment;
00146 typedef struct _MDThread _MDThread;
00147 typedef struct _MDThreadStack _MDThreadStack;
00148 typedef struct _MDSemaphore _MDSemaphore;
00149 typedef struct _MDDir _MDDir;
00150 #ifdef MOZ_UNICODE
00151 typedef struct _MDDirUTF16 _MDDirUTF16;
00152 #endif /* MOZ_UNICODE */
00153 typedef struct _MDFileDesc _MDFileDesc;
00154 typedef struct _MDProcess _MDProcess;
00155 typedef struct _MDFileMap _MDFileMap;
00156 
00157 #if defined(_PR_PTHREADS)
00158 
00159 /*
00160 ** The following definitions are unique to implementing NSPR using pthreads.
00161 ** Since pthreads defines most of the thread and thread synchronization
00162 ** stuff, this is a pretty small set.
00163 */
00164 
00165 #define PT_CV_NOTIFIED_LENGTH 6
00166 typedef struct _PT_Notified _PT_Notified;
00167 struct _PT_Notified
00168 {
00169     PRIntn length;              /* # of used entries in this structure */
00170     struct
00171     {
00172         PRCondVar *cv;          /* the condition variable notified */
00173         PRIntn times;           /* and the number of times notified */
00174     } cv[PT_CV_NOTIFIED_LENGTH];
00175     _PT_Notified *link;         /* link to another of these | NULL */
00176 };
00177 
00178 /*
00179  * bits defined for pthreads 'state' field 
00180  */
00181 #define PT_THREAD_DETACHED  0x01    /* thread can't be joined */
00182 #define PT_THREAD_GLOBAL    0x02    /* a global thread (unlikely) */
00183 #define PT_THREAD_SYSTEM    0x04    /* system (not user) thread */
00184 #define PT_THREAD_PRIMORD   0x08    /* this is the primordial thread */
00185 #define PT_THREAD_ABORTED   0x10    /* thread has been interrupted */
00186 #define PT_THREAD_GCABLE    0x20    /* thread is garbage collectible */
00187 #define PT_THREAD_SUSPENDED 0x40    /* thread has been suspended */
00188 #define PT_THREAD_FOREIGN   0x80    /* thread is not one of ours */
00189 #define PT_THREAD_BOUND     0x100    /* a bound-global thread */
00190 
00191 #define _PT_THREAD_INTERRUPTED(thr)                                   \
00192               (!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED))
00193 #define _PT_THREAD_BLOCK_INTERRUPT(thr)                        \
00194               (thr->interrupt_blocked = 1)
00195 #define _PT_THREAD_UNBLOCK_INTERRUPT(thr)               \
00196               (thr->interrupt_blocked = 0)
00197 
00198 #ifdef GC_LEAK_DETECTOR
00199 /* All threads are GCable. */
00200 #define _PT_IS_GCABLE_THREAD(thr) 1
00201 #else
00202 #define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE)
00203 #endif /* GC_LEAK_DETECTOR */
00204 
00205 /* 
00206 ** Possible values for thread's suspend field
00207 ** Note that the first two can be the same as they are really mutually exclusive,
00208 ** i.e. both cannot be happening at the same time. We have two symbolic names
00209 ** just as a mnemonic.
00210 **/
00211 #define PT_THREAD_RESUMED   0x80    /* thread has been resumed */
00212 #define PT_THREAD_SETGCABLE 0x100   /* set the GCAble flag */
00213 
00214 #if defined(DEBUG)
00215 
00216 typedef struct PTDebug
00217 {
00218     PRTime timeStarted;
00219     PRUintn locks_created, locks_destroyed;
00220     PRUintn locks_acquired, locks_released;
00221     PRUintn cvars_created, cvars_destroyed;
00222     PRUintn cvars_notified, delayed_cv_deletes;
00223 } PTDebug;
00224 
00225 #endif /* defined(DEBUG) */
00226 
00227 NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
00228 
00229 #else /* defined(_PR_PTHREADS) */
00230 
00231 NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
00232 
00233 /*
00234 ** This section is contains those parts needed to implement NSPR on
00235 ** platforms in general. One would assume that the pthreads implementation
00236 ** included lots of the same types, at least conceptually.
00237 */
00238 
00239 /*
00240  * Local threads only.  No multiple CPU support and hence all the
00241  * following routines are no-op.
00242  */
00243 #ifdef _PR_LOCAL_THREADS_ONLY
00244 
00245 #define        _PR_MD_SUSPEND_THREAD(thread)        
00246 #define        _PR_MD_RESUME_THREAD(thread)        
00247 #define        _PR_MD_SUSPEND_CPU(cpu)        
00248 #define        _PR_MD_RESUME_CPU(cpu)        
00249 #define        _PR_MD_BEGIN_SUSPEND_ALL()        
00250 #define        _PR_MD_END_SUSPEND_ALL()        
00251 #define        _PR_MD_BEGIN_RESUME_ALL()        
00252 #define        _PR_MD_END_RESUME_ALL()
00253 #define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE
00254 
00255 #endif
00256 
00257 typedef struct _PRCPUQueue _PRCPUQueue;
00258 typedef struct _PRCPU _PRCPU;
00259 typedef struct _MDCPU _MDCPU;
00260 
00261 struct _PRCPUQueue {
00262     _MDLock  runQLock;          /* lock for the run + wait queues */
00263     _MDLock  sleepQLock;        /* lock for the run + wait queues */
00264     _MDLock  miscQLock;         /* lock for the run + wait queues */
00265 
00266     PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */
00267     PRUint32  runQReadyMask;
00268     PRCList sleepQ;
00269     PRIntervalTime sleepQmax;
00270     PRCList pauseQ;
00271     PRCList suspendQ;
00272     PRCList waitingToJoinQ;
00273 
00274     PRUintn   numCPUs;          /* number of CPUs using this Q */
00275 };
00276 
00277 struct _PRCPU {
00278     PRCList links;              /* link list of CPUs */
00279     PRUint32 id;                /* id for this CPU */
00280 
00281     union {
00282         PRInt32 bits;
00283         PRUint8 missed[4];
00284     } u;
00285     PRIntn where;               /* index into u.missed */
00286     PRPackedBool paused;        /* cpu is paused */
00287     PRPackedBool exit;          /* cpu should exit */
00288 
00289     PRThread *thread;           /* native thread for this CPUThread */
00290     PRThread *idle_thread;      /* user-level idle thread for this CPUThread */
00291 
00292     PRIntervalTime last_clock;  /* the last time we went into 
00293                                  * _PR_ClockInterrupt() on this CPU
00294                                  */
00295 
00296     _PRCPUQueue *queue;
00297 
00298     _MDCPU md;
00299 };
00300 
00301 typedef struct _PRInterruptTable {
00302     const char *name;
00303     PRUintn missed_bit;
00304     void (*handler)(void);
00305 } _PRInterruptTable;
00306 
00307 #define _PR_CPU_PTR(_qp) \
00308     ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links)))
00309 
00310 #if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \
00311         && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY))
00312 #define _MD_GET_ATTACHED_THREAD()        (_PR_MD_CURRENT_THREAD())
00313 #endif
00314 
00315 #ifdef _PR_LOCAL_THREADS_ONLY 
00316 
00317 NSPR_API(struct _PRCPU *)              _pr_currentCPU;
00318 NSPR_API(PRThread *)                   _pr_currentThread;
00319 NSPR_API(PRThread *)                   _pr_lastThread;
00320 NSPR_API(PRInt32)                      _pr_intsOff;
00321 
00322 #define _MD_CURRENT_CPU()               (_pr_currentCPU)
00323 #define _MD_SET_CURRENT_CPU(_cpu)       (_pr_currentCPU = (_cpu))
00324 #define _MD_CURRENT_THREAD()            (_pr_currentThread)
00325 #define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
00326 #define _MD_LAST_THREAD()               (_pr_lastThread)
00327 #define _MD_SET_LAST_THREAD(t)          (_pr_lastThread = t)
00328 
00329 #ifndef XP_MAC
00330 #define _MD_GET_INTSOFF()               (_pr_intsOff)
00331 #define _MD_SET_INTSOFF(_val)           (_pr_intsOff = _val)
00332 #endif
00333 
00334 
00335 /* The unbalanced curly braces in these two macros are intentional */
00336 #define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is);
00337 #define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); }
00338 
00339 #endif /* _PR_LOCAL_THREADS_ONLY */
00340 
00341 extern PRInt32                  _native_threads_only;
00342 
00343 #if defined(_PR_GLOBAL_THREADS_ONLY)
00344 
00345 #define _MD_GET_INTSOFF() 0
00346 #define _MD_SET_INTSOFF(_val)
00347 #define _PR_INTSOFF(_is)
00348 #define _PR_FAST_INTSON(_is)
00349 #define _PR_INTSON(_is)
00350 #define _PR_THREAD_LOCK(_thread)
00351 #define _PR_THREAD_UNLOCK(_thread)
00352 #define _PR_RUNQ_LOCK(cpu)
00353 #define _PR_RUNQ_UNLOCK(cpu)
00354 #define _PR_SLEEPQ_LOCK(thread)
00355 #define _PR_SLEEPQ_UNLOCK(thread)
00356 #define _PR_MISCQ_LOCK(thread)
00357 #define _PR_MISCQ_UNLOCK(thread)
00358 #define _PR_CPU_LIST_LOCK()
00359 #define _PR_CPU_LIST_UNLOCK()
00360 
00361 #define _PR_ADD_RUNQ(_thread, _cpu, _pri)
00362 #define _PR_DEL_RUNQ(_thread)
00363 #define _PR_ADD_SLEEPQ(_thread, _timeout)
00364 #define _PR_DEL_SLEEPQ(_thread, _propogate)
00365 #define _PR_ADD_JOINQ(_thread, _cpu)
00366 #define _PR_DEL_JOINQ(_thread)
00367 #define _PR_ADD_SUSPENDQ(_thread, _cpu)
00368 #define _PR_DEL_SUSPENDQ(_thread)
00369 
00370 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
00371 
00372 #define _PR_IS_NATIVE_THREAD(thread) 1
00373 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
00374 
00375 #else
00376 
00377 #ifdef XP_MAC
00378 
00379 #define _PR_INTSOFF(_is)        _MD_INTSOFF(_is)
00380 
00381 #else /* XP_MAC */
00382 
00383 #define _PR_INTSOFF(_is) \
00384     PR_BEGIN_MACRO \
00385         (_is) = _PR_MD_GET_INTSOFF(); \
00386         _PR_MD_SET_INTSOFF(1); \
00387     PR_END_MACRO
00388 
00389 #endif /* XP_MAC */
00390 
00391 #define _PR_FAST_INTSON(_is) \
00392     PR_BEGIN_MACRO \
00393         _PR_MD_SET_INTSOFF(_is); \
00394     PR_END_MACRO
00395 
00396 #define _PR_INTSON(_is) \
00397     PR_BEGIN_MACRO \
00398         if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \
00399                 _PR_IntsOn((_PR_MD_CURRENT_CPU())); \
00400         _PR_MD_SET_INTSOFF(_is); \
00401     PR_END_MACRO
00402 
00403 #ifdef _PR_LOCAL_THREADS_ONLY 
00404 
00405 #define _PR_IS_NATIVE_THREAD(thread) 0
00406 #define _PR_THREAD_LOCK(_thread)
00407 #define _PR_THREAD_UNLOCK(_thread)
00408 #define _PR_RUNQ_LOCK(cpu)
00409 #define _PR_RUNQ_UNLOCK(cpu)
00410 #define _PR_SLEEPQ_LOCK(thread)
00411 #define _PR_SLEEPQ_UNLOCK(thread)
00412 #define _PR_MISCQ_LOCK(thread)
00413 #define _PR_MISCQ_UNLOCK(thread)
00414 #define _PR_CPU_LIST_LOCK()
00415 #define _PR_CPU_LIST_UNLOCK()
00416 
00417 #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
00418     PR_BEGIN_MACRO \
00419     PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
00420     _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
00421     PR_END_MACRO
00422 
00423 #define _PR_DEL_RUNQ(_thread) \
00424     PR_BEGIN_MACRO \
00425     _PRCPU *_cpu = _thread->cpu; \
00426     PRInt32 _pri = _thread->priority; \
00427     PR_REMOVE_LINK(&(_thread)->links); \
00428     if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
00429         _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
00430     PR_END_MACRO
00431 
00432 #define _PR_ADD_SLEEPQ(_thread, _timeout) \
00433     _PR_AddSleepQ(_thread, _timeout);   
00434 
00435 #define _PR_DEL_SLEEPQ(_thread, _propogate) \
00436     _PR_DelSleepQ(_thread, _propogate);  
00437 
00438 #define _PR_ADD_JOINQ(_thread, _cpu) \
00439     PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
00440 
00441 #define _PR_DEL_JOINQ(_thread) \
00442     PR_REMOVE_LINK(&(_thread)->links);
00443 
00444 #define _PR_ADD_SUSPENDQ(_thread, _cpu) \
00445     PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
00446 
00447 #define _PR_DEL_SUSPENDQ(_thread) \
00448     PR_REMOVE_LINK(&(_thread)->links);
00449 
00450 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
00451 
00452 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 0
00453 
00454 #else        /* _PR_LOCAL_THREADS_ONLY */
00455 
00456 /* These are for the "combined" thread model */
00457 
00458 #define _PR_THREAD_LOCK(_thread) \
00459     _PR_MD_LOCK(&(_thread)->threadLock);
00460 
00461 #define _PR_THREAD_UNLOCK(_thread) \
00462     _PR_MD_UNLOCK(&(_thread)->threadLock);
00463 
00464 #define _PR_RUNQ_LOCK(_cpu) \
00465     PR_BEGIN_MACRO \
00466     _PR_MD_LOCK(&(_cpu)->queue->runQLock );\
00467     PR_END_MACRO
00468     
00469 #define _PR_RUNQ_UNLOCK(_cpu) \
00470     PR_BEGIN_MACRO \
00471     _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\
00472     PR_END_MACRO
00473 
00474 #define _PR_SLEEPQ_LOCK(_cpu) \
00475     _PR_MD_LOCK(&(_cpu)->queue->sleepQLock );
00476 
00477 #define _PR_SLEEPQ_UNLOCK(_cpu) \
00478     _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock );
00479 
00480 #define _PR_MISCQ_LOCK(_cpu) \
00481     _PR_MD_LOCK(&(_cpu)->queue->miscQLock );
00482 
00483 #define _PR_MISCQ_UNLOCK(_cpu) \
00484     _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock );
00485 
00486 #define _PR_CPU_LIST_LOCK()                 _PR_MD_LOCK(&_pr_cpuLock)
00487 #define _PR_CPU_LIST_UNLOCK()               _PR_MD_UNLOCK(&_pr_cpuLock)
00488 
00489 #define QUEUE_RUN           0x1
00490 #define QUEUE_SLEEP         0x2
00491 #define QUEUE_JOIN          0x4
00492 #define QUEUE_SUSPEND       0x8
00493 #define QUEUE_LOCK          0x10
00494 
00495 #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
00496     PR_BEGIN_MACRO \
00497     PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
00498     _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
00499     PR_ASSERT((_thread)->queueCount == 0); \
00500     (_thread)->queueCount = QUEUE_RUN; \
00501     PR_END_MACRO
00502 
00503 #define _PR_DEL_RUNQ(_thread) \
00504     PR_BEGIN_MACRO \
00505     _PRCPU *_cpu = _thread->cpu; \
00506     PRInt32 _pri = _thread->priority; \
00507     PR_REMOVE_LINK(&(_thread)->links); \
00508     if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
00509         _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
00510     PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\
00511     (_thread)->queueCount = 0; \
00512     PR_END_MACRO
00513 
00514 #define _PR_ADD_SLEEPQ(_thread, _timeout) \
00515     PR_ASSERT((_thread)->queueCount == 0); \
00516     (_thread)->queueCount = QUEUE_SLEEP; \
00517     _PR_AddSleepQ(_thread, _timeout);  
00518 
00519 #define _PR_DEL_SLEEPQ(_thread, _propogate) \
00520     PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\
00521     (_thread)->queueCount = 0; \
00522     _PR_DelSleepQ(_thread, _propogate);  
00523 
00524 #define _PR_ADD_JOINQ(_thread, _cpu) \
00525     PR_ASSERT((_thread)->queueCount == 0); \
00526     (_thread)->queueCount = QUEUE_JOIN; \
00527     PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
00528 
00529 #define _PR_DEL_JOINQ(_thread) \
00530     PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\
00531     (_thread)->queueCount = 0; \
00532     PR_REMOVE_LINK(&(_thread)->links);
00533 
00534 #define _PR_ADD_SUSPENDQ(_thread, _cpu) \
00535     PR_ASSERT((_thread)->queueCount == 0); \
00536     (_thread)->queueCount = QUEUE_SUSPEND; \
00537     PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
00538 
00539 #define _PR_DEL_SUSPENDQ(_thread) \
00540     PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\
00541     (_thread)->queueCount = 0; \
00542     PR_REMOVE_LINK(&(_thread)->links);
00543 
00544 #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \
00545     (_thread)->cpu = (_newCPU);
00546 
00547 #define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE)
00548 #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
00549 
00550 #endif /* _PR_LOCAL_THREADS_ONLY */
00551 
00552 #endif /* _PR_GLOBAL_THREADS_ONLY */
00553 
00554 #define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1
00555 #define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0
00556 
00557 extern _PRInterruptTable _pr_interruptTable[];
00558 
00559 /* Bits for _pr_interruptState.u.missed[0,1] */
00560 #define _PR_MISSED_CLOCK    0x1
00561 #define _PR_MISSED_IO        0x2
00562 #define _PR_MISSED_CHILD    0x4
00563 
00564 extern void _PR_IntsOn(_PRCPU *cpu);
00565 
00566 NSPR_API(void) _PR_WakeupCPU(void);
00567 NSPR_API(void) _PR_PauseCPU(void);
00568 
00569 /************************************************************************/
00570 
00571 #define _PR_LOCK_LOCK(_lock) \
00572     _PR_MD_LOCK(&(_lock)->ilock);
00573 #define _PR_LOCK_UNLOCK(_lock) \
00574     _PR_MD_UNLOCK(&(_lock)->ilock);
00575     
00576 extern void _PR_UnblockLockWaiter(PRLock *lock);
00577 
00578 #define _PR_LOCK_PTR(_qp) \
00579     ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links)))
00580 
00581 /************************************************************************/
00582 
00583 #define _PR_CVAR_LOCK(_cvar) \
00584     _PR_MD_LOCK(&(_cvar)->ilock); 
00585 #define _PR_CVAR_UNLOCK(_cvar) \
00586     _PR_MD_UNLOCK(&(_cvar)->ilock);
00587 
00588 extern PRStatus _PR_WaitCondVar(
00589     PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
00590 extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
00591 
00592 NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky);
00593 
00594 /* PRThread.flags */
00595 #define _PR_SYSTEM          0x01
00596 #define _PR_INTERRUPT       0x02
00597 #define _PR_ATTACHED        0x04        /* created via PR_AttachThread */
00598 #define _PR_PRIMORDIAL      0x08        /* the thread that called PR_Init */
00599 #define _PR_ON_SLEEPQ       0x10        /* thread is on the sleepQ */
00600 #define _PR_ON_PAUSEQ       0x20        /* thread is on the pauseQ */
00601 #define _PR_SUSPENDING      0x40        /* thread wants to suspend */
00602 #define _PR_GLOBAL_SCOPE    0x80        /* thread is global scope */
00603 #define _PR_IDLE_THREAD     0x200       /* this is an idle thread        */
00604 #define _PR_GCABLE_THREAD   0x400       /* this is a collectable thread */
00605 #define _PR_BOUND_THREAD    0x800       /* a bound thread */
00606 #define _PR_INTERRUPT_BLOCKED      0x1000 /* interrupts blocked */
00607 
00608 /* PRThread.state */
00609 #define _PR_UNBORN       0
00610 #define _PR_RUNNABLE     1
00611 #define _PR_RUNNING      2
00612 #define _PR_LOCK_WAIT    3
00613 #define _PR_COND_WAIT    4
00614 #define _PR_JOIN_WAIT    5
00615 #define _PR_IO_WAIT      6
00616 #define _PR_SUSPENDED    7
00617 #define _PR_DEAD_STATE   8  /* for debugging */
00618 
00619 /* PRThreadStack.flags */
00620 #define _PR_STACK_VM            0x1    /* using vm instead of malloc */
00621 #define _PR_STACK_MAPPED        0x2    /* vm is mapped */
00622 #define _PR_STACK_PRIMORDIAL    0x4    /* stack for primordial thread */
00623 
00624 /* 
00625 ** If the default stcksize from the client is zero, we need to pick a machine
00626 ** dependent value.  This is only for standard user threads.  For custom threads,
00627 ** 0 has a special meaning.
00628 ** Adjust stackSize. Round up to a page boundary.
00629 */
00630 
00631 #ifndef _MD_MINIMUM_STACK_SIZE
00632 #define _MD_MINIMUM_STACK_SIZE     0
00633 #endif
00634 
00635 #if (!defined(HAVE_CUSTOM_USER_THREADS))
00636 #define        _PR_ADJUST_STACKSIZE(stackSize) \
00637         PR_BEGIN_MACRO \
00638     if (stackSize == 0) \
00639                 stackSize = _MD_DEFAULT_STACK_SIZE; \
00640     if (stackSize < _MD_MINIMUM_STACK_SIZE) \
00641                 stackSize = _MD_MINIMUM_STACK_SIZE; \
00642     stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \
00643     stackSize <<= _pr_pageShift; \
00644         PR_END_MACRO
00645 #else
00646 #define        _PR_ADJUST_STACKSIZE(stackSize)
00647 #endif
00648 
00649 #ifdef GC_LEAK_DETECTOR
00650 /* All threads are GCable. */
00651 #define _PR_IS_GCABLE_THREAD(thr) 1
00652 #else
00653 #define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD)
00654 #endif /* GC_LEAK_DETECTOR */
00655 
00656 #define _PR_PENDING_INTERRUPT(thr)                             \
00657               (!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_INTERRUPT))
00658 #define _PR_THREAD_BLOCK_INTERRUPT(thr)                 \
00659               (thr->flags |= _PR_INTERRUPT_BLOCKED)
00660 #define _PR_THREAD_UNBLOCK_INTERRUPT(thr)               \
00661               (thr->flags &= ~_PR_INTERRUPT_BLOCKED)
00662 
00663 #define _PR_THREAD_PTR(_qp) \
00664     ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links)))
00665 
00666 #define _PR_ACTIVE_THREAD_PTR(_qp) \
00667     ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active)))
00668 
00669 #define _PR_THREAD_CONDQ_PTR(_qp) \
00670     ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks)))
00671 
00672 #define _PR_THREAD_MD_TO_PTR(_md) \
00673     ((PRThread*) ((char*) (_md) - offsetof(PRThread,md)))
00674 
00675 #define _PR_THREAD_STACK_TO_PTR(_stack) \
00676     ((PRThread*) (_stack->thr))
00677 
00678 extern PRCList _pr_active_local_threadQ;
00679 extern PRCList _pr_active_global_threadQ;
00680 extern PRCList _pr_cpuQ;
00681 extern _MDLock  _pr_cpuLock;
00682 extern PRInt32 _pr_md_idle_cpus;
00683 
00684 #define _PR_ACTIVE_LOCAL_THREADQ()          _pr_active_local_threadQ
00685 #define _PR_ACTIVE_GLOBAL_THREADQ()         _pr_active_global_threadQ
00686 #define _PR_CPUQ()                          _pr_cpuQ
00687 #define _PR_RUNQ(_cpu)                      ((_cpu)->queue->runQ)
00688 #define _PR_RUNQREADYMASK(_cpu)             ((_cpu)->queue->runQReadyMask)
00689 #define _PR_SLEEPQ(_cpu)                    ((_cpu)->queue->sleepQ)
00690 #define _PR_SLEEPQMAX(_cpu)                 ((_cpu)->queue->sleepQmax)
00691 #define _PR_PAUSEQ(_cpu)                    ((_cpu)->queue->pauseQ)
00692 #define _PR_SUSPENDQ(_cpu)                  ((_cpu)->queue->suspendQ)
00693 #define _PR_WAITINGTOJOINQ(_cpu)            ((_cpu)->queue->waitingToJoinQ)
00694 
00695 extern PRUint32 _pr_recycleThreads;   /* Flag for behavior on thread cleanup */
00696 extern PRLock *_pr_deadQLock;
00697 extern PRUint32 _pr_numNativeDead;
00698 extern PRUint32 _pr_numUserDead;
00699 extern PRCList _pr_deadNativeQ;
00700 extern PRCList _pr_deadUserQ;
00701 #define _PR_DEADNATIVEQ     _pr_deadNativeQ
00702 #define _PR_DEADUSERQ       _pr_deadUserQ
00703 #define _PR_DEADQ_LOCK      PR_Lock(_pr_deadQLock);
00704 #define _PR_DEADQ_UNLOCK    PR_Unlock(_pr_deadQLock);
00705 #define _PR_INC_DEADNATIVE  (_pr_numNativeDead++)
00706 #define _PR_DEC_DEADNATIVE  (_pr_numNativeDead--)
00707 #define _PR_NUM_DEADNATIVE  (_pr_numNativeDead)
00708 #define _PR_INC_DEADUSER    (_pr_numUserDead++)
00709 #define _PR_DEC_DEADUSER    (_pr_numUserDead--)
00710 #define _PR_NUM_DEADUSER    (_pr_numUserDead)
00711 
00712 extern PRUint32 _pr_utid;
00713 
00714 extern struct _PRCPU  *_pr_primordialCPU;
00715 
00716 extern PRLock *_pr_activeLock;          /* lock for userActive and systemActive */
00717 extern PRInt32 _pr_userActive;          /* number of active user threads */
00718 extern PRInt32 _pr_systemActive;        /* number of active system threads */
00719 extern PRInt32 _pr_primordialExitCount; /* number of user threads left
00720                                          * before the primordial thread
00721                                          * can exit.  */
00722 extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for
00723                                            * notifying the primordial thread
00724                                            * when all other user threads
00725                                            * have terminated.  */
00726 
00727 extern PRUintn _pr_maxPTDs;
00728 
00729 extern PRLock *_pr_terminationCVLock;
00730 
00731 /*************************************************************************
00732 * Internal routines either called by PR itself or from machine-dependent *
00733 * code.                                                                  *
00734 *************************************************************************/
00735 
00736 extern void _PR_ClockInterrupt(void);
00737 
00738 extern void _PR_Schedule(void);
00739 extern void _PR_SetThreadPriority(
00740     PRThread* thread, PRThreadPriority priority);
00741 
00742 /***********************************************************************
00743 ** FUNCTION:  _PR_NewSegment()
00744 ** DESCRIPTION:
00745 **   Allocate a memory segment. The "size" value is rounded up to the
00746 **   native system page size and a page aligned portion of memory is
00747 **   returned.  This memory is not part of the malloc heap. If "vaddr" is
00748 **   not NULL then PR tries to allocate the segment at the desired virtual
00749 **   address.
00750 ** INPUTS:    size:  size of the desired memory segment
00751 **          vaddr:  address at which the newly aquired segment is to be
00752 **                  mapped into memory.
00753 ** OUTPUTS:   a memory segment is allocated, a PRSegment is allocated
00754 ** RETURN:    pointer to PRSegment
00755 ***********************************************************************/
00756 extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr);
00757 
00758 /***********************************************************************
00759 ** FUNCTION:  _PR_DestroySegment()
00760 ** DESCRIPTION:
00761 **   The memory segment and the PRSegment are freed
00762 ** INPUTS:    seg:  pointer to PRSegment to be freed
00763 ** OUTPUTS:   the the PRSegment and its associated memory segment are freed
00764 ** RETURN:    void
00765 ***********************************************************************/
00766 extern void _PR_DestroySegment(PRSegment *seg);
00767 
00768 extern PRThreadStack * _PR_NewStack(PRUint32 stackSize);
00769 extern void _PR_FreeStack(PRThreadStack *stack);
00770 extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me);
00771 extern void _PR_NotifyLockedThread (PRThread *thread);
00772 
00773 NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout);
00774 NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time);
00775 
00776 extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread);
00777 
00778 NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type,
00779                                      void (*start)(void *arg),
00780                                      void *arg,
00781                                      PRThreadPriority priority,
00782                                      PRThreadScope scope,
00783                                      PRThreadState state,
00784                                      PRUint32 stackSize,
00785                      PRUint32 flags);
00786 
00787 extern void _PR_NativeDestroyThread(PRThread *thread);
00788 extern void _PR_UserDestroyThread(PRThread *thread);
00789 
00790 extern PRThread* _PRI_AttachThread(
00791     PRThreadType type, PRThreadPriority priority,
00792     PRThreadStack *stack, PRUint32 flags);
00793 
00794 extern void _PRI_DetachThread(void);
00795 
00796 
00797 #define _PR_IO_PENDING(_thread) ((_thread)->io_pending)
00798 
00799 NSPR_API(void) _PR_MD_INIT_CPUS();
00800 #define    _PR_MD_INIT_CPUS _MD_INIT_CPUS
00801 
00802 NSPR_API(void) _PR_MD_WAKEUP_CPUS();
00803 #define    _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS
00804 
00805 /* Interrupts related */
00806 
00807 NSPR_API(void) _PR_MD_START_INTERRUPTS(void);
00808 #define    _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS
00809 
00810 NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void);
00811 #define    _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS
00812 
00813 NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void);
00814 #define    _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS
00815 
00816 NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void);
00817 #define    _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS
00818 
00819 NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void);
00820 #define    _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS
00821 
00822 NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
00823 #define    _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS
00824 
00825 /* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
00826  * awaken a thread which is waiting on a lock or cvar.
00827  */
00828 extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
00829 #define    _PR_MD_WAIT _MD_WAIT
00830 
00831 extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *);
00832 #define    _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER
00833 
00834 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
00835 NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void);
00836 #define    _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT
00837 #endif
00838 
00839 /* Stack debugging */
00840 NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone);
00841 #define    _PR_MD_INIT_STACK _MD_INIT_STACK
00842 
00843 NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts);
00844 #define    _PR_MD_CLEAR_STACK _MD_CLEAR_STACK
00845 
00846 /* CPU related */
00847 NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void);
00848 #define    _PR_MD_GET_INTSOFF _MD_GET_INTSOFF
00849 
00850 NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val);
00851 #define    _PR_MD_SET_INTSOFF _MD_SET_INTSOFF
00852 
00853 NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void);
00854 #define    _PR_MD_CURRENT_CPU _MD_CURRENT_CPU
00855 
00856 NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu);
00857 #define    _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU
00858 
00859 NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
00860 #define    _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU
00861 
00862 /*
00863  * Returns the number of threads awoken or 0 if a timeout occurred;
00864  */
00865 extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
00866 #define    _PR_MD_PAUSE_CPU _MD_PAUSE_CPU
00867 
00868 extern void _PR_MD_CLEANUP_BEFORE_EXIT(void);
00869 #define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT
00870 
00871 extern void _PR_MD_EXIT(PRIntn status);
00872 #define    _PR_MD_EXIT _MD_EXIT
00873 
00874 /* Locks related */
00875 
00876 NSPR_API(void) _PR_MD_INIT_LOCKS(void);
00877 #define    _PR_MD_INIT_LOCKS _MD_INIT_LOCKS
00878 
00879 NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md);
00880 #define    _PR_MD_NEW_LOCK _MD_NEW_LOCK
00881 
00882 NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md);
00883 #define    _PR_MD_FREE_LOCK _MD_FREE_LOCK
00884 
00885 NSPR_API(void) _PR_MD_LOCK(_MDLock *md);
00886 #define    _PR_MD_LOCK _MD_LOCK
00887 
00888 /* Return 0 on success, a nonzero value on failure. */
00889 NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md);
00890 #define    _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK
00891 
00892 NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md);
00893 #define    _PR_MD_UNLOCK _MD_UNLOCK
00894 
00895 NSPR_API(void) _PR_MD_IOQ_LOCK(void);
00896 #define    _PR_MD_IOQ_LOCK _MD_IOQ_LOCK
00897 
00898 NSPR_API(void) _PR_MD_IOQ_UNLOCK(void);
00899 #define    _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK
00900 
00901 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
00902 /* Semaphore related -- only for native threads */
00903 #ifdef HAVE_CVAR_BUILT_ON_SEM
00904 NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value);
00905 #define _PR_MD_NEW_SEM _MD_NEW_SEM
00906 
00907 NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md);
00908 #define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM
00909 
00910 NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM(
00911     _MDSemaphore *md, PRIntervalTime timeout);
00912 #define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM
00913 
00914 NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md);
00915 #define _PR_MD_WAIT_SEM _MD_WAIT_SEM
00916 
00917 NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md);
00918 #define _PR_MD_POST_SEM _MD_POST_SEM
00919 #endif /* HAVE_CVAR_BUILT_ON_SEM */
00920 
00921 #endif
00922 
00923 /* Condition Variables related -- only for native threads */
00924 
00925 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
00926 NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md);
00927 #define    _PR_MD_NEW_CV _MD_NEW_CV
00928 
00929 NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md);
00930 #define    _PR_MD_FREE_CV _MD_FREE_CV
00931 
00932 NSPR_API(void) _PR_MD_WAIT_CV(
00933     _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout);
00934 #define    _PR_MD_WAIT_CV _MD_WAIT_CV
00935 
00936 NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock);
00937 #define    _PR_MD_NOTIFY_CV _MD_NOTIFY_CV
00938 
00939 NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock);
00940 #define    _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV
00941 #endif /* _PR_LOCAL_THREADS_ONLY */
00942 
00943 /* Threads related */
00944 NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void);
00945 #define    _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD
00946 
00947 NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void);
00948 #define    _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD
00949 
00950 NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void);
00951 #define    _PR_MD_LAST_THREAD _MD_LAST_THREAD
00952 
00953 NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread);
00954 #define    _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD
00955 
00956 NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread);
00957 #define    _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD
00958 
00959 extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread);
00960 #define    _PR_MD_INIT_THREAD _MD_INIT_THREAD
00961 
00962 extern void _PR_MD_EXIT_THREAD(PRThread *thread);
00963 #define    _PR_MD_EXIT_THREAD _MD_EXIT_THREAD
00964 
00965 #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
00966 
00967 NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread);
00968 #define    _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD
00969 
00970 extern void _PR_MD_SUSPEND_THREAD(PRThread *thread);
00971 #define    _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD
00972 
00973 extern void _PR_MD_RESUME_THREAD(PRThread *thread);
00974 #define    _PR_MD_RESUME_THREAD _MD_RESUME_THREAD
00975 
00976 extern void _PR_MD_SUSPEND_CPU(_PRCPU  *cpu);
00977 #define    _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU
00978 
00979 extern void _PR_MD_RESUME_CPU(_PRCPU  *cpu);
00980 #define    _PR_MD_RESUME_CPU _MD_RESUME_CPU
00981 
00982 extern void _PR_MD_BEGIN_SUSPEND_ALL(void);
00983 #define    _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL
00984 
00985 extern void _PR_MD_END_SUSPEND_ALL(void);
00986 #define    _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL
00987 
00988 extern void _PR_MD_BEGIN_RESUME_ALL(void);
00989 #define    _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL
00990 
00991 extern void _PR_MD_END_RESUME_ALL(void);
00992 #define    _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL
00993 
00994 #if defined(IRIX) 
00995 NSPR_API(void) _PR_IRIX_CHILD_PROCESS(void);
00996 #endif        /* IRIX */
00997 
00998 #endif        /* !_PR_LOCAL_THREADS_ONLY */
00999 
01000 extern void _PR_MD_CLEAN_THREAD(PRThread *thread);
01001 #define    _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD
01002 
01003 #ifdef HAVE_CUSTOM_USER_THREADS
01004 extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
01005 #define    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD
01006 
01007 extern PRThread* _PR_MD_CREATE_USER_THREAD(
01008                         PRUint32 stacksize,
01009                         void (*start)(void *),
01010                         void *arg);
01011 #define    _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
01012 #endif
01013 
01014 extern PRStatus _PR_MD_CREATE_THREAD(
01015                         PRThread *thread, 
01016                         void (*start) (void *), 
01017                         PRThreadPriority priority,                      
01018                         PRThreadScope scope,
01019                         PRThreadState state,
01020                         PRUint32 stackSize);
01021 #define    _PR_MD_CREATE_THREAD _MD_CREATE_THREAD
01022 
01023 extern void _PR_MD_JOIN_THREAD(_MDThread *md);
01024 #define    _PR_MD_JOIN_THREAD _MD_JOIN_THREAD
01025 
01026 extern void _PR_MD_END_THREAD(void);
01027 #define    _PR_MD_END_THREAD _MD_END_THREAD
01028 
01029 extern void _PR_MD_YIELD(void);
01030 #define    _PR_MD_YIELD _MD_YIELD
01031 
01032 extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
01033 #define    _PR_MD_SET_PRIORITY _MD_SET_PRIORITY
01034 
01035 NSPR_API(void) _PR_MD_SUSPENDALL(void);
01036 #define    _PR_MD_SUSPENDALL _MD_SUSPENDALL
01037 
01038 NSPR_API(void) _PR_MD_RESUMEALL(void);
01039 #define    _PR_MD_RESUMEALL _MD_RESUMEALL
01040 
01041 extern void _PR_MD_INIT_CONTEXT(
01042     PRThread *thread, char *top, void (*start) (void), PRBool *status);
01043 #define    _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT
01044 
01045 extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread);
01046 #define    _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT
01047 
01048 extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread);
01049 #define    _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT
01050 
01051 /* Segment related */
01052 extern void _PR_MD_INIT_SEGS(void);
01053 #define    _PR_MD_INIT_SEGS _MD_INIT_SEGS
01054 
01055 extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr);
01056 #define    _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT
01057 
01058 extern void _PR_MD_FREE_SEGMENT(PRSegment *seg);
01059 #define    _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT
01060 
01061 /* Directory enumeration related */
01062 extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name);
01063 #define    _PR_MD_OPEN_DIR _MD_OPEN_DIR
01064 
01065 extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags);
01066 #define    _PR_MD_READ_DIR _MD_READ_DIR
01067 
01068 extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md);
01069 #define    _PR_MD_CLOSE_DIR _MD_CLOSE_DIR
01070 
01071 /* Named semaphores related */
01072 extern PRSem * _PR_MD_OPEN_SEMAPHORE(
01073     const char *osname, PRIntn flags, PRIntn mode, PRUintn value);
01074 #define    _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE
01075 
01076 extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem);
01077 #define    _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE
01078 
01079 extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem);
01080 #define    _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE
01081 
01082 extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem);
01083 #define    _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE
01084 
01085 extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname);
01086 #define    _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE
01087 
01088 /* I/O related */
01089 extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd);
01090 #define    _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC
01091 
01092 #ifdef XP_MAC
01093 extern void _PR_MD_FREE_FILEDESC(PRFileDesc *fd);
01094 #define    _PR_MD_FREE_FILEDESC _MD_FREE_FILEDESC
01095 #endif
01096 
01097 extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
01098 #define    _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK
01099 
01100 /* File I/O related */
01101 extern PRInt32 _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode);
01102 #define    _PR_MD_OPEN _MD_OPEN
01103 
01104 extern PRInt32 _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode);
01105 #define    _PR_MD_OPEN_FILE _MD_OPEN_FILE
01106 
01107 extern PRInt32 _PR_MD_CLOSE_FILE(PRInt32 osfd);
01108 #define    _PR_MD_CLOSE_FILE _MD_CLOSE_FILE
01109 
01110 extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount);
01111 #define    _PR_MD_READ _MD_READ
01112 
01113 extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount);
01114 #define    _PR_MD_WRITE _MD_WRITE
01115 
01116 extern PRInt32 _PR_MD_WRITEV(
01117     PRFileDesc *fd, const struct PRIOVec *iov,
01118     PRInt32 iov_size, PRIntervalTime timeout);
01119 #define    _PR_MD_WRITEV _MD_WRITEV
01120 
01121 extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd);
01122 #define    _PR_MD_FSYNC _MD_FSYNC
01123 
01124 extern PRInt32 _PR_MD_DELETE(const char *name);
01125 #define        _PR_MD_DELETE _MD_DELETE
01126 
01127 extern PRInt32 _PR_MD_RENAME(const char *from, const char *to);
01128 #define _PR_MD_RENAME _MD_RENAME
01129 
01130 extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how);
01131 #define _PR_MD_ACCESS _MD_ACCESS
01132 
01133 extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf);
01134 #define _PR_MD_STAT _MD_STAT
01135 
01136 extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode);
01137 #define _PR_MD_MKDIR _MD_MKDIR
01138 
01139 extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode);
01140 #define _PR_MD_MAKE_DIR _MD_MAKE_DIR
01141 
01142 extern PRInt32 _PR_MD_RMDIR(const char *name);
01143 #define _PR_MD_RMDIR _MD_RMDIR
01144 
01145 #ifdef MOZ_UNICODE
01146 /* UTF16 File I/O related */
01147 extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name);
01148 #define    _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16
01149 
01150 extern PRInt32 _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode);
01151 #define    _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16
01152 
01153 extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags);
01154 #define    _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16
01155 
01156 extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md);
01157 #define    _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16
01158 
01159 extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info);
01160 #define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16
01161 #endif /* MOZ_UNICODE */
01162 
01163 /* Socket I/O related */
01164 extern void _PR_MD_INIT_IO(void);
01165 #define    _PR_MD_INIT_IO _MD_INIT_IO
01166 
01167 extern PRInt32 _PR_MD_CLOSE_SOCKET(PRInt32 osfd);
01168 #define    _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET
01169 
01170 extern PRInt32 _PR_MD_CONNECT(
01171     PRFileDesc *fd, const PRNetAddr *addr,
01172     PRUint32 addrlen, PRIntervalTime timeout);
01173 #define    _PR_MD_CONNECT _MD_CONNECT
01174 
01175 extern PRInt32 _PR_MD_ACCEPT(
01176     PRFileDesc *fd, PRNetAddr *addr,
01177     PRUint32 *addrlen, PRIntervalTime timeout);
01178 #define    _PR_MD_ACCEPT _MD_ACCEPT
01179 
01180 extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
01181 #define    _PR_MD_BIND _MD_BIND
01182 
01183 extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog);
01184 #define    _PR_MD_LISTEN _MD_LISTEN
01185 
01186 extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how);
01187 #define    _PR_MD_SHUTDOWN _MD_SHUTDOWN
01188 
01189 extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, 
01190                                PRIntn flags, PRIntervalTime timeout);
01191 #define    _PR_MD_RECV _MD_RECV
01192 
01193 extern PRInt32 _PR_MD_SEND(
01194     PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, 
01195     PRIntervalTime timeout);
01196 #define    _PR_MD_SEND _MD_SEND
01197 
01198 extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PRInt32 *newSock, 
01199                                 PRNetAddr **raddr, void *buf, PRInt32 amount,
01200                                 PRIntervalTime timeout);
01201 #define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ
01202 
01203 #ifdef WIN32
01204 extern PRInt32 _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, 
01205                                 PRUint32 *addrlen, PRIntervalTime timeout,
01206                                 PRBool fast,
01207                                 _PR_AcceptTimeoutCallback callback,
01208                                 void *callbackArg);
01209 
01210 extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PRInt32 *newSock, 
01211                                 PRNetAddr **raddr, void *buf, PRInt32 amount,
01212                                 PRIntervalTime timeout, PRBool fast,
01213                                 _PR_AcceptTimeoutCallback callback,
01214                                 void *callbackArg);
01215 
01216 extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PRInt32 s, PRInt32 ls);
01217 #define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT
01218 #endif /* WIN32 */
01219 
01220 extern PRInt32 _PR_MD_SENDFILE(
01221     PRFileDesc *sock, PRSendFileData *sfd, 
01222        PRInt32 flags, PRIntervalTime timeout);
01223 #define _PR_MD_SENDFILE _MD_SENDFILE
01224 
01225 extern PRStatus _PR_MD_GETSOCKNAME(
01226     PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
01227 #define    _PR_MD_GETSOCKNAME _MD_GETSOCKNAME
01228 
01229 extern PRStatus _PR_MD_GETPEERNAME(
01230     PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
01231 #define    _PR_MD_GETPEERNAME _MD_GETPEERNAME
01232 
01233 extern PRStatus _PR_MD_GETSOCKOPT(
01234     PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
01235 #define    _PR_MD_GETSOCKOPT _MD_GETSOCKOPT
01236 
01237 extern PRStatus _PR_MD_SETSOCKOPT(
01238     PRFileDesc *fd, PRInt32 level, PRInt32 optname,
01239     const char* optval, PRInt32 optlen);
01240 #define    _PR_MD_SETSOCKOPT _MD_SETSOCKOPT
01241 
01242 extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption(
01243     PRFileDesc *fd, PRSocketOptionData *data);
01244 
01245 extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption(
01246     PRFileDesc *fd, const PRSocketOptionData *data);
01247 
01248 extern PRInt32 _PR_MD_RECVFROM(
01249     PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
01250     PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
01251 #define    _PR_MD_RECVFROM _MD_RECVFROM
01252 
01253 extern PRInt32 _PR_MD_SENDTO(
01254     PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
01255     const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
01256 #define    _PR_MD_SENDTO _MD_SENDTO
01257 
01258 extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PRInt32 *osfd);
01259 #define    _PR_MD_SOCKETPAIR _MD_SOCKETPAIR
01260 
01261 extern PRInt32 _PR_MD_SOCKET(int af, int type, int flags);
01262 #define    _PR_MD_SOCKET _MD_SOCKET
01263 
01264 extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd);
01265 #define    _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE
01266 
01267 extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd);
01268 #define    _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE
01269 
01270 extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds,
01271                                                                                         PRIntervalTime timeout);
01272 #define    _PR_MD_PR_POLL _MD_PR_POLL
01273 
01274 /*
01275  * Initialize fd->secret->inheritable for a newly created fd.
01276  * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd)
01277  * was created by NSPR and hence has the OS-dependent default
01278  * inheritable attribute.  If 'imported' is true, the osfd was
01279  * not created by NSPR and hence a system call is required to
01280  * query its inheritable attribute.  Since we may never need to
01281  * know the inheritable attribute of a fd, a platform may choose
01282  * to initialize fd->secret->inheritable of an imported fd to
01283  * _PR_TRI_UNKNOWN and only pay the cost of the system call
01284  * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary.
01285  */
01286 extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported);
01287 #define    _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE
01288 
01289 extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable);
01290 #define    _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE
01291 
01292 
01293 #define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \
01294         if (_PR_PENDING_INTERRUPT(me)) { \
01295                 me->flags &= ~_PR_INTERRUPT; \
01296                 PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \
01297         } else { \
01298                 PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \
01299         }                                                        
01300                 
01301 extern void *_PR_MD_GET_SP(PRThread *thread);
01302 #define    _PR_MD_GET_SP _MD_GET_SP
01303 
01304 #endif /* defined(_PR_PTHREADS) */
01305 
01306 /************************************************************************/
01307 /*************************************************************************
01308 ** The remainder of the definitions are shared by pthreads and the classic
01309 ** NSPR code. These too may be conditionalized.
01310 *************************************************************************/
01311 /************************************************************************/
01312 
01313 extern PROffset32 _PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence);
01314 #define    _PR_MD_LSEEK _MD_LSEEK
01315 
01316 extern PROffset64 _PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence);
01317 #define    _PR_MD_LSEEK64 _MD_LSEEK64
01318 
01319 extern PRInt32 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info);
01320 #define _PR_MD_GETFILEINFO _MD_GETFILEINFO
01321 
01322 extern PRInt32 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info);
01323 #define _PR_MD_GETFILEINFO64 _MD_GETFILEINFO64
01324 
01325 extern PRInt32 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info);
01326 #define _PR_MD_GETOPENFILEINFO _MD_GETOPENFILEINFO
01327 
01328 extern PRInt32 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info);
01329 #define _PR_MD_GETOPENFILEINFO64 _MD_GETOPENFILEINFO64
01330 
01331 
01332 /*****************************************************************************/
01333 /************************** File descriptor caching **************************/
01334 /*****************************************************************************/
01335 extern void _PR_InitFdCache(void);
01336 extern void _PR_CleanupFdCache(void);
01337 extern PRFileDesc *_PR_Getfd(void);
01338 extern void _PR_Putfd(PRFileDesc *fd);
01339 
01340 /*
01341  * These flags are used by NSPR temporarily in the poll
01342  * descriptor's out_flags field to record the mapping of
01343  * NSPR's poll flags to the system poll flags.
01344  *
01345  * If _PR_POLL_READ_SYS_WRITE bit is set, it means the
01346  * PR_POLL_READ flag specified by the topmost layer is
01347  * mapped to the WRITE flag at the system layer.  Similarly
01348  * for the other three _PR_POLL_XXX_SYS_YYY flags.  It is
01349  * assumed that the PR_POLL_EXCEPT flag doesn't get mapped
01350  * to other flags.
01351  */
01352 #define _PR_POLL_READ_SYS_READ     0x1
01353 #define _PR_POLL_READ_SYS_WRITE    0x2
01354 #define _PR_POLL_WRITE_SYS_READ    0x4
01355 #define _PR_POLL_WRITE_SYS_WRITE   0x8
01356 
01357 /*
01358 ** These methods are coerced into file descriptor methods table
01359 ** when the intended service is inappropriate for the particular
01360 ** type of file descriptor.
01361 */
01362 extern PRIntn _PR_InvalidInt(void);
01363 extern PRInt16 _PR_InvalidInt16(void);
01364 extern PRInt64 _PR_InvalidInt64(void);
01365 extern PRStatus _PR_InvalidStatus(void);
01366 extern PRFileDesc *_PR_InvalidDesc(void);
01367 
01368 extern PRIOMethods _pr_faulty_methods;
01369 
01370 /*
01371 ** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union
01372 ** whose 'family' field is set.  It returns the size of the union
01373 ** member corresponding to the specified address family.
01374 */
01375 
01376 extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr);
01377 
01378 #if defined(_PR_INET6)
01379 
01380 #define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr)
01381 
01382 #elif defined(_PR_HAVE_MD_SOCKADDR_IN6)
01383 
01384 /*
01385 ** Under the following conditions:
01386 ** 1. _PR_INET6 is not defined;
01387 ** 2. _PR_INET6_PROBE is defined;
01388 ** 3. struct sockaddr_in6 has nonstandard fields at the end
01389 **    (e.g., on Solaris 8),
01390 ** (_addr)->ipv6 is smaller than struct sockaddr_in6, and
01391 ** hence we can't pass sizeof((_addr)->ipv6) to socket
01392 ** functions such as connect because they would fail with
01393 ** EINVAL.
01394 **
01395 ** To pass the correct socket address length to socket
01396 ** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and
01397 ** define struct _md_sockaddr_in6 to be isomorphic to
01398 ** struct sockaddr_in6.
01399 */
01400 
01401 #if defined(XP_UNIX) || defined(XP_OS2_EMX)
01402 #define PR_NETADDR_SIZE(_addr)                                 \
01403         ((_addr)->raw.family == PR_AF_INET              \
01404         ? sizeof((_addr)->inet)                                \
01405         : ((_addr)->raw.family == PR_AF_INET6    \
01406         ? sizeof(struct _md_sockaddr_in6)        \
01407         : sizeof((_addr)->local)))
01408 #else
01409 #define PR_NETADDR_SIZE(_addr)                                 \
01410         ((_addr)->raw.family == PR_AF_INET              \
01411         ? sizeof((_addr)->inet)                                \
01412         : sizeof(struct _md_sockaddr_in6))
01413 #endif /* defined(XP_UNIX) */
01414 
01415 #else
01416 
01417 #if defined(XP_UNIX) || defined(XP_OS2_EMX)
01418 #define PR_NETADDR_SIZE(_addr)                                 \
01419         ((_addr)->raw.family == PR_AF_INET              \
01420         ? sizeof((_addr)->inet)                                \
01421         : ((_addr)->raw.family == PR_AF_INET6    \
01422         ? sizeof((_addr)->ipv6)                                \
01423         : sizeof((_addr)->local)))
01424 #else
01425 #define PR_NETADDR_SIZE(_addr)                                 \
01426         ((_addr)->raw.family == PR_AF_INET              \
01427         ? sizeof((_addr)->inet)                                \
01428         : sizeof((_addr)->ipv6))
01429 #endif /* defined(XP_UNIX) */
01430 
01431 #endif /* defined(_PR_INET6) */
01432 
01433 extern PRStatus _PR_MapOptionName(
01434     PRSockOption optname, PRInt32 *level, PRInt32 *name);
01435 extern void _PR_InitThreads(
01436     PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs);
01437 
01438 struct PRLock {
01439 #if defined(_PR_PTHREADS)
01440     pthread_mutex_t mutex;          /* the underlying lock */
01441     _PT_Notified notified;          /* array of conditions notified */
01442     PRBool locked;                  /* whether the mutex is locked */
01443     pthread_t owner;                /* if locked, current lock owner */
01444 #elif defined(_PR_BTHREADS)
01445     sem_id    semaphoreID;      /* the underlying lock */
01446     int32     benaphoreCount;          /* number of people in lock */
01447     thread_id owner;            /* current lock owner */
01448 #else /* not pthreads or Be threads */
01449     PRCList links;                  /* linkage for PRThread.lockList */
01450     struct PRThread *owner;         /* current lock owner */
01451     PRCList waitQ;                  /* list of threads waiting for lock */
01452     PRThreadPriority priority;      /* priority of lock */ 
01453     PRThreadPriority boostPriority; /* boosted priority of lock owner */
01454     _MDLock ilock;                  /* Internal Lock to protect user-level fields */
01455 #endif
01456 };
01457 
01458 extern void _PR_InitLocks(void);
01459 
01460 struct PRCondVar {
01461     PRLock *lock;               /* associated lock that protects the condition */
01462 #if defined(_PR_PTHREADS)
01463     pthread_cond_t cv;          /* underlying pthreads condition */
01464     PRInt32 notify_pending;     /* CV has destroy pending notification */
01465 #elif defined(_PR_BTHREADS)
01466     sem_id    sem;              /* the underlying lock */
01467     sem_id    handshakeSem;     /* the lock for 'notify'-threads waiting for confirmation */
01468     sem_id    signalSem;        /* the lock for threads waiting for someone to notify */
01469     volatile int32    nw;       /* the number waiting */
01470     volatile int32    ns;       /* the number signalling */
01471     long signalBenCount;        /* the number waiting on the underlying sem */
01472 #else /* not pthreads or Be threads */
01473     PRCList condQ;              /* Condition variable wait Q */
01474     _MDLock ilock;              /* Internal Lock to protect condQ */
01475     _MDCVar md;
01476 #endif
01477 };
01478 
01479 /************************************************************************/
01480 
01481 struct PRMonitor {
01482     const char* name;           /* monitor name for debugging */
01483 #if defined(_PR_PTHREADS)
01484     PRLock lock;                /* the lock structure */
01485     pthread_t owner;            /* the owner of the lock or invalid */
01486     PRCondVar *cvar;            /* condition variable queue */
01487 #else  /* defined(_PR_PTHREADS) */
01488     PRCondVar *cvar;            /* associated lock and condition variable queue */
01489 #endif /* defined(_PR_PTHREADS) */
01490     PRUint32 entryCount;        /* # of times re-entered */
01491 };
01492 
01493 /************************************************************************/
01494 
01495 struct PRSemaphore {
01496 #if defined(_PR_BTHREADS)
01497     sem_id  sem;
01498     int32   benaphoreCount;
01499 #else
01500     PRCondVar *cvar;        /* associated lock and condition variable queue */
01501     PRUintn count;            /* the value of the counting semaphore */
01502     PRUint32 waiters;            /* threads waiting on the semaphore */
01503 #if defined(_PR_PTHREADS)
01504 #else  /* defined(_PR_PTHREADS) */
01505     _MDSemaphore md;
01506 #endif /* defined(_PR_PTHREADS) */
01507 #endif /* defined(_PR_BTHREADS) */
01508 };
01509 
01510 NSPR_API(void) _PR_InitSem(void);
01511 
01512 /*************************************************************************/
01513 
01514 struct PRSem {
01515 #ifdef _PR_HAVE_POSIX_SEMAPHORES
01516     sem_t *sem;
01517 #elif defined(_PR_HAVE_SYSV_SEMAPHORES)
01518     int semid;
01519 #elif defined(WIN32)
01520     HANDLE sem;
01521 #else
01522     PRInt8 notused;
01523 #endif
01524 };
01525 
01526 /*************************************************************************/
01527 
01528 struct PRStackStr {
01529     /* head MUST be at offset 0; assembly language code relies on this */
01530 #if defined(AIX)
01531     volatile PRStackElem prstk_head;
01532 #else
01533     PRStackElem prstk_head;
01534 #endif
01535 
01536     PRLock *prstk_lock;
01537     char *prstk_name;
01538 };
01539 
01540 /************************************************************************/
01541 
01542 /* XXX this needs to be exported (sigh) */
01543 struct PRThreadStack {
01544     PRCList links;
01545     PRUintn flags;
01546 
01547     char *allocBase;            /* base of stack's allocated memory */
01548     PRUint32 allocSize;         /* size of stack's allocated memory */
01549     char *stackBottom;          /* bottom of stack from C's point of view */
01550     char *stackTop;             /* top of stack from C's point of view */
01551     PRUint32 stackSize;         /* size of usable portion of the stack */
01552 
01553     PRSegment *seg;
01554         PRThread* thr;          /* back pointer to thread owning this stack */
01555 
01556 #if defined(_PR_PTHREADS)
01557 #else /* defined(_PR_PTHREADS) */
01558     _MDThreadStack md;
01559 #endif /* defined(_PR_PTHREADS) */
01560 };
01561 
01562 extern void _PR_DestroyThreadPrivate(PRThread*);
01563 
01564 typedef void (PR_CALLBACK *_PRStartFn)(void *);
01565 
01566 struct PRThread {
01567     PRUint32 state;                 /* thread's creation state */
01568     PRThreadPriority priority;      /* apparent priority, loosly defined */
01569 
01570     void *arg;                      /* argument to the client's entry point */
01571     _PRStartFn startFunc;           /* the root of the client's thread */
01572 
01573     PRThreadStack *stack;           /* info about thread's stack (for GC) */
01574     void *environment;              /* pointer to execution environment */
01575 
01576     PRThreadDumpProc dump;          /* dump thread info out */
01577     void *dumpArg;                  /* argument for the dump function */
01578 
01579     /*
01580     ** Per thread private data
01581     */
01582     PRUint32 tpdLength;             /* thread's current vector length */
01583     void **privateData;             /* private data vector or NULL */
01584     PRErrorCode errorCode;          /* current NSPR error code | zero */
01585     PRInt32 osErrorCode;            /* mapping of errorCode | zero */
01586     PRIntn  errorStringLength;      /* textLength from last call to PR_SetErrorText() */
01587     PRInt32 errorStringSize;        /* malloc()'d size of buffer | zero */
01588     char *errorString;              /* current error string | NULL */
01589 
01590 #if defined(_PR_PTHREADS)
01591     pthread_t id;                   /* pthread identifier for the thread */
01592     PRBool okToDelete;              /* ok to delete the PRThread struct? */
01593     PRCondVar *waiting;             /* where the thread is waiting | NULL */
01594     void *sp;                       /* recorded sp for garbage collection */
01595     PRThread *next, *prev;          /* simple linked list of all threads */
01596     PRUint32 suspend;               /* used to store suspend and resume flags */
01597 #ifdef PT_NO_SIGTIMEDWAIT
01598     pthread_mutex_t suspendResumeMutex;
01599     pthread_cond_t suspendResumeCV;
01600 #endif
01601     PRUint32 interrupt_blocked;     /* interrupt blocked */
01602     struct pollfd *syspoll_list;    /* Unix polling list used by PR_Poll */
01603     PRUint32 syspoll_count;         /* number of elements in syspoll_list */
01604 #if defined(_PR_POLL_WITH_SELECT)
01605     int *selectfd_list;             /* Unix fd's that PR_Poll selects on */
01606     PRUint32 selectfd_count;        /* number of elements in selectfd_list */
01607 #endif
01608 #elif defined(_PR_BTHREADS)
01609     PRUint32 flags;
01610     _MDThread md;
01611     PRBool io_pending;
01612     PRInt32 io_fd;
01613     PRBool io_suspended;
01614 #else /* not pthreads or Be threads */
01615     _MDLock threadLock;             /* Lock to protect thread state variables.
01616                                      * Protects the following fields:
01617                                      *     state
01618                                      *     priority
01619                                      *     links
01620                                      *     wait
01621                                      *     cpu
01622                                      */
01623     PRUint32 queueCount;
01624     PRUint32 waitCount;
01625 
01626     PRCList active;                 /* on list of all active threads        */
01627     PRCList links;
01628     PRCList waitQLinks;             /* when thread is PR_Wait'ing */
01629     PRCList lockList;               /* list of locks currently holding */
01630     PRIntervalTime sleep;           /* sleep time when thread is sleeping */
01631     struct _wait {
01632         struct PRLock *lock;
01633         struct PRCondVar *cvar;
01634     } wait;
01635 
01636     PRUint32 id;
01637     PRUint32 flags;
01638     PRUint32 no_sched;              /* Don't schedule the thread to run.
01639                                      * This flag has relevance only when
01640                                      * multiple NSPR CPUs are created.
01641                                      * When a thread is de-scheduled, there
01642                                      * is a narrow window of time in which
01643                                      * the thread is put on the run queue
01644                                      * but the scheduler is actually using
01645                                      * the stack of this thread.  It is safe
01646                                      * to run this thread on a different CPU
01647                                      * only when its stack is not in use on
01648                                      * any other CPU.  The no_sched flag is
01649                                      * set during this interval to prevent
01650                                      * the thread from being scheduled on a
01651                                      * different CPU.
01652                                      */
01653 
01654     /* thread termination condition variable for join */
01655     PRCondVar *term;
01656 
01657     _PRCPU *cpu;                    /* cpu to which this thread is bound    */
01658     PRUint32 threadAllocatedOnStack;/* boolean */
01659 
01660     /* When an async IO is in progress and a second async IO cannot be 
01661      * initiated, the io_pending flag is set to true.  Some platforms will
01662      * not use the io_pending flag.  If the io_pending flag is true, then
01663      * io_fd is the OS-file descriptor on which IO is pending.
01664      */
01665     PRBool io_pending;
01666     PRInt32 io_fd;
01667  
01668     /* If a timeout occurs or if an outstanding IO is interrupted and the
01669      * OS doesn't support a real cancellation (NT or MAC), then the 
01670      * io_suspended flag will be set to true.  The thread will be resumed
01671      * but may run into trouble issuing additional IOs until the io_pending
01672      * flag can be cleared 
01673      */
01674     PRBool io_suspended;
01675 
01676     _MDThread md;
01677 #endif
01678 };
01679 
01680 struct PRProcessAttr {
01681     PRFileDesc *stdinFd;
01682     PRFileDesc *stdoutFd;
01683     PRFileDesc *stderrFd;
01684     char *currentDirectory;
01685     char *fdInheritBuffer;
01686     PRSize fdInheritBufferSize;
01687     PRSize fdInheritBufferUsed;
01688 };
01689 
01690 struct PRProcess {
01691     _MDProcess md;
01692 };
01693 
01694 struct PRFileMap {
01695     PRFileDesc *fd;
01696     PRFileMapProtect prot;
01697     _MDFileMap md;
01698 };
01699 
01700 /************************************************************************/
01701 
01702 /*
01703 ** File descriptors of the NSPR layer can be in one of the
01704 ** following states (stored in the 'state' field of struct
01705 ** PRFilePrivate):
01706 ** - _PR_FILEDESC_OPEN: The OS fd is open.
01707 ** - _PR_FILEDESC_CLOSED: The OS fd is closed.  The PRFileDesc
01708 **   is still open but is unusable.  The only operation allowed
01709 **   on the PRFileDesc is PR_Close().
01710 ** - _PR_FILEDESC_FREED: The OS fd is closed and the PRFileDesc
01711 **   structure is freed.
01712 */
01713 
01714 #define _PR_FILEDESC_OPEN       0xaaaaaaaa    /* 1010101... */
01715 #define _PR_FILEDESC_CLOSED     0x55555555    /* 0101010... */
01716 #define _PR_FILEDESC_FREED      0x11111111
01717 
01718 /*
01719 ** A boolean type with an additional "unknown" state
01720 */
01721 
01722 typedef enum {
01723     _PR_TRI_TRUE = 1,
01724     _PR_TRI_FALSE = 0,
01725     _PR_TRI_UNKNOWN = -1
01726 } _PRTriStateBool;
01727 
01728 struct PRFilePrivate {
01729     PRInt32 state;
01730     PRBool nonblocking;
01731     _PRTriStateBool inheritable;
01732     PRFileDesc *next;
01733     PRIntn lockCount;   /*   0: not locked
01734                          *  -1: a native lockfile call is in progress
01735                          * > 0: # times the file is locked */
01736 #ifdef _PR_HAVE_PEEK_BUFFER
01737     char *peekBuffer;
01738     PRInt32 peekBufSize;
01739     PRInt32 peekBytes;
01740 #endif
01741 #if !defined(_PR_HAVE_O_APPEND)
01742     PRBool  appendMode; /* Some platforms don't have O_APPEND or its
01743                          * equivalent, so they have to seek to end of
01744                          * file on write if the file was opened in
01745                          * append mode.  See Bugzilla 4090, 276330. */
01746 #endif
01747     _MDFileDesc md;
01748 #ifdef _PR_NEED_SECRET_AF
01749     PRUint16 af;        /* If the platform's implementation of accept()
01750                          * requires knowing the address family of the 
01751                       * socket, we save the address family here. */
01752 #endif
01753 };
01754 
01755 struct PRDir {
01756     PRDirEntry d;
01757     _MDDir md;
01758 };
01759 
01760 #ifdef MOZ_UNICODE
01761 struct PRDirUTF16 { 
01762     PRDirEntry d; 
01763     _MDDirUTF16 md; 
01764 }; 
01765 #endif /* MOZ_UNICODE */
01766 
01767 extern void _PR_InitSegs(void);
01768 extern void _PR_InitStacks(void);
01769 extern void _PR_InitTPD(void);
01770 extern void _PR_InitMem(void);
01771 extern void _PR_InitEnv(void);
01772 extern void _PR_InitCMon(void);
01773 extern void _PR_InitIO(void);
01774 extern void _PR_InitLog(void);
01775 extern void _PR_InitNet(void);
01776 extern void _PR_InitClock(void);
01777 extern void _PR_InitLinker(void);
01778 extern void _PR_InitAtomic(void);
01779 extern void _PR_InitCPUs(void);
01780 extern void _PR_InitDtoa(void);
01781 extern void _PR_InitTime(void);
01782 extern void _PR_InitMW(void);
01783 extern void _PR_InitRWLocks(void);
01784 extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me);
01785 extern void _PR_CleanupThread(PRThread *thread);
01786 extern void _PR_CleanupCallOnce(void);
01787 extern void _PR_CleanupMW(void);
01788 extern void _PR_CleanupTime(void);
01789 extern void _PR_CleanupDtoa(void);
01790 extern void _PR_ShutdownLinker(void);
01791 extern void _PR_CleanupEnv(void);
01792 extern void _PR_CleanupIO(void);
01793 extern void _PR_CleanupNet(void);
01794 extern void _PR_CleanupLayerCache(void);
01795 extern void _PR_CleanupStacks(void);
01796 #ifdef WINNT
01797 extern void _PR_CleanupCPUs(void);
01798 #endif
01799 extern void _PR_CleanupThreads(void);
01800 extern void _PR_CleanupTPD(void);
01801 extern void _PR_Cleanup(void);
01802 extern void _PR_LogCleanup(void);
01803 extern void _PR_InitLayerCache(void);
01804 #ifdef GC_LEAK_DETECTOR
01805 extern void _PR_InitGarbageCollector(void);
01806 #endif
01807 
01808 extern PRBool _pr_initialized;
01809 extern void _PR_ImplicitInitialization(void);
01810 extern PRBool _PR_Obsolete(const char *obsolete, const char *preferred);
01811 
01812 /************************************************************************/
01813 
01814 struct PRSegment {
01815     void *vaddr;
01816     PRUint32 size;
01817     PRUintn flags;
01818 #if defined(_PR_PTHREADS)
01819 #else  /* defined(_PR_PTHREADS) */
01820     _MDSegment md;
01821 #endif /* defined(_PR_PTHREADS) */
01822 };
01823 
01824 /* PRSegment.flags */
01825 #define _PR_SEG_VM    0x1
01826 
01827 /************************************************************************/
01828 
01829 extern PRInt32 _pr_pageSize;
01830 extern PRInt32 _pr_pageShift;
01831 
01832 extern PRLogModuleInfo *_pr_clock_lm;
01833 extern PRLogModuleInfo *_pr_cmon_lm;
01834 extern PRLogModuleInfo *_pr_io_lm;
01835 extern PRLogModuleInfo *_pr_cvar_lm;
01836 extern PRLogModuleInfo *_pr_mon_lm;
01837 extern PRLogModuleInfo *_pr_linker_lm;
01838 extern PRLogModuleInfo *_pr_sched_lm;
01839 extern PRLogModuleInfo *_pr_thread_lm;
01840 extern PRLogModuleInfo *_pr_gc_lm;
01841 
01842 extern PRFileDesc *_pr_stdin;
01843 extern PRFileDesc *_pr_stdout;
01844 extern PRFileDesc *_pr_stderr;
01845 
01846 /* Zone allocator */
01847 /*
01848 ** The zone allocator code has hardcoded pthread types and
01849 ** functions, so it can only be used in the pthreads version.
01850 ** This can be fixed by replacing the hardcoded pthread types
01851 ** and functions with macros that expand to the native thread
01852 ** types and functions on each platform.
01853 */
01854 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
01855 #define _PR_ZONE_ALLOCATOR
01856 #endif
01857 
01858 #ifdef _PR_ZONE_ALLOCATOR
01859 extern void _PR_InitZones(void);
01860 extern void _PR_DestroyZones(void);
01861 #endif
01862 
01863 /* Overriding malloc, free, etc. */
01864 #if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \
01865         && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \
01866         && !defined(PURIFY) \
01867         && !defined(DARWIN) \
01868         && !defined(NEXTSTEP) \
01869         && !defined(QNX) \
01870         && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS))
01871 #define _PR_OVERRIDE_MALLOC
01872 #endif
01873 
01874 /*************************************************************************
01875 * External machine-dependent code provided by each OS.                     *                                                                     *
01876 *************************************************************************/
01877 
01878 /* Initialization related */
01879 extern void _PR_MD_EARLY_INIT(void);
01880 #define    _PR_MD_EARLY_INIT _MD_EARLY_INIT
01881 
01882 extern void _PR_MD_INTERVAL_INIT(void);
01883 #define    _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT
01884 
01885 NSPR_API(void) _PR_MD_FINAL_INIT(void);
01886 #define    _PR_MD_FINAL_INIT _MD_FINAL_INIT
01887 
01888 /* Process control */
01889 
01890 extern PRProcess * _PR_MD_CREATE_PROCESS(
01891     const char *path,
01892     char *const *argv,
01893     char *const *envp,
01894     const PRProcessAttr *attr);
01895 #define    _PR_MD_CREATE_PROCESS _MD_CREATE_PROCESS
01896 
01897 extern PRStatus _PR_MD_DETACH_PROCESS(PRProcess *process);
01898 #define    _PR_MD_DETACH_PROCESS _MD_DETACH_PROCESS
01899 
01900 extern PRStatus _PR_MD_WAIT_PROCESS(PRProcess *process, PRInt32 *exitCode);
01901 #define    _PR_MD_WAIT_PROCESS _MD_WAIT_PROCESS
01902 
01903 extern PRStatus _PR_MD_KILL_PROCESS(PRProcess *process);
01904 #define    _PR_MD_KILL_PROCESS _MD_KILL_PROCESS        
01905 
01906 /* Current Time */
01907 NSPR_API(PRTime) _PR_MD_NOW(void);
01908 #define    _PR_MD_NOW _MD_NOW
01909 
01910 /* Environment related */
01911 extern char* _PR_MD_GET_ENV(const char *name);
01912 #define    _PR_MD_GET_ENV _MD_GET_ENV
01913 
01914 extern PRIntn _PR_MD_PUT_ENV(const char *name);
01915 #define    _PR_MD_PUT_ENV _MD_PUT_ENV
01916 
01917 /* Atomic operations */
01918 
01919 extern void _PR_MD_INIT_ATOMIC(void);
01920 #define    _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC
01921 
01922 extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *);
01923 #define    _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT
01924 
01925 extern PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *, PRInt32);
01926 #define    _PR_MD_ATOMIC_ADD _MD_ATOMIC_ADD
01927 
01928 extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *);
01929 #define    _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT
01930 
01931 extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32);
01932 #define    _PR_MD_ATOMIC_SET _MD_ATOMIC_SET
01933 
01934 /* Garbage collection */
01935 
01936 /*
01937 ** Save the registers that the GC would find interesting into the thread
01938 ** "t". isCurrent will be non-zero if the thread state that is being
01939 ** saved is the currently executing thread. Return the address of the
01940 ** first register to be scanned as well as the number of registers to
01941 ** scan in "np".
01942 **
01943 ** If "isCurrent" is non-zero then it is allowed for the thread context
01944 ** area to be used as scratch storage to hold just the registers
01945 ** necessary for scanning.
01946 */
01947 extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np);
01948 
01949 /* Time intervals */
01950 
01951 extern PRIntervalTime _PR_MD_GET_INTERVAL(void);
01952 #define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL
01953 
01954 extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void);
01955 #define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC
01956 
01957 /* Affinity masks */
01958 
01959 extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask );
01960 #define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK
01961 
01962 extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask);
01963 #define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK
01964 
01965 /* File locking */
01966 
01967 extern PRStatus _PR_MD_LOCKFILE(PRInt32 osfd);
01968 #define    _PR_MD_LOCKFILE _MD_LOCKFILE
01969 
01970 extern PRStatus _PR_MD_TLOCKFILE(PRInt32 osfd);
01971 #define    _PR_MD_TLOCKFILE _MD_TLOCKFILE
01972 
01973 extern PRStatus _PR_MD_UNLOCKFILE(PRInt32 osfd);
01974 #define    _PR_MD_UNLOCKFILE _MD_UNLOCKFILE
01975 
01976 /* Memory-mapped files */
01977 
01978 extern PRStatus _PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size);
01979 #define _PR_MD_CREATE_FILE_MAP _MD_CREATE_FILE_MAP
01980 
01981 extern PRInt32 _PR_MD_GET_MEM_MAP_ALIGNMENT(void);
01982 #define _PR_MD_GET_MEM_MAP_ALIGNMENT _MD_GET_MEM_MAP_ALIGNMENT
01983 
01984 extern void * _PR_MD_MEM_MAP(
01985     PRFileMap *fmap,
01986     PROffset64 offset,
01987     PRUint32 len);
01988 #define _PR_MD_MEM_MAP _MD_MEM_MAP
01989 
01990 extern PRStatus _PR_MD_MEM_UNMAP(void *addr, PRUint32 size);
01991 #define _PR_MD_MEM_UNMAP _MD_MEM_UNMAP
01992 
01993 extern PRStatus _PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap);
01994 #define _PR_MD_CLOSE_FILE_MAP _MD_CLOSE_FILE_MAP
01995 
01996 /* Named Shared Memory */
01997 
01998 /*
01999 ** Declare PRSharedMemory.
02000 */
02001 struct PRSharedMemory 
02002 {
02003     char        *ipcname; /* after conversion to native */
02004     PRSize      size;  /* from open */
02005     PRIntn      mode;  /* from open */
02006     PRIntn      flags; /* from open */
02007 #if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY)
02008     int         id;
02009 #elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY)
02010     int         id;
02011 #elif defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)
02012     HANDLE      handle;
02013 #else
02014     PRUint32    nothing; /* placeholder, nothing behind here */
02015 #endif
02016     PRUint32    ident; /* guard word at end of struct */
02017 #define _PR_SHM_IDENT 0xdeadbad
02018 };
02019                                                       
02020 extern PRSharedMemory * _MD_OpenSharedMemory( 
02021     const char *name,
02022     PRSize      size,
02023     PRIntn      flags,
02024     PRIntn      mode
02025 );
02026 #define _PR_MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
02027 
02028 extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags );
02029 #define _PR_MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
02030 
02031 extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr );
02032 #define _PR_MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
02033 
02034 extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm );
02035 #define _PR_MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
02036 
02037 extern PRStatus _MD_DeleteSharedMemory( const char *name );
02038 #define _PR_MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
02039 
02040 extern PRFileMap* _md_OpenAnonFileMap( 
02041     const char *dirName,
02042     PRSize      size,
02043     PRFileMapProtect prot
02044 );
02045 #define _PR_MD_OPEN_ANON_FILE_MAP _md_OpenAnonFileMap
02046 
02047 extern PRStatus _md_ExportFileMapAsString(
02048     PRFileMap *fm,
02049     PRSize    bufSize,
02050     char      *buf
02051 );
02052 #define _PR_MD_EXPORT_FILE_MAP_AS_STRING _md_ExportFileMapAsString
02053 
02054 extern PRFileMap * _md_ImportFileMapFromString(
02055     const char *fmstring
02056 );
02057 #define _PR_MD_IMPORT_FILE_MAP_FROM_STRING _md_ImportFileMapFromString
02058 
02059 
02060 
02061 /* Interprocess communications (IPC) */
02062 
02063 /*
02064  * The maximum length of an NSPR IPC name, including the
02065  * terminating null byte.
02066  */
02067 #define PR_IPC_NAME_SIZE 1024
02068 
02069 /*
02070  * Types of NSPR IPC objects
02071  */
02072 typedef enum {
02073     _PRIPCSem,  /* semaphores */
02074     _PRIPCShm   /* shared memory segments */
02075 } _PRIPCType;
02076 
02077 /*
02078  * Make a native IPC name from an NSPR IPC name.
02079  */
02080 extern PRStatus _PR_MakeNativeIPCName(
02081     const char *name,  /* NSPR IPC name */
02082     char *result,      /* result buffer */
02083     PRIntn size,       /* size of result buffer */
02084     _PRIPCType type    /* type of IPC object */
02085 );
02086 
02087 /* Socket call error code */
02088 
02089 NSPR_API(PRInt32) _PR_MD_GET_SOCKET_ERROR(void);
02090 #define    _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR
02091 
02092 /* Get name of current host */
02093 extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
02094 #define    _PR_MD_GETHOSTNAME _MD_GETHOSTNAME
02095 
02096 extern PRStatus _PR_MD_GETSYSINFO(PRSysInfo cmd, char *name, PRUint32 namelen);
02097 #define    _PR_MD_GETSYSINFO _MD_GETSYSINFO
02098 
02099 /* File descriptor inheritance */
02100 
02101 /*
02102  * If fd->secret->inheritable is _PR_TRI_UNKNOWN and we need to
02103  * know the inheritable attribute of the fd, call this function
02104  * to find that out.  This typically requires a system call.
02105  */
02106 extern void _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd);
02107 #define    _PR_MD_QUERY_FD_INHERITABLE _MD_QUERY_FD_INHERITABLE
02108 
02109 /* --- PR_GetRandomNoise() related things --- */
02110 
02111 extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size );
02112 #define _PR_MD_GET_RANDOM_NOISE(buf,size) _PR_MD_GetRandomNoise((buf),(size))
02113 extern PRSize _pr_CopyLowBits( void *dest, PRSize dstlen, void *src, PRSize srclen );
02114 
02115 /* end PR_GetRandomNoise() related */
02116 
02117 #ifdef XP_BEOS
02118 
02119 extern PRLock *_connectLock;
02120 
02121 typedef struct _ConnectListNode {
02122        PRInt32              osfd;
02123        PRNetAddr     addr;
02124        PRUint32      addrlen;
02125        PRIntervalTime       timeout;
02126 } ConnectListNode;
02127 
02128 extern ConnectListNode connectList[64];
02129 
02130 extern PRUint32 connectCount;
02131 
02132 #endif /* XP_BEOS */
02133 
02134 PR_END_EXTERN_C
02135 
02136 #endif /* primpl_h___ */