Trailing-Edge
-
PDP-10 Archives
-
decuslib10-08
-
43,50512/cproc.b36
There are no other files named cproc.b36 in the archive.
MODULE CPROC=
!Create a process block, stack, & everything else a process is known to need
!Also contains routines to clean up after process termination
BEGIN
!
!Table of Contents
!
FORWARD ROUTINE
CPROC, !Create a process
SAYDIE, !Say we're dead
REMINF, !Remove a deceased inferior
CHECKF; !Validate a pseudoprocess handle
!
!Library & Require files
!
REQUIRE 'INTR.REQ';
!
!Version info
!
THIS_IS [CPROC] VERSION[2] EDIT[3] DATE[10,OCT,79]
![3] Validate process handles
!
!Literals
!
LITERAL PTAB_LEN=20;
LITERAL JBREL=%O'44';
!
!Externals
!
EXTERNAL ROUTINE
CREATEPROC, !Set up stack
FREEFB, !RELEASE and free storage for a file block & decendants
TSICLF, !Clear pending clock requests for fork
FREE, !Release storage
ALLOC;
EXTERNAL
RUN: REF PROCESS_BLOCK, !Current process block
FREEOK, !First word of dynamic memory
CMDPBL: PROCESS_BLOCK; !Top level process block
!
!Global data
!
GLOBAL PTAB: VECTOR[PTAB_LEN];
!
! Macros
!
MACRO PREFIX='IPH' %;
!
!Routines
!
GLOBAL ROUTINE CPROC(RTN,ARGLST,STKL)=
!Create process
!Arguments:
!RTN: Top level routine to execute
!ARGLST: List of arguments (# of args following,arg,arg,arg...)
!STKL: # of words of stack to allocate
BEGIN
LOCAL PB: REF PROCESS_BLOCK;
LOCAL T;
MAP ARGLST: REF VECTOR;
PB=ALLOC((T=.STKL+P_LEN+.ARGLST[0]+1));
!Allocate space for process block and stack
! and argument list
PB[P$FREE]=.T; !Remember how much space to free later
T=.PB+P_LEN+.STKL; !Get origin of argument list storage place
INCR I FROM 0 TO .ARGLST[0] DO
(.T+.I)=.ARGLST[.I]; !Copy argument list
PB[P$STKL]=.STKL;
PB[P$STK]=.PB+P_LEN; !Store origin of stack
PB[P$SUPERIOR]=.RUN; !We are the superior to this process
IF .RUN[P$INFERIORS] EQL 0 THEN RUN[P$INFERIORS]=.PB !Start of linked list
ELSE BEGIN
LOCAL T: REF PROCESS_BLOCK;
T=.RUN[P$INFERIORS];
DO BEGIN
IF .T[P$LINK] EQL 0 THEN
BEGIN
T[P$LINK]=.PB; !Put at end of linked list
EXITLOOP
END;
T=.T[P$LINK]
END WHILE 1
END;
PB[P$WAIT]=0; !Not waiting for anything yet
!Put this process in the process table
IF (INCR I FROM 0 TO PTAB_LEN-1
DO (IF .PTAB[.I] EQL 0 THEN (PTAB[.I]=.PB;EXITLOOP -1;)))
EQL 0 THEN CRASH('No free processes');
CREATEPROC(.PB[P$STK],.STKL,SAYDIE,.RTN,.T); !Set up the stack
NOINTS((
BEGIN
LOCAL T: REF PROCESS_BLOCK;
MAP RUN: REF PROCESS_BLOCK;
T=.RUN; !Start at this process
DO BEGIN
IF .T[P$NEXT] EQL 0 THEN
BEGIN
T[P$NEXT]=.PB;
EXITLOOP;
END;
T=.T[P$NEXT];
END WHILE 1;
END;
));!NOINTS
.PB !Return address of process block
END; !CPROC
GLOBAL ROUTINE SAYDIE=
!Tell our superior of our demise
BEGIN
EXTERNAL ROUTINE
QUIT, !Signal superior that we gave up the ghost
STOP; !HALTF, MONRT., ...
EXTERNAL RUN: REF PROCESS_BLOCK;
IF .RUN[P$SUPERIOR] EQL 0 THEN STOP(); !Return to the monitor
QUIT(SS$_NORMAL); !Say we finished
END;
GLOBAL ROUTINE REMINF(AFORK)=
!Remove a process from all linked-lists and tables
!AFORK: address of process block (process must be an immediate inferior)
BEGIN
MAP AFORK: REF PROCESS_BLOCK;
EXTERNAL RUN: REF PROCESS_BLOCK;
LOCAL T: REF PROCESS_BLOCK;
LOCAL IB: REF INT_BLOCK;
LABEL FIND_PROCESS;
!Remove from process table
INCR I FROM 0 TO PTAB_LEN-1
DO IF .PTAB[.I] EQL .AFORK THEN (PTAB[.I]=0; EXITLOOP);
!Free up any pending temporary interrupt blocks
IF (IB=.AFORK[P$INTERRUPTS]) NEQ 0 THEN
BEGIN
LOCAL TIB: REF INT_BLOCK;
DO BEGIN
TIB=.IB[INT$NEXT]; !Save addr of next one
IF .IB[INT$TEMP] THEN FREE(.IB,INT_LEN)
END WHILE (IB=.TIB) NEQ 0;
END;
TSICLF(.AFORK); !Clear any pending clock requests
IF .RUN[P$INFERIORS] EQL .AFORK THEN
RUN[P$INFERIORS]=.AFORK[P$LINK] !Close the linked list
ELSE
FIND_PROCESS: BEGIN
IF (T=.RUN[P$INFERIORS]) EQL 0 THEN CRASH('REMINF--no inferior');
DO BEGIN !Chase the pointers to find the process
IF .T[P$LINK] EQL .AFORK THEN
BEGIN
T[P$LINK]=.AFORK[P$LINK];
LEAVE FIND_PROCESS
END;
END WHILE (T=.T[P$LINK]) NEQ 0;
CRASH('REMINF--not an inferior')
END;
IF (T=.AFORK[P$NDB]) NEQ 0 THEN FREEFB(.T); !Free his NDB
FREE(.AFORK,.AFORK[P$FREE]); !Give back the storage
END; !REMINF
GLOBAL ROUTINE CHECKF(PH)=
!Verify a process handle
!Return: WIN if OK, 0 if not
BEGIN
MAP PH: REF PROCESS_BLOCK;
SELECT .PH OF SET
[CMDPBL]: RETURN WIN; !This is the top level
[0]: RETURN 0; !This is nothing
[.FREEOK TO .JBREL]: INCR I FROM 0 TO PTAB_LEN-1
DO IF .PH EQL .PTAB[.I] THEN RETURN WIN;
TES;
INFO('Ignoring Invalid process handle');
0
END; !CHECKF
END ELUDOM