Thread or event

QNX SDP8.0Programmer's GuideDeveloper

Should you associate a thread directly with an interrupt (InterruptAttachThread()) or associate an event (InterruptAttachEvent())?

InterruptAttachThread() is the preferred choice; it gives the least overhead and best interrupt latency. But there are some limitations: you can attach a thread to only one interrupt, and that thread can block only with InterruptWait().

InterruptAttachEvent() with an interrupt event (SIGEV_INTR_INIT()) gives the same behaviour as InterruptAttachThread(). With any other event type, InterruptAttachEvent() actually creates a new thread (that belongs to your process—it is visible from pidin) that only executes in kernel space. It essentially does:
while (1) {
    InterruptWait();
    deliver_your_event();
}

This increases the latency, and is primarily supplied for source-compatibility with QNX Neutrino 7.1 and earlier versions.

Code example using InterruptAttachEvent()

#include <sys/neutrino.h>

#define IRQ_NUM 76
#define IRQ_PULSE_CODE (_PULSE_CODE_MINAVAIL +2)

int main(void) {

    const int chid = ChannelCreate(0);
    if (chid == -1) {
        // Handle errors.
    }
    const int coid = ConnectAttach(0, 0, chid, _NTO_SIDE_CHANNEL, 0);
    if (coid == -1) {
        // Handle errors.
    }

    struct sigevent ev;
    SIGEV_PULSE_INIT(&ev, coid, 30, IRQ_PULSE_CODE, 0);
    int const id = InterruptAttachEvent(IRQ_NUM, &ev, 0);
    if (id == -1) {
        // Handle errors.
    }

    struct _pulse rbuf;
    while(1) {
        rcvid_t const rcvid = MsgReceive(chid, &rbuf, sizeof(rbuf), NULL);
        if (rcvid == -1) {
            // Handle errors.
        }
        if (rcvid == 0) {
            if (rbuf.code == IRQ_PULSE_CODE) {
                // Handle the interrupt.
                // After interrupt has been handled, unmask interrupt.
                InterruptUnmask(IRQ_NUM, id);
            } else {
                // Handle other pulses.
            }
        } else {
            // Handle messages.
        }
    }
    return 0;
}
Page updated: