int irq_request(int irq, int pri, struct sigevent *ev);
This function allows a MOSS application to intercept one of the PC's hardware interrupts and service it in the application itself.There are two ways the application can service interrupts, indicated by ev->sigev_notify:
- SIGEV_SIGNAL: Intercepted hardware interrupts will be dispatched to the application as POSIX signals. ev->sigev_signo specifies the signal number. An opaque value can be provided in ev->sigev_value; this value will be passed back to the application's handler when it is invoked, identifying to the hardware interrupt that occurred.
MOSS will automatically clear and disable the hardware interrupt in the PC's programmable interrupt controller (PIC) until the signal handler finishes and returns; then it will automatically re-enable the hardware interrupt. Thus, the interrupt handler should never need to access the PIC registers directly. Of course, the interrupt handler itself must deal with any interrupt enable/disable flags specific to the device actually generating the interrupt.
Dispatching interrupts as signals is not supported under DPMI. (This is because of a deficiency in the DPMI specification, not a bug in MOSS.)
- SIGEV_FASTINT: Intercepted hardware interrupts will be dispatched directly to an application interrupt handler, bypassing the signal mechanism entirely. ev->sigev_handler must point to the handler to invoke, and ev->sigev_stack must contain the initial stack pointer value indicating the stack to be used by the interrupt handler. The provided stack must have at least 32 bytes available in addition to the requirements of the handler itself.
Fast interrupt handlers must run to completion without causing any processor exceptions. All memory touched by the interrupt handler, including its code, stack, and any other data it references, must be locked down using mlock or mlockall. All interrupts will be disabled on entry to the handler, and the handler must leave interrupts disabled for the duration. MOSS will clear the interrupt in the PIC; the handler should not touch the PIC. Only one fast interrupt handler will ever be invoked at once (they can't be stacked), so multiple interrupt handlers can share the same stack.
The irq_request() function causes the specified hardware interrupt to be enabled if it wasn't enabled already. Therefore, the interrupt handler must be ready to service interrupts when this routine is called.
The main advantages of dispatching hardware interrupts as signals are:
- You can call any MOSS system calls, DOS calls, or signal-safe C library functions, from within the signal handler. This means, for example, that you can print messages to the screen from within a signal handler.
- If you are debugging the application remotely, you can set breakpoints in signal handlers, single-step through them, etc.
- It is not necessary to lock down all the memory touched by the signal handler: if a page fault occurs while the handler is running, it will be serviced normally.
- Multiple interrupts can be serviced at once (signal handlers can be stacked).
The advantages of using the FASTINT mechanism are:
- Dispatching FASTINT handlers is somewhat faster, as you might expect.
- Interrupts can be handled during MOSS or DOS calls, providing a much lower worst-case interrupt latency.
- FASTINT handlers work under DPMI as well as the ``plain'' DOS modes.
In general, you may want to use signal handlers to catch and handle hardware interrupts during debugging, because of their greater convenience, and switch to using FASTINT handlers for the ``release'' version of the program to achieve maximum performance and DPMI compatibility.
- irq
- The hardware IRQ number to intercept, 0-15.
- pri
- Currently unused.
- ev
- A sigevent structure describing the action to take when the interrupt occurs.
Returns 0 if successful, or -1 on error, in which case errno indicates the error.