Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-08 - 43,50512/clock.b36
There are no other files named clock.b36 in the archive.
MODULE CLOCK=
!Routine to see if anything timed out
BEGIN

!
! Table of Contents
!
FORWARD ROUTINE
CLKCHK,		!Check for any clock requests that should go off now
TSIGNL,		!Put a clock request in the table
TSICAN,		!Remove a clock request
TSICLF,		!Clear pending clock requests for fork
UDT;		!Get time of day in NBS/Universal date-time format

!
! REQUIRE & LIBRARY files
!
REQUIRE 'INTR.REQ';

!
! Literals
!

!%IF NOT %DECLARED(CLKMAX) %THEN
COMPILETIME CLKMAX=25;
LITERAL TSICWO=3;		!TSICAN removed a timer that went off already
!%FI

LITERAL CNDTM=%O'53000011';	!Gettab for universal date/time
LITERAL
	CLKREQ_INT=0,	!Address of interrupt block
	CLKREQ_TIME=1;	!Time to go off

!
! Structure declarations
!
STRUCTURE ARRAY[A,B;C,D]=
	[C*D] (ARRAY+(A*D)+B);
!
! Global Data
!
GLOBAL CLKREQ: ARRAY[CLKMAX,2];

%(	CLKREQ	consists of  2-word entries
	1st word: time (in Universal Date/Time format)
	2nd word: process to wake up

	Unused entries are all 0			)%
!
! Externals
!
EXTERNAL ROUTINE
!INTSIG,
ALLOC;
EXTERNAL
RUN: REF PROCESS_BLOCK;
!
! Macros
!

!
! Routines
!
GLOBAL ROUTINE CLKCHK=
!See if any processes timed out since last we looked
BEGIN
LOCAL TIME;

TIME=UDT();	!What time is it?

INCR I FROM 0 TO CLKMAX DO
	IF (.CLKREQ[.I,CLKREQ_TIME] LSS .TIME)
	AND (.CLKREQ[.I,CLKREQ_INT] NEQ 0)
	THEN	BEGIN
		INTSIG(.CLKREQ[.I,CLKREQ_INT]);	!Signal the interrupt
		CLKREQ[.I,CLKREQ_TIME]=%O'377777777777';
				!No more interrupts from this
		END;

END; !CLKCHK
GLOBAL ROUTINE TSIGNL(INT,TIME)=
!Add a signal request to the clock table
!INT: address of interrupt block
!TIME: time for signal to happen
!Returns: index in table if successful, signal CLKFUL if table full
BEGIN
MAP INT: REF INT_BLOCK;
INCR I FROM 0 TO CLKMAX DO
	BEGIN
	IF .CLKREQ[.I,CLKREQ_TIME] EQL 0 THEN
		BEGIN
		IF .INT[INT$PROCESS] EQL 0 THEN INT[INT$PROCESS]=.RUN;
			!Do it to us if not specified yet
		CLKREQ[.I,CLKREQ_INT]=.INT;	!Put in interrupt block
		CLKREQ[.I,CLKREQ_TIME]=.TIME;	!And time
		RETURN .I
		END
	END;
ERROR(CLKFUL);	!No more room in the table
END; !TSIGNL
GLOBAL ROUTINE TSICAN(INDEX)=
!Routine to cancel a signal request
!INDEX: index within CLKREQ of request to cancel 
!	(as returned by TSIGNL)
!Returns: 1 if successful, 0 if not
BEGIN
IF CLKREQ[.INDEX,CLKREQ_TIME] NEQ 0 THEN
	BEGIN
	LOCAL T;
	T=.CLKREQ[.INDEX,CLKREQ_INT];	!So we can see if it went off yet
	CLKREQ[.INDEX,CLKREQ_INT]=(CLKREQ[.INDEX,CLKREQ_TIME]=0);
	IF .T NEQ 0 THEN WIN ELSE TSICWO	!Alternate return value if so
	END
ELSE	0
END; !TSICAN

GLOBAL ROUTINE TSICLF(AFORK)=
!Clear all pending clock requests for a fork
!AFORK: address of process block for fork
BEGIN
INCR I FROM 0 TO CLKMAX DO
	BEGIN
	BIND IB=.CLKREQ[.I,CLKREQ_INT]: INT_BLOCK;	!Get interrupt block
	IF .IB[INT$PROCESS] EQL .AFORK THEN
		CLKREQ[.I,CLKREQ_INT]=(CLKREQ[.I,CLKREQ_TIME]=0);
	END
END; !TSICLF

GLOBAL ROUTINE UDT(ARG)=(EXTERNAL ROUTINE GETTAB;GETTAB(CNDTM));
END ELUDOM