Google
 

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