Chris McKillop wrote:
David Alessio <> david.alessio@hsa.hitachi.com> > wrote:
Hmmm, this is exactly what I ended up doing. But I don’t like it. I
don’t like it because I have an ISR waking a thread whose sole
responsibility now becomes that of an intermediary for other threads.
Well - if you actually have this thread do some other work besides waking
up other threads then how is this any different from what you wanted to do?
That is, say you have 3 worker threads waiting then you can just dedicate one
of them to be the dispatcher of the other two.
The three threads have different priorities. To prevent unbounded
priority inversion, it would have to be the highest priority thread that
doubles as a dispatcher. But as high priority threads go, it’s
optimized for short time-critical tasks. If it now needs to play with
pthread_mutex_lock/cond_var/unlock, it clearly affects the temporal
response of the whole system.
In my case it’s not catastrophic; but it’s not as clean as I would like
it to be.
Can I make a case for SIG_INTR_THREAD?
BTW, where is the binding between SIG_INTR and the thread which
installed the ISR? Is it exposed, and can I tweak it in a way that’s
safe and sanctioned?
You only get to return a single “event” structure from the ISR. Generally,
Understood.
if you look at something like a network driver, it is using a SIGEV_PULSE
to send a pulse to a RECEIVE blocked thread. This is, I belive, the
recommended way of handling events from ISRs. So, you would have one of your
worker threads MsgReceive() and the others wait on conditional variables.
The first worker can then check to see if it needs to schedual the other
workers before it does it’s work. This is nice since it allows you to use
priorities to your advantage since it will minimize the work done in the
ISR itself.
I understand you point. I’m not suggesting that more work be done it
the ISR. But typically an ISR needs to check several conditions. In
the case of a simple FIFO-less 8250 the ISR needs to check for Rx, Tx,
Framing errors, etc. anyway. But the 8250 is not the best example to
make my case – I’m thinking of HW that generates mutually exclusive
events which must be checked individually:
if (my_hw->reg_0 & BIT(3))
return(event_reg_0);
if (my_hw->reg_1 & BIT(7))
return(event_reg_1);
if (my_hw->reg_2 & BIT(0))
return(event_reg_2);
As it is today my ISR looks like:
int flag = 0;
if (my_hw->reg_0 & BIT(3)) {
flag = 1;
global_isr_flag_reg0 = 1;
}
if (my_hw->reg_1 & BIT(7))
flag = 1;
global_isr_flag_reg1 = 1;
}
if (my_hw->reg_2 & BIT(0))
flag = 1;
global_isr_flag_reg2 = 1;
}
if (flag)
return(event_wake_ist);
// other processing that doesn’t warrent waking a thread
What if I approach this from a different angle: Why do we have
SIGEV_SIGNAL_THREAD? Don’t those same reasons also advocate the need
for SIG_INTR_THREAD?
Thanks,
-david