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: