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