📄 primpl.h
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#ifndef primpl_h___#define primpl_h___/* * HP-UX 10.10's pthread.h (DCE threads) includes dce/cma.h, which * has: * #define sigaction _sigaction_sys * This macro causes chaos if signal.h gets included before pthread.h. * To be safe, we include pthread.h first. */#if defined(_PR_PTHREADS)#include <pthread.h>#endif#if defined(_PR_BTHREADS)#include <kernel/OS.h>#endif#ifdef WINNT/* Need to force service-pack 3 extensions to be defined by** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h.*/#ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0400#elif (_WIN32_WINNT < 0x0400) #undef _WIN32_WINNT #define _WIN32_WINNT 0x0400#endif /* _WIN32_WINNT */#endif /* WINNT */#include "nspr.h"#include "prpriv.h"typedef struct PRSegment PRSegment;#ifdef XP_MAC#include "prosdep.h"#include "probslet.h"#else#include "md/prosdep.h"#include "obsolete/probslet.h"#endif /* XP_MAC */#ifdef _PR_HAVE_POSIX_SEMAPHORES#include <semaphore.h>#elif defined(_PR_HAVE_SYSV_SEMAPHORES)#include <sys/sem.h>#endif/****************************************************************************** A Word about Model Dependent Function Naming Convention ************************************************************************************//*NSPR 2.0 must implement its function across a range of platforms including: MAC, Windows/16, Windows/95, Windows/NT, and severalvariants of Unix. Each implementation shares common code as well as having platform dependent portions. This standard describes howthe model dependent portions are to be implemented.In header file pr/include/primpl.h, each publicly declared platform dependent function is declared as:NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 );#define _PR_MD_FUNCTION _MD_FUNCTIONIn header file pr/include/md/<platform>/_<platform>.h, each #define'd macro is redefined as one of:#define _MD_FUNCTION <blanks>#define _MD_FUNCTION <expanded macro>#define _MD_FUNCTION <osFunction>#define _MD_FUNCTION <_MD_Function>Where:<blanks> is no definition at all. In this case, the function is not implemented and is never called for this platform. For example: #define _MD_INIT_CPUS()<expanded macro> is a C language macro expansion. For example: #define _MD_CLEAN_THREAD(_thread) \ PR_BEGIN_MACRO \ PR_DestroyCondVar(_thread->md.asyncIOCVar); \ PR_DestroyLock(_thread->md.asyncIOLock); \ PR_END_MACRO<osFunction> is some function implemented by the host operating system. For example: #define _MD_EXIT exit<_MD_function> is the name of a function implemented for this platform in pr/src/md/<platform>/<soruce>.c file. For example: #define _MD_GETFILEINFO _MD_GetFileInfoIn <source>.c, the implementation is:PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info);*/PR_BEGIN_EXTERN_Ctypedef struct _MDLock _MDLock;typedef struct _MDCVar _MDCVar;typedef struct _MDSegment _MDSegment;typedef struct _MDThread _MDThread;typedef struct _MDThreadStack _MDThreadStack;typedef struct _MDSemaphore _MDSemaphore;typedef struct _MDDir _MDDir;typedef struct _MDFileDesc _MDFileDesc;typedef struct _MDProcess _MDProcess;typedef struct _MDFileMap _MDFileMap;#if defined(_PR_PTHREADS)/*** The following definitions are unique to implementing NSPR using pthreads.** Since pthreads defines most of the thread and thread synchronization** stuff, this is a pretty small set.*/#define PT_CV_NOTIFIED_LENGTH 6typedef struct _PT_Notified _PT_Notified;struct _PT_Notified{ PRIntn length; /* # of used entries in this structure */ struct { PRCondVar *cv; /* the condition variable notified */ PRIntn times; /* and the number of times notified */ } cv[PT_CV_NOTIFIED_LENGTH]; _PT_Notified *link; /* link to another of these | NULL */};/* * bits defined for pthreads 'state' field */#define PT_THREAD_DETACHED 0x01 /* thread can't be joined */#define PT_THREAD_GLOBAL 0x02 /* a global thread (unlikely) */#define PT_THREAD_SYSTEM 0x04 /* system (not user) thread */#define PT_THREAD_PRIMORD 0x08 /* this is the primordial thread */#define PT_THREAD_ABORTED 0x10 /* thread has been interrupted */#define PT_THREAD_GCABLE 0x20 /* thread is garbage collectible */#define PT_THREAD_SUSPENDED 0x40 /* thread has been suspended */#define PT_THREAD_FOREIGN 0x80 /* thread is not one of ours */#define PT_THREAD_BOUND 0x100 /* a bound-global thread */#define _PT_THREAD_INTERRUPTED(thr) \ (!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED))#define _PT_THREAD_BLOCK_INTERRUPT(thr) \ (thr->interrupt_blocked = 1)#define _PT_THREAD_UNBLOCK_INTERRUPT(thr) \ (thr->interrupt_blocked = 0)#ifdef GC_LEAK_DETECTOR/* All threads are GCable. */#define _PT_IS_GCABLE_THREAD(thr) 1#else#define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE)#endif /* GC_LEAK_DETECTOR *//* ** Possible values for thread's suspend field** Note that the first two can be the same as they are really mutually exclusive,** i.e. both cannot be happening at the same time. We have two symbolic names** just as a mnemonic.**/#define PT_THREAD_RESUMED 0x80 /* thread has been resumed */#define PT_THREAD_SETGCABLE 0x100 /* set the GCAble flag */#if defined(DEBUG)typedef struct PTDebug{ PRTime timeStarted; PRUintn locks_created, locks_destroyed; PRUintn locks_acquired, locks_released; PRUintn cvars_created, cvars_destroyed; PRUintn cvars_notified, delayed_cv_deletes;} PTDebug;NSPR_API(void) PT_GetStats(PTDebug* here);NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);#elsetypedef PRUintn PTDebug;#define PT_GetStats(_p)#define PT_FPrintStats(_fd, _msg)#endif /* defined(DEBUG) */#else /* defined(_PR_PTHREADS) */typedef PRUintn PTDebug;#define PT_GetStats(_p)#define PT_FPrintStats(_fd, _msg)/*** This section is contains those parts needed to implement NSPR on** platforms in general. One would assume that the pthreads implementation** included lots of the same types, at least conceptually.*//* * Local threads only. No multiple CPU support and hence all the * following routines are no-op. */#ifdef _PR_LOCAL_THREADS_ONLY#define _PR_MD_SUSPEND_THREAD(thread) #define _PR_MD_RESUME_THREAD(thread) #define _PR_MD_SUSPEND_CPU(cpu) #define _PR_MD_RESUME_CPU(cpu) #define _PR_MD_BEGIN_SUSPEND_ALL() #define _PR_MD_END_SUSPEND_ALL() #define _PR_MD_BEGIN_RESUME_ALL() #define _PR_MD_END_RESUME_ALL()#define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE#endiftypedef struct _PRCPUQueue _PRCPUQueue;typedef struct _PRCPU _PRCPU;typedef struct _MDCPU _MDCPU;struct _PRCPUQueue { _MDLock runQLock; /* lock for the run + wait queues */ _MDLock sleepQLock; /* lock for the run + wait queues */ _MDLock miscQLock; /* lock for the run + wait queues */ PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */ PRUint32 runQReadyMask; PRCList sleepQ; PRIntervalTime sleepQmax; PRCList pauseQ; PRCList suspendQ; PRCList waitingToJoinQ; PRUintn numCPUs; /* number of CPUs using this Q */};struct _PRCPU { PRCList links; /* link list of CPUs */ PRUint32 id; /* id for this CPU */ union { PRInt32 bits; PRUint8 missed[4]; } u; PRIntn where; /* index into u.missed */ PRPackedBool paused; /* cpu is paused */ PRPackedBool exit; /* cpu should exit */ PRThread *thread; /* native thread for this CPUThread */ PRThread *idle_thread; /* user-level idle thread for this CPUThread */ PRIntervalTime last_clock; /* the last time we went into * _PR_ClockInterrupt() on this CPU */ _PRCPUQueue *queue; _MDCPU md;};typedef struct _PRInterruptTable { const char *name; PRUintn missed_bit; void (*handler)(void);} _PRInterruptTable;#define _PR_CPU_PTR(_qp) \ ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links)))#if !defined(IRIX) && !defined(WIN32)#define _MD_GET_ATTACHED_THREAD() (_PR_MD_CURRENT_THREAD())#endif#ifdef _PR_LOCAL_THREADS_ONLY NSPR_API(struct _PRCPU *) _pr_currentCPU;NSPR_API(PRThread *) _pr_currentThread;NSPR_API(PRThread *) _pr_lastThread;NSPR_API(PRInt32) _pr_intsOff;#define _MD_CURRENT_CPU() (_pr_currentCPU)#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = (_cpu))#define _MD_CURRENT_THREAD() (_pr_currentThread)#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))#define _MD_LAST_THREAD() (_pr_lastThread)#define _MD_SET_LAST_THREAD(t) (_pr_lastThread = t)#ifndef XP_MAC#define _MD_GET_INTSOFF() (_pr_intsOff)#define _MD_SET_INTSOFF(_val) (_pr_intsOff = _val)#endif/* The unbalanced curly braces in these two macros are intentional */#define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is);#define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); }#endif /* _PR_LOCAL_THREADS_ONLY */extern PRInt32 _native_threads_only;#if defined(_PR_GLOBAL_THREADS_ONLY)#define _MD_GET_INTSOFF() 0#define _MD_SET_INTSOFF(_val)#define _PR_INTSOFF(_is)#define _PR_FAST_INTSON(_is)#define _PR_INTSON(_is)#define _PR_THREAD_LOCK(_thread)#define _PR_THREAD_UNLOCK(_thread)#define _PR_RUNQ_LOCK(cpu)#define _PR_RUNQ_UNLOCK(cpu)#define _PR_SLEEPQ_LOCK(thread)#define _PR_SLEEPQ_UNLOCK(thread)#define _PR_MISCQ_LOCK(thread)#define _PR_MISCQ_UNLOCK(thread)#define _PR_CPU_LIST_LOCK()#define _PR_CPU_LIST_UNLOCK()#define _PR_ADD_RUNQ(_thread, _cpu, _pri)#define _PR_DEL_RUNQ(_thread)#define _PR_ADD_SLEEPQ(_thread, _timeout)#define _PR_DEL_SLEEPQ(_thread, _propogate)#define _PR_ADD_JOINQ(_thread, _cpu)#define _PR_DEL_JOINQ(_thread)#define _PR_ADD_SUSPENDQ(_thread, _cpu)#define _PR_DEL_SUSPENDQ(_thread)#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)#define _PR_IS_NATIVE_THREAD(thread) 1#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1#else#ifdef XP_MAC#define _PR_INTSOFF(_is) _MD_INTSOFF(_is)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -