/* begincopyright Copyright (c) 1988 Xerox Corporation. All rights reserved. Use and copying of this software and preparation of derivative works based upon this software are permitted. Any distribution of this software or derivative works must comply with all applicable United States export control laws. This software is made available AS IS, and Xerox Corporation makes no warranty about the software, its performance or its conformity to any specification. Any person obtaining a copy of this software is requested to send their name and post office or electronic mail address to: PCR Coordinator Xerox PARC 3333 Coyote Hill Rd. Palo Alto, CA 94304 endcopyright */ /* * ThreadsSignalsPrivate.h * * Demers, February 26, 1990 4:58:54 pm PST * Boehm, October 29, 1992 2:17:14 pm PST * * Unix signal definitions for VPs and IOPs */ #ifndef ←XR←THREADS←SIGNALS←PRIVATE← #define ←XR←THREADS←SIGNALS←PRIVATE← 1 #ifndef NSIG # include <sys/signal.h> #endif /* * For each interrupt (Unix signal) we provide: * * A Unix signum to send to generate the interrupt: * * XR←SIG←XXX * * A list of Unix signals to be interpreted as this interrupt when received: * * XR←XXX←SIGS * * Indication whether this interrupt is disabled by other handlers: * * XR←XXX←HELD * * Indication that this interrupt is handled on separate stack in the VP's: * * XR←XXX←ONSTACK * * Interrupt handler procedure: * * extern int XR←XxxSigHandler(); * * Initialization proc for handler: * * extern void XR←XxxSigHandlerInit( installed ); * bool installed; * * This is called twice - * before installation of the sigHandler (with installed == FALSE) * after installation of the sigHandler (with installed == TRUE) */ extern void XR←NullSigHandlerInit(/* installed */); /* does nothing */ /* * Resched * * The general paradigm is to store some state and then wake up * a processor by sending it a resched signal, at which point * it notices the stored state and acts on it. * Held by other sigHandlers. * * IOP: * Runs on ordinary stack -- but it's the Unix stack, which * is grown automatically, so no stack overflow worries. * This is how orders are passed to the IOP. * * VP: * Runs on ordinary (process) stack, so it must be careful about * stack overflow. * Often results in a thread switch. */ #define XR←SIG←RESCHED SIGUSR1 #define XR←RESCHED←SIGS { SIGUSR1, 0 } #define XR←RESCHED←HELD TRUE #define XR←RESCHED←ONSTACK FALSE extern void XR←ReschedSigHandler(); #define XR←ReschedSigHandlerInit XR←NullSigHandlerInit /* * Memerr * * Stack overflow, segmentation violation, etc. * Not held by other sigHandlers. * * IOP: * Panic * * VP: * Runs on sigHandler stack. */ #define XR←SIG←MEMERR SIGBUS #define XR←MEMERR←SIGS { SIGBUS, SIGSEGV, 0 } #define XR←MEMERR←HELD FALSE #define XR←MEMERR←ONSTACK TRUE extern void XR←MemerrSigHandler(); #define XR←MemerrSigHandlerInit XR←NullSigHandlerInit /* * Traps * * Floating point exceptions, etc. * Not held by other sigHandlers. * * IOP: * Panic * * VP: * Runs on ordinary (thread) stack. * The sigHandler typically never returns; it just translates the trap * to a Mesa ERROR. This may eventually cause stack overflow, which * get caught in the normal way ... BUT it CAN return, thus must * run on ordinary stack. * If it occurs inside another sigHandler, it should Panic */ #define XR←SIG←TRAP SIGFPE #define XR←TRAP←SIGS { SIGTRAP, SIGIOT, SIGEMT, SIGFPE, 0 } #define XR←TRAP←HELD FALSE #define XR←TRAP←ONSTACK FALSE extern void XR←TrapSigHandler(); #define XR←TrapSigHandlerInit XR←NullSigHandlerInit /* * Illegal ops * * Illegal stack, illegal instruction, privileged instruction, illegal trap * Not held by other sigHandlers. * * IOP: * Panic * * VP: * Runs on handler stack. * If it occurs inside another sigHandler, it should Panic */ #define XR←SIG←ILL SIGILL #define XR←ILL←SIGS { SIGILL, 0 } #define XR←ILL←HELD FALSE #define XR←ILL←ONSTACK TRUE extern void XR←IllSigHandler(); #define XR←IllSigHandlerInit XR←NullSigHandlerInit /* * termination / exit -- used to shut down the XR world */ #define XR←SIG←EXIT SIGTERM #define XR←EXIT←SIGS { SIGTERM, 0 } #define XR←EXIT←HELD TRUE #define XR←EXIT←ONSTACK FALSE extern void XR←ExitSigHandler(); #define XR←ExitSigHandlerInit XR←NullSigHandlerInit /* * Child termination -- used by UIO IOP for Spawn */ #define XR←SIG←CHILD SIGCHLD #define XR←CHILD←SIGS { SIGCHLD, 0 } #define XR←CHILD←HELD TRUE #define XR←CHILD←ONSTACK FALSE extern void XR←ChildSigHandler(); #define XR←ChildSigHandlerInit XR←NullSigHandlerInit /* * Urgent data -- used by UIO IOP for network streams */ #define XR←SIG←URGENT←DATA SIGURG #define XR←URGENT←DATA←SIGS { SIGURG, 0 } #define XR←URGENT←DATA←HELD TRUE #define XR←URGENT←DATA←ONSTACK FALSE extern void XR←UrgentDataSigHandler(); #define XR←UrgentDataSigHandlerInit XR←NullSigHandlerInit /* * Alarm * * "Hardware" clock. * * Runs on handler stack. * If the timeout queue is nonempty, set sa←doTimeouts and request * resched for lowest priority processor. */ #define XR←SIG←ALARM SIGALRM #define XR←ALARM←SIGS { SIGALRM, 0 } #define XR←ALARM←HELD TRUE #define XR←ALARM←ONSTACK TRUE extern void XR←AlarmSigHandler(); extern void XR←AlarmSigHandlerInit(/* installed */); /* * Interrupts for DebugTool * * The INTR signal is just passed to ThreadsDebugTool. * The TTIN signal tells the stdio module that the tty got preempted by * ThreadsDebugTool. */ #define XR←SIG←INTR SIGINT #define XR←INTR←SIGS { SIGINT, SIGQUIT, 0 } #define XR←INTR←HELD TRUE #define XR←INTR←ONSTACK TRUE extern void XR←IntrSigHandler(); #define XR←IntrSigHandlerInit XR←NullSigHandlerInit #define XR←SIG←TTIN SIGTTIN #define XR←TTIN←SIGS { SIGTTIN, 0 } #define XR←TTIN←HELD TRUE #define XR←TTIN←ONSTACK TRUE extern void XR←TtinSigHandler(); #define XR←TtinSigHandlerInit XR←NullSigHandlerInit /* * Interrupts that should get default handlers */ #define XR←DEFAULTED←SIGS { SIGTSTP, SIGCONT, 0 } /* * Size of per process signal stack */ #define XR←SIG←STACK←SIZE (8*1024) #define XR←SIG←STACK←ALIGNMENT 8 /* * Utilities */ extern void XR←InstallSigHandlers (); /* Install handlers for all interrupts. Called after differentiating between vps and iops. It's the responsibility of each handler to do the right thing as a function of what kind of processor it's running on. */ extern void XR←SigStack(/* onStack */); /* bool onStack; Assert we're running on handler stack (onStack == TRUE) or not. */ typedef unsigned XR←SignalState; extern XR←SignalState XR←DisableSignals (); /* Mask signals for critical section. Return previous signal state. */ extern XR←SignalState XR←EnableSignals (); /* Enable signals. Return previous signal state. */ extern XR←SignalState XR←SetSignalState (/* XR←SignalState state */); /* Set specified signal state. Return previous signal state. */ extern void XR←WaitForSignal (); /* Atomically enable all signals and wait for one. */ /* * t←Errno locking * * Used in handlers (so per-thread errno value isn't trashed * by asynchronous signals) */ #define XR←LockErrno() XR←currThread->t←errnoLock += 1 #define XR←UnlockErrno() XR←currThread->t←errnoLock -= 1 #endif ←XR←THREADS←SIGNALS←PRIVATE←