ISR waking a thread

Hello,


I have written my own ISR and use it to conditionally return a
SIGEV_INTR to wake a thread blocked on InterruptWait().

How do I extend this so my one ISR may conditionally wake a second,
different, thread?

I’m looking for something similar to SIGEV_SIGNAL_THREAD; something like
SIG_INTR_THREAD. I could use SIGEV_SIGNAL_THREAD, write a special-case
signal handler, set the sig mask in each thread, … messy!

Any suggestions?


Thanks,
-david

Well - off the top of my head - the easiest thing would be to have the
thread that the ISR scheduals do the condition check and invoke
pthread_cond_signal() if the other thread(s) need to be woken up.

chris



David Alessio <david.alessio@hsa.hitachi.com> wrote:

Hello,


I have written my own ISR and use it to conditionally return a
SIGEV_INTR to wake a thread blocked on InterruptWait().

How do I extend this so my one ISR may conditionally wake a second,
different, thread?

I’m looking for something similar to SIGEV_SIGNAL_THREAD; something like
SIG_INTR_THREAD. I could use SIGEV_SIGNAL_THREAD, write a special-case
signal handler, set the sig mask in each thread, … messy!

Any suggestions?


Thanks,
-david

cdm@qnx.com > “The faster I go, the behinder I get.”

Chris McKillop – Lewis Carroll –
Software Engineer, QSSL
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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.

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?


Thanks,
-david



Chris McKillop wrote:

Well - off the top of my head - the easiest thing would be to have the
thread that the ISR scheduals do the condition check and invoke
pthread_cond_signal() if the other thread(s) need to be woken up.

chris

David Alessio <> david.alessio@hsa.hitachi.com> > wrote:


Hello,


I have written my own ISR and use it to conditionally return a
SIGEV_INTR to wake a thread blocked on InterruptWait().

How do I extend this so my one ISR may conditionally wake a second,
different, thread?

I’m looking for something similar to SIGEV_SIGNAL_THREAD; something like
SIG_INTR_THREAD. I could use SIGEV_SIGNAL_THREAD, write a special-case
signal handler, set the sig mask in each thread, … messy!

Any suggestions?


Thanks,
-david

cdm@qnx.com > “The faster I go, the behinder I get.”
Chris McKillop – Lewis Carroll –
Software Engineer, QSSL

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.

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,
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.

chris





Thanks,
-david



Chris McKillop wrote:

Well - off the top of my head - the easiest thing would be to have the
thread that the ISR scheduals do the condition check and invoke
pthread_cond_signal() if the other thread(s) need to be woken up.

chris

David Alessio <> david.alessio@hsa.hitachi.com> > wrote:


Hello,


I have written my own ISR and use it to conditionally return a
SIGEV_INTR to wake a thread blocked on InterruptWait().

How do I extend this so my one ISR may conditionally wake a second,
different, thread?

I’m looking for something similar to SIGEV_SIGNAL_THREAD; something like
SIG_INTR_THREAD. I could use SIGEV_SIGNAL_THREAD, write a special-case
signal handler, set the sig mask in each thread, … messy!

Any suggestions?


Thanks,
-david

cdm@qnx.com > “The faster I go, the behinder I get.”
Chris McKillop – Lewis Carroll –
Software Engineer, QSSL

cdm@qnx.com > “The faster I go, the behinder I get.”

Chris McKillop – Lewis Carroll –
Software Engineer, QSSL
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

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.

Fair enough…however, to signal a condvar you don’t need to have a mutex
locked. So it isn’t really getting in the way of the system at all. Worse
for the temporal response is trying to do more then you need to do in an
ISR! :wink:

chris

cdm@qnx.com > “The faster I go, the behinder I get.”

Chris McKillop – Lewis Carroll –
Software Engineer, QSSL
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Chris McKillop wrote:

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.


Fair enough…however, to signal a condvar you don’t need to have a mutex
locked.

I just learned something. Thanks.


So it isn’t really getting in the way of the system at all. Worse
for the temporal response is trying to do more then you need to do in an
ISR! > :wink:

Agreed! And if you look at the ISR for both cases you’ll see the
version with SIG_INTR_THREAD is actually simpler.

I won’t beat this drum too loudly, please consider it for 6.2

Cheers,
-david