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

165 lines
6.4 KiB
C

/* @(#) process.h 1.1 94/10/31 Copyr 1987 Sun Micro */
/* Copyright (C) 1987. Sun Microsystems, Inc. */
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify this source code without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* THIS PROGRAM CONTAINS SOURCE CODE COPYRIGHTED BY SUN MICROSYSTEMS, INC.
* AND IS LICENSED TO SUNSOFT, INC., A SUBSIDIARY OF SUN MICROSYSTEMS, INC.
* SUN MICROSYSTEMS, INC., MAKES NO REPRESENTATIONS ABOUT THE SUITABLITY
* OF SUCH SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT
* EXPRESS OR IMPLIED WARRANTY OF ANY KIND. SUN MICROSYSTEMS, INC. DISCLAIMS
* ALL WARRANTIES WITH REGARD TO SUCH SOURCE CODE, INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN
* NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT,
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM USE OF SUCH SOURCE CODE, REGARDLESS OF THE THEORY OF LIABILITY.
*
* This source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS
* SOURCE CODE OR ANY PART THEREOF.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#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 */
struct msg_t lwp_tag; /* message sent by this thread */
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 */
} 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->lwp_lwperrno != LE_NOERROR) \
#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) { \
__HighPrio = prio; \
WAIT(); \
} else { \
UNLOCK(); \
} \
}
/*
* 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) { \
ASSERT((dest) != __Curproc); \
INS_QUEUE(&__SuspendQ, dest); \
(dest)->lwp_run = RS_SUSPEND; \
} else { \
INS_QUEUE(&__RunQ[dest->lwp_prio], dest); \
__HighPrio = MAX(__HighPrio, (dest)->lwp_prio); \
(dest)->lwp_run = RS_UNBLOCKED; \
} \
(dest)->lwp_blockedon = NOBODY; \
} \
__Nrunnable++; \
}
extern qheader_t __SuspendQ; /* Queue of suspended processes */
extern qheader_t __SleepQ; /* place to put processes sleeping on an alarm */
extern qheader_t __ZombieQ; /* Queue of zombies (killed during send) */
extern int __LwpRunCnt; /* Number of lwp's in the system */
extern thread_t __Slaves[]; /* list of server threads */
extern int __SlaveThreads; /* index of free server thread */
extern int __NActiveSlaves; /* count of living slave threads */
extern int __Nrunnable; /* number of runnable threads */
extern void __freeproc(/* lwp */); /* free lwp resources */
extern void __rem_corpse(/* queue, corpse, error */); /* remove a dead lwp */
extern void __init_lwp(); /* initialize lwp library */
extern void __maincreate(); /* turn main into a l wp */
#endif /*!_lwp_process_h*/