nsprpub/pr/include/private/primpl.h

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

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

mercurial