/* * Threads.h -- stubbed out PCR version */ #ifndef _P_THREADS_H #define _P_THREADS_H #include "BasicTypes.h" #include /* * These #defines are also in portbasics.h for C code generated by mimosa */ #define XR_setjmp(jb) setjmp((jb)) #define XR_longjmp(jb, rv) longjmp((jb), (rv)) #define XR_Thread struct XR_ThreadRep * /* breaks recursion in dcls */ /* * THE thread for pPCR */ extern struct XR_ThreadRep theOnlyThread; extern XR_Thread XR_currThread; /* * Time * * ... for cv timeouts, pausing, etc. */ typedef int XR_DBMsg; /* bogus declaration for type of XR_CallDebugger() */ typedef unsigned XR_Ticks; #define XR_TICKS_PER_SECOND 20 #define XR_MSECS_PER_TICK (1000/XR_TICKS_PER_SECOND) #define XR_USECS_PER_TICK (1000000/XR_TICKS_PER_SECOND) #define XR_WAIT_FOREVER ((XR_Ticks) 0) #define XR_END_OF_TIME ((XR_Ticks)(0xffffffff)) #define XR_DEFAULT_TMP_DIRECTORY "/tmp/" /* Priority */ typedef unsigned XR_Pri; typedef struct XR_MLRep { XR_Thread ml_holder; /* holds mon_lock */ } *XR_ML; /* * Condition Variables (CV's) */ typedef struct XR_CVRep { /* declarations deleted for psuedo-threads work */ XR_Ticks cv_timeout; /* timeout for waiting threads */ bool cv_abortable; /* aborts enabled? */ bool cv_wakeupWaiting; /* a wakeup is waiting */ } *XR_CV; /* * context save/restore */ #if defined(sparc) # define JMPBUFSIZE _JBLEN /* needs to be big enough */ # define XR_PC_FROM_JMP_BUF(b) (((XR_Pointer *)(b->jb_data))[0]) # define XR_FP_FROM_JMP_BUF(b) --> not used on sparc <-- # define XR_SP_FROM_JMP_BUF(b) (((XR_Pointer *)(b->jb_data))[2]) #endif typedef struct XR_JmpBufRep { unsigned jb_data[JMPBUFSIZE]; } *XR_JmpBuf; /* * signal/error interface * * * A handler proc is invoked * - as a result of a trap (in Unix, one of a collection of signals) * - explicitly by XR_CallHandler(...). * * When it is invoked: * It starts with an empty stack. * It can call XR_RestartHandlee(...) instead of returning. * It can terminate the thread by calling XR_Exit. * IF the handlee is prepared to resume, the handler can resume it * by just returning. * * A handler proc is registered with each thread, and is inherited across * XR_Fork calls. * * It is okay to register NIL; a NIL handler just calls the debugger. */ /* Args to Unix signal handler -- see */ typedef struct XR_TrapArgsRep { int ta_sig; int ta_code; struct sigcontext *ta_scp; XR_Pointer ta_addr; } *XR_TrapArgs; /* type code for handler */ typedef unsigned XR_HandlerWhich; /* 0 => not a handler call */ /* low values are reserved for machine- or OS- traps */ /* low-order bit => not resumable */ # define XR_HANDLER_WHICH_NULL 0 # define XR_HANDLER_WHICH_MK_FATAL(which) ((which) | 0x1) # define XR_HANDLER_WHICH_IS_FATAL(which) ((which) & 0x1) # define XR_HANDLER_WHICH_TRAP_UNIX (0x2) # define XR_HANDLER_WHICH_TRAP_UNIX_FATAL \ XR_HANDLER_WHICH_MK_FATAL(XR_HANDLER_WHICH_TRAP_UNIX) # define XR_HANDLER_WHICH_STACK_OVERFLOW \ XR_HANDLER_WHICH_MK_FATAL(1022) #define XR_HANDLER_WHICH_TRAP_LIM ((XR_HandlerWhich)(1024)) /* registered handler proc */ typedef void (*XR_HandlerProc)(/* XR_Thread handlee, -- obsolete, always XR_currThread XR_HandlerWhich which, -- exception type code XR_Pointer arg -- XR_TrapArgs for trap, else arbitrary XR_Pointer clientData -- client data registered with proc */); /* XR_HandlerData is private */ typedef struct XR_HandlerDataRep { XR_HandlerProc hd_proc; /* registered handler proc */ XR_Pointer hd_clientData; /* passed to proc when invoked */ XR_HandlerWhich hd_which; /* saved XR_HandlerProc `which' argument */ XR_Pointer hd_arg; /* saved XR_HandlerProc `arg' argument */ struct XR_JmpBufRep hd_resume; /* resume after trap or CallDebugger ... */ unsigned hd_result; /* ... by XR_longjmp(&hd_resume, hd_result) */ } * XR_HandlerData; /* Thread Data Structure, sort of */ typedef struct XR_ThreadRep { int t_this_is_only_a_dummy; #undef XR_Thread } * XR_Thread; /* * Checked Thread Data Structure -- includes ref and generation number */ typedef struct XR_CTRep { XR_Thread ct_thread; /* -> thread */ unsigned ct_gen; /* generation number */ } *XR_CT; /* * function declarations */ extern XR_Ticks XR_TicksSinceBoot (/* */); /* Return time in ticks since boot. Wraparound is ignored. */ extern XR_Ticks XR_MsecToTicks (/* msec */); /* unsigned msec; Convert milliseconds to ticks. Rounds up. Overflow if msec > LAST(unsigned)-1000. */ extern unsigned XR_TicksToMsec (/* ticks */); /* XR_Ticks ticks; Convert ticks to milliseconds. Undefined if it would overflow. */ extern void XR_InitializeMonitor (/* ml */); /* XR_ML ml; Initialize `ml'. Call only once, before handing out the object. */ extern void XR_MonitorEntry (/* XR_ML ml */); extern void XR_MonitorExit (/* XR_ML ml */); extern void XR_InitializeCondition (/* cv, timeout */); /* XR_CV cv; XR_Ticks timeout; Initialize `cv'. Call only once per variable. */ extern void XR_SetTimeout (/* cv, timeout */); /* XR_CV cv; XR_Ticks timeout; Set the timeout associated with `cv'. Has no effect on currently waiting threads. */ extern void XR_DisableTimeout (/* cv */); /* XR_CV cv; Disable timeouts for `cv'. Has no effect on currently waiting threads. */ extern void XR_EnableAborts (/* cv */); /* XR_CV cv; Enable aborts on `cv'. No effect on threads currently waiting. */ extern void XR_DisableAborts (/* cv */); /* XR_CV cv; Disable aborts on `cv'. No effect on threads currently waiting. */ extern int XR_WaitCV (/* cv, ml */); /* XR_CV cv; XR_ML ml; Wait for `cv'. Assumes `ml' is held; releases it while waiting. If `ml' is NIL, that's okay - this is a wait on an icv. Return 0 if okay, -1 if ABORTED. */ extern void XR_Notify (/* cv */); /* XR_CV cv; Notify `cv'. */ extern void XR_Broadcast (/* cv */); /* XR_CV cv; Broadcast `cv'. */ extern XR_DBMsg XR_CallDebugger(/* XR_Pointer arg */); /* Equivalent to XR_CallDebugger2(arg, XR_DB_MSG_CLIENT_REQUEST). */ extern XR_Pointer XR_ExtensionFree (/* x */); /* XR_Pointer x; Assuming x is the address of a frame extension allocated with XR_ExtensionAlloc, free it and return NIL. */ extern XR_Pri XR_GetPriority (); /* Return priority of current thread. */ extern void XR_SetPriority (/* pri */); /* XR_Pri pri; Set priority of current thread. */ extern void XR_Yield (/* */); /* Yield processor. */ extern void XR_GetCurrent (/* result */); /* struct XR_CTRep *result; Return the current thread in *result. */ extern void XR_Fork (/* struct XR_CTRep *result, XR_MesaProc mp */); extern XR_Pointer XR_JoinCT (/* ct */); /* XR_CT ct; JOIN with `ct' returning (pointer to) its results. The caller is presumed to know how many results to expect. If cp is an invalid thread, return ((XR_Pointer)(-1)), which is guaranteed not to be a valid pointer. */ extern int XR_PauseAbortable (/* ticks */); /* XR_Ticks ticks; Pause the specified number of ticks, with aborts enabled. Ticks may be XR_WAIT_FOREVER. Return 0 ordinarily, or -1 if aborted. */ extern bool XR_AbortPending (); /* Check whether an abort has been requested. This does not clear the p_abortRequest flag. */ extern int XR_CancelAbort (/* ct */); /* XR_CT ct; Cancel any abort request for `ct' (i.e. clear the t_abortRequest flag). If `ct' == NIL it means the current thread. Return 0 if okay, or -1 if `ct' is invalid. */ extern int XR_DetachCT (/* ct */); /* XR_CT ct; Detach `ct'. Return 0 if okay, or -1 if `ct' is invalid. */ extern int XR_AbortCT (/* ct */); /* XR_CT ct; Abort `ct'. Return 0 if okay, or -1 if `ct' is invalid. */ extern int XR_ValidateCT (/* ct */); /* XR_CT ct; Return 0 if okay, -1 if `ct' is invalid. */ /* * Terminate the world ... */ extern void XR_ExitWorld (/* int status */); /* Terminate PCR; in Unix(tm) this looks like _exit(status); to the invoker of PCR. Tries to free all allocated resources (e.g. system semaphores, swap file, ...). */ extern void XR_RestartHandlee(/* XR_Thread t, XR_JmpBuf where, unsigned result */); extern XR_Thread XR_GetNextHandlee(/* XR_Thread t */); extern void XR_RegisterThreadStartProc (/* startProc */); /* XR_MesaProc startProc; Register startProc as the "start proc" for this thread and its descendants. Ordinarily, the effect of XR_Fork(result, forkProc); is result = (*forkProc->mp_proc)(forkProc); After RegisterThreadStartProc(startProc) the effect will be result = (*startProc->mp_proc)(forkProc, startProc); allowing the startProc to catch uncaught signals, etc. It is okay to register NIL. */ bool XR_StackPushTest(/* int nbytes */); /* Return TRUE if it's possible to push nbytes onto the current stack without causing a thread stack overflow. */ #endif _P_THREADS_H