Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - timer_settime/SIGEV_SIGNAL_PULSE and SchedSet: (9 Items)
   
timer_settime/SIGEV_SIGNAL_PULSE and SchedSet  
I'm trying to write a small driver that uses a periodic timer to initiate a DAC read from the SPI bus. It generally 
works fine, but I wanted to be able to change the priority of the process using SchedSet.  I've found that if I try to 
wake up using the pulse variant of the timer event, I can't adjust the priority (the calls don't fail, but pidin 
indicates my process is still running 10r).  I can run the program using nice, and it works as expected, allowing me to 
up the priority.  But when I try to change internally using SchedSet, the priority doesn't seem to change.  If, instead,
 I use the SIGNAL_THREAD event, then I can handle the signal using sigaction/sa_handler and my MsgReceive will wake up. 
 In this mode, my SchedSet works and priorities can be changed.  The latter version is actually fine, but I was curious 
what timer_settime does behind the scenes when sending pulses that prevents my call to SchedSet from working as I expect
?
Re: timer_settime/SIGEV_SIGNAL_PULSE and SchedSet  
Without a code example of what you are doing exactly it's hard to say for sure.

Having said that MsgReceive  normally inherits the message/pulse priority. This feature is called "priority inheritance"
.

As such there normally isn't much point setting the priority of a thread that is using MsgReceive.

If you don't want to have priority inheritance, you can disable it on the channel using _NTO_CHF_FIXED_PRIORITY.
see http://docserver.ott.qnx.com/700website/com.qnx.doc.neutrino.lib_ref/topic/c/channelcreate.html#channelcreate__Fixed



However the way this is normally handled is by setting the pulse priority in the event structure.
see the example here
http://www.qnx.com/developers/docs/7.0.0/index.html#com.qnx.doc.neutrino.lib_ref/topic/t/timer_create.html

specifically this line 
event.sigev_priority = prio;

Re: timer_settime/SIGEV_SIGNAL_PULSE and SchedSet  
Re: timer_settime/SIGEV_SIGNAL_PULSE and SchedSet  
Thanks very much for the reply. As a very concrete example, I took the time1.c example here, which works fine generally:


http://www.qnx.com/developers/docs/qnxcar2/topic/com.qnx.doc.neutrino.getting_started/topic/examples_time1.c.html

From that I tried to use SchedSet to change the priority of the main thread which I thought would be inherited by the 
pulse. It would be even easier if all I needed to do was change the priority of the pulse from the event structure. I 
actually tried that (I think?!) but it still seemed that the timer itself then didn't have the higher priority (even if 
the pulse did)?  I was using the code to twiddle a GPIO bit and without upping the priority I could see other processes 
(telnet interactions or pidin) had big effects in the timing.

It doesn't seem like the timer_settime starts a new thread (according to pidin, at least), but if I just comment out 
that line and also use SchedSet, the priority of the time1 process elevates as expected.
Re: timer_settime/SIGEV_SIGNAL_PULSE and SchedSet  
Ok, following your suggestion, I did change the call to ChannelCreate(_NTO_CHF_FIXED_PRIORITY) and used 
SIGEV_PULSE_PRIO_INHERIT for the pulse.  Now I see the process running at the higher priority as expected.

Thanks!
Re: timer_settime/SIGEV_SIGNAL_PULSE and SchedSet  
Your solution may work if you only ever receive one type of pulse/message, but generally (as John mentioned) it is 
expected that a receiver thread runs at the priority of the client (for a message) or the pulse it received last.
Also note that there is no such thing as process priority in QNX. Priorities are only associated with threads. The 
nice() function is an anachronism that really should never have been provided, and will probably be dropped soon.

--Elad
Re: timer_settime/SIGEV_SIGNAL_PULSE and SchedSet  
Thanks Elad - that all makes sense.  It does seem like a bad idea to use _NTO_CHF_FIXED_PRIORITY as opposed to letting 
the pulse priority dictate that.  And I do see that threads, not processes, have priorities.  What is still puzzling to 
me is if I elevate priority of the server using SchedSet (for the single thread), then create the pulse event using

SIGEV_PULSE_INIT (&event, coid, SIGEV_PULSE_PRIO_INHERIT, 0, 0);

I would expect my process to run at the elevated priority both with respect to the timer interval generating the pulses 
and the receipt and processing of the timer pulse.  My relatively crude debugging (twiddling the digital bit) doesn't 
clearly show whether it's the timer interval or the actual response to the timer pulse that jitters, but it seems that 
something is still running at 10r if I don't choose the _NTO_CHF_FIXED_PRIORITY upon creating the channel?
Re: timer_settime/SIGEV_SIGNAL_PULSE and SchedSet  
My mistake.  Upon a closer read of the docs I see:

short sigev_priority
The priority of the pulse, or SIGEV_PULSE_PRIO_INHERIT if you want the thread that receives the pulse to run at the 
initial priority of the process.

I thought (incorrectly, it seems) that if I changed the priority of the thread before making that call, the new priority
 would be inherited.  That seems to be wrong, because if I use the desired priority there (and call SchedSet for the 
thread with the same priority, the code seems to work as expected.  I was thrown by the "INHERIT"...

I really appreciate the help.  I'm a long time QNX4.25 user finally moving code to Neutrino...  And looking forward to 
replacing expensive and aging PCI/ISA machines...
Re: timer_settime/SIGEV_SIGNAL_PULSE and SchedSet  
You are not the first person to be fooled by the name of this constant. I really don't like it either.
It so happens that if you use this value in an explicit call to MsgSendPulse() you get what you expect, i.e., the server
 thread inherits the priority of the thread that sent the pulse. But that is only because the value of 
SIGEV_PULSE_PRIO_INHERIT is -1, which is the documented value of MsgSendPulse() for this behaviour. 
However, when using asynchronous events there is no notion of a sender, and so SIGEV_PULSE_PRIO_INHERIT uses the default
 process priority for the server. I think it could have used a better name, though.

--Elad