2021-10-11 18:37:13 -03:00

126 lines
4.2 KiB
C

/* @(#) process.h 1.1 94/10/31 Copyr 1987 Sun Micro */
/* Copyright (C) 1987. Sun Microsystems, Inc. */
#ifndef _lwp_process_h
#define _lwp_process_h
/*
* Which queue or state a thread belongs to (if not on any queue)
* A thread never belongs to more than one queue.
*/
typedef enum lwp_state_t {
RS_UNBLOCKED =0, /* Runnable (__RunQ) */
RS_SEND =1, /* Blocked on a send (__SendQ) */
RS_RECEIVE =2, /* Blocked on a receive (__ReceiveQ) */
RS_SLEEP =3, /* Sleeping for finite time (__SleepQ) */
RS_MONITOR =4, /* Blocked on a monitor (__MonitorQ) */
RS_CONDVAR =5, /* Blocked on a condition var (__CondvarQ) */
RS_SUSPEND =6, /* Suspended (__SuspendQ) */
RS_ZOMBIE =7, /* Dead but memory kept around until msg reply */
RS_JOIN =8, /* Blocked on a join */
RS_UNINIT =9, /* Not on any queue, uninitialized */
} lwp_state_t;
/*
* Context block for lightweight process.
*/
typedef struct lwp_t {
struct lwp_t *lwp_next; /* list of processes blocked together */
object_type_t lwp_type; /* type (agt/lwp) (MUST BE 2'nd) */
machstate_t lwp_machstate; /* machine-dependent state */
qheader_t lwp_ctx; /* special context save/restore actions */
bool_t lwp_full; /* TRUE if rti resume, else coroutine */
bool_t lwp_suspended; /* TRUE if to be suspended */
enum lwp_state_t lwp_run; /* which queue holds the process */
enum lwp_err_t lwp_lwperrno; /* errors in primitives */
qheader_t lwp_messages; /* list of unreceived messages */
caddr_t lwp_blockedon; /* entity waited upon */
struct monitor_t *lwp_curmon; /* currently-held monitor */
int lwp_monlevel; /* nesting level of reentrant monitor */
qheader_t lwp_exchandles; /* stack of exception handlers */
qheader_t lwp_joinq; /* threads awaiting this thread's death */
int lwp_prio; /* scheduling priority, higher favored */
int lwp_flags; /* LWPSUSPEND|LWPSERVER|LWPNOLASTRITES */
int lwp_stack; /* stack arg, passed to LASTRITES agt */
int lwp_lock; /* for validity checks */
int lwp_cancel; /* for kernel: TRUE if unwanted */
caddr_t lwp_ref; /* o.s. reference key (owner proc) */
} lwp_t;
#define LWPNULL ((lwp_t *) 0)
#define NOBODY CHARNULL /* lwp_blockedon: not waiting on any object */
/*
* Manipulate client error setting/clearing
*/
#define SET_ERROR(proc, err) { \
if ((proc != LWPNULL)) { \
(proc)->lwp_lwperrno = err; \
} \
}
#define IS_ERROR() \
__Curproc ? (__Curproc->lwp_lwperrno != LE_NOERROR) : \
(panic("Curproc is null"), 0)
#define CLR_ERROR() { \
if ((__Curproc != LWPNULL)) { \
__Curproc->lwp_lwperrno = LE_NOERROR; \
} \
}
#define NUGPRIO 0 /* idle priority (no other lwp this low) */
/*
* Conditionally give up the processor if "prio" warrants it.
* Always UNLOCKED when it returns, either via WAIT or UNLOCK.
*/
#define YIELD_CPU(prio) { \
if (prio > __Curproc->lwp_prio) { \
WAIT(); \
} \
}
/*
* Remove the specified process from the run
* queue and set it's new state:
* which queue it will be blocked on and which object can unblock it
* (if applicable).
*/
#define BLOCK(pro, state, waiton) { \
REMX_ITEM(&__RunQ[pro->lwp_prio], pro); \
pro->lwp_run = state; \
pro->lwp_blockedon = (caddr_t)waiton; \
__Nrunnable--; \
}
/*
* Put a process back on the run queue. lwp_run prevents
* a wakeup from unblocking an unblocked process.
* Do this AFTER deueueing from whatever queue the process was on before.
* If the (blocked) process is suspended, we now alter its status
* to the suspended state (and __HighPrio remains the same since no new
* runnable process was added).
*/
#define UNBLOCK(dest) { \
if ((dest)->lwp_run != RS_UNBLOCKED) { \
if ((dest)->lwp_suspended) { \
INS_QUEUE(&__SuspendQ, dest); \
(dest)->lwp_run = RS_SUSPEND; \
} else { \
INS_QUEUE(&__RunQ[dest->lwp_prio], dest); \
(dest)->lwp_run = RS_UNBLOCKED; \
} \
(dest)->lwp_blockedon = NOBODY; \
} \
__Nrunnable++; \
}
extern qheader_t __SuspendQ; /* Queue of suspended processes */
extern int __LwpRunCnt; /* Number of lwp's in the system */
extern int __Nrunnable; /* number of runnable threads */
extern void __freeproc(); /* free lwp resources */
extern void __init_lwp(); /* initialize lwp library */
#endif /*!_lwp_process_h*/