Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_FS_1_19910112 - kccdist/lib/usys/sigdat.c
There are 6 other files named sigdat.c in the archive. Click here to see a list.
/* SIGDAT - Signal Data module.
**	The reason this module exists is to define certain globals which
** must always exist whether or not the program actually invokes signal()
** or sigvec(); all USYS routines refer to these globals and hence they
** must always be present.  By separating them from the sigvec() code we
** can avoid loading the bulk of the signal stuff if it is never used.
*/
#include "c-env.h"
#include "signal.h"
#include "sys/usysig.h"		/* Check for type clashes */

int _sigusys;			/* Positive if within critical USYS code */
unsigned int _sigpendmask;	/* Mask of pending signals */
				/* Ints can add to this during _sigusys. */
unsigned int _sigblockmask;	/* Mask of signals to block */
				/* Ints cannot change this during _sigusys. */
struct sigstack _sigstk;	/* Alternate stack pointer */
				/* This is in SIGDAT so setjmp can find it. */
struct sigcontext *_sigframe;	/* Current signal stack frame, for debugging */

#if SYS_T20+SYS_10X	/* Additional globals for T20/10X */
unsigned _chnpendmask;		/* Mask of PSI channel ints pending */
unsigned _sigcmask[_NSIGS+1];	/* Chan bits for each signal */
int _intlev;			/* Current PSI interrupt level in progress */
int *_intpca;			/* Interrupt PC address */

static int dummy(){ return(0);}
int (*_doati)() = dummy;	/* Dispatch vector for TTY int setup */

/* _SIGTRIGPEND - Internal rtn called to process any pending signals.
**	Should ONLY be called when _sigusys is zero.  Thus, interrupts
** can be serviced during this call, and no further additions to _sigpendmask
** or _chnpendmask will happen.  We determine whether any signals can now
** be taken, and if so derive a mask of the PSI channel bits for those signals,
** and for those which are actually pending we trigger them all at once.
**	This routine returns one of three values:
**	0  - nothing happened.
**	-1 - interrupt was triggered.
**	+1 - interrupt was triggered, but handler permits restarting syscall.
** The latter return value can only happen if the PSI handling code in SIGVEC
** bumps the PC accordingly.  This is the reason for the _sigtx label, so
** the "pclsr" routine can check for this case.
*/
int
_sigtrigpend()
{	
#asm
	search monsym
	extern abort
	intern .sigtx		/* So sigvec can find this symbol */

	skipn 1,.sigpendmask
	 popj 17,		/* No pending signals, return 0 */
	andcm 1,.sigblockmask	/* Get (_sigpendmask & _sigblockmask) */
	skipn 4,1		/* If no pending signals permitted */
	 popj 17,		/* then return 0 without doing anything */
	jsp 15,.cnvmask		/* Convert sig mask to channel mask */
	and 2,.chnpendmask	/* Only pass on those chans actually pending */
	cain 2,			/* Double-check */
	 pushj 17,abort		/* No PSI bits?  Something's wrong!! */
	movei 1,.fhslf		/* Mask is ready, set up for IIC */
	iic%			/* Trigger the interrupts! */
.sigtx:
	skipa 1,[-1]		/* Normal return says interrupt happened */
	 movei 1,1		/* Special return if sigvec diddles PC */
	popj 17,		/* All done... */

/* _CNVMASK - special support.  Converts signal mask to channel mask.
**	This uses a JSP call so it can be used by the interrupt handlers
** in SIGVEC.C without touching the stack.
**	Calling sequence:
**		MOVE 4,<signal mask>
**		JSP 15,.CNVMASK
**		<returns channel mask in AC2>
** Clobbers 3,4,5 (and 15)
*/
	intern .cnvmask		/* So sigvec() module can get at this */
.cnvmask:
	setz 2,			/* Set up PSI channel mask */
	movei 3,44		/* Set up starting signal # */
cnvlup:	jffo 4,.+2		/* Find 1st 1 and skip if found */
	 jrst (15)		/* No ones left, return! */
	lsh 4,1(5)		/* Found a bit, shift that bit out */
	subi 3,1(5)		/* Bump current signal # down */
	ior 2,.sigcmask+1(3)	/* Add channel mask for this signal */
	jrst cnvlup		/* Back to get any remaining bits */
#endasm
}
#endif /* T20+10X */