Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-08 - 43,50512/intsig.b36
There are no other files named intsig.b36 in the archive.
MODULE INTSIG=
!Code to pass a software interrupt to a process in NETSPL
!FACILITY:	NETSPL
!ENVIRONMENT:	TOPS-10 only
!SPECIAL INSTRUCTIONS:	DO NOT COMPILE WITH /DEBUG!!!
BEGIN

%IF %SWITCHES(DEBUG) %THEN %WARN('INTSIG compiled with /DEBUG') %FI
COMPILETIME FTDEBUG=(%VARIANT AND %O'1000') NEQ 0;
COMPILETIME FTINTOFF=(%VARIANT AND %O'200') NEQ 0;

FORWARD ROUTINE
INTSIG;	!Inform a process of the occurrance of an interrupt of interest to it

REQUIRE 'INTR.REQ';	!Interrupt processing stuff
			! this also REQUIREs TBL

THIS_IS[INTS]	VERSION [1]	EDIT [3]	DATE [4,APR,78]

%(	R E V I S I O N   H I S T O R Y

[3]	Put in some defensive and/or debugging code for possible PSISER problems
[2]	Use WAKE routine
[1]	Separate INTSIG from INT so INT can compile /DEBUG

END	R E V I S I O N   H I S T O R Y		)%

EXTERNAL ROUTINE
INTCOPY,!Make copy of int block
WAKE;	!Put a process on the RUNlist

GLOBAL ROUTINE INTSIG(INT)=
!Routine to find the process to handle an interrupt and signal it
!Argument:
!INT:	Interrupt block.  (INT[INT$PROCESS] contains process to bother)
BEGIN
LOCAL SAVE_TEMPS: VECTOR[4];
EXTERNAL RUN: REF PROCESS_BLOCK;	!Running process

SAVE_TEMPS[0]=.VREG;
SAVE_TEMPS[1]=.T2;
SAVE_TEMPS[2]=.T3;
SAVE_TEMPS[3]=.T4;
	BEGIN
	MAP INT:  REF INT_BLOCK;
	BIND IFORK=.INT[INT$PROCESS]: PROCESS_BLOCK;
	LOCAL I;

	%IF FTDEBUG %THEN
		BEGIN
		IF .INT LSS 140
		THEN	BEGIN
			TYPE('%NETISI  Ignoring spurious interrupt',CRLF);
			RETURN
			END;
		IF IFORK LSS 140
		THEN	BEGIN
			TYPE('%NETIPB  Invalid process block',CRLF);
			RETURN
			END;
		END %FI;
	I=.INT[INT$OFFSET];	!Offset in interrupt vector
	IF	((.INT[INT$STSCODE] NEQ 0) AND
		(.INT[INT$SALWAYS] OR (.INT[INT$SREASONS] EQL 0) OR
		((.INT[INT$S_REASONS] AND .INTVEC[.I,INTVEC$REASON]) NEQ 0)))
		THEN BEGIN
		!First see if the block is in use
		IF .INT[INT$PENDING] THEN
			INT=INTCOPY(.INT);	!It was so copy it
		!We have to signal something
		!First save the PC & status info for the interrupt
		!from the 4-word block PSISER puts the info in
		INT[INT$PC]=.INTVEC[.I,INTVEC$OLDPC];
		INT[INT$REASON]=.INTVEC[.I,INTVEC$REASON];
		INT[INT$STATUS]=.INTVEC[.I,INTVEC$STATUS];
		IF IFORK NEQ .RUN
		THEN	BEGIN
			FSIGNL(IFORK,.INT)	!Force it for process
			!Since it was not the running process, we just
			!give it a signal when it runs next
			END

		ELSE	BEGIN
			%IF FTINTOFF %THEN
				CRASH('Interrupt to running process');
			%FI
			%NAME('.SIGNL')(INT[INT$SIGNAL_ARGS])
			!If it was the running process then signal it
			END;
		END
	ELSE	IFORK[P$WAIT]=0;	!Must have been a wait

	WAKE(IFORK);	!Put this on the runlist
	!See if we have to signal a condition somewhere
	INTVEC[.I,INTVEC$REASON]=0;	!Zero out reason bits (noone else will)
	END;
T2=.SAVE_TEMPS[1];
T3=.SAVE_TEMPS[2];
T4=.SAVE_TEMPS[3];
.SAVE_TEMPS[0]
END;

END ELUDOM