Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - A timer with pulse: (23 Items)
   
A timer with pulse  
What if a timer is set up to deliver a pulse at some time but when that time comes, there is no free memory to allocate 
the pulse and queue it for the connection? Is this situation possible? If yes, how could it be detected/handled from the
 client's point of view?
Re: A timer with pulse  
On Tue, Mar 31, 2009 at 01:12:04PM -0400, Oleh Derevenko wrote:
> What if a timer is set up to deliver a pulse at some time but when that time comes, there is no free memory to 
allocate the pulse and queue it for the connection? Is this situation possible? If yes, how could it be detected/handled
 from the client's point of view?

Yes, it's possible, though we try our darndest to make sure it doesn't
happen. There's memory that the kernel pre-allocates for just
this occasion (the kernel critical heap stuff in nano_alloc.c). You should
only have a critical heap allocation failure if your server process
is failing to process the pulses in a timely manner.

If it does occur, the pulse is just lost. If you have two or more -v's 
on the procnto command line, you'll get a debug message about it - search
for the kprintf in nano_pulse.c for the code. There's no mechanism
to inform user code that this has occured.

-- 
Brian Stecher (bstecher@qnx.com)        QNX Software Systems
phone: +1 (613) 591-0931 (voice)        175 Terence Matthews Cr.
       +1 (613) 591-3579 (fax)          Kanata, Ontario, Canada K2M 1W8
Re: A timer with pulse  
> Yes, it's possible, though we try our darndest to make sure it doesn't
> happen. There's memory that the kernel pre-allocates for just
> this occasion (the kernel critical heap stuff in nano_alloc.c). You should
> only have a critical heap allocation failure if your server process
> is failing to process the pulses in a timely manner.

Well, there is a single kernel and single critical heap while there can be lots of processes and any of them can 
schedule timers and those timers can expire at the same time.
Sure, I understand that there's no way to deliver error code to client (perhaps, just crash the kernel on access to NULL
 pointer if memory can't be allocated ;) ) but still I don't think a person injured or killed by machinery would be 
happy to find out that we tried our best and that accident was nearly impossible. :(
Perhaps it's better to use timers with signal delivery instead of pulses because as far as I can guess, signal delivery 
does not require memory allocation.
Re: A timer with pulse  
And you can do that - set your sigevent to be a signal when you create  
the timer.
-Adam

On 1-Apr-09, at 12:19 PM, Oleh Derevenko wrote:

>
>> Yes, it's possible, though we try our darndest to make sure it  
>> doesn't
>> happen. There's memory that the kernel pre-allocates for just
>> this occasion (the kernel critical heap stuff in nano_alloc.c). You  
>> should
>> only have a critical heap allocation failure if your server process
>> is failing to process the pulses in a timely manner.
>
> Well, there is a single kernel and single critical heap while there  
> can be lots of processes and any of them can schedule timers and  
> those timers can expire at the same time.
> Sure, I understand that there's no way to deliver error code to  
> client (perhaps, just crash the kernel on access to NULL pointer if  
> memory can't be allocated ;) ) but still I don't think a person  
> injured or killed by machinery would be happy to find out that we  
> tried our best and that accident was nearly impossible. :(
> Perhaps it's better to use timers with signal delivery instead of  
> pulses because as far as I can guess, signal delivery does not  
> require memory allocation.
>
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post25775
>
Re: A timer with pulse  
> Sure, I understand that there's no way to deliver error code to client (
> perhaps, just crash the kernel on access to NULL pointer if memory can't be allocated ;) ) 

By the way, would not it be reasonable to have a command line option for procnto to allow crashing the kernel indeed in 
cases if operation fails and there is no way to notify client applicaton?
Re: A timer with pulse  
On Wed, Apr 01, 2009 at 01:27:26PM -0400, Oleh Derevenko wrote:
> > Sure, I understand that there's no way to deliver error code to client (
> > perhaps, just crash the kernel on access to NULL pointer if memory can't be allocated ;) ) 
> 
> By the way, would not it be reasonable to have a command line option for procnto to allow crashing the kernel indeed 
in cases if operation fails and there is no way to notify client applicaton?

I've been thinking about that since your original posting. Probably not
a command line option, but I've been toying with the idea with something
along the lines of InterruptHookIdle() - allow user code to register a
function that'll be invoked in an ISR like environment when the allocation
failure occurs. If the system designer decides it's best to crash the
system, it can be done there. It's not something that'll make it in to
the next release, but I'll continue to cogitate on it.

-- 
Brian Stecher (bstecher@qnx.com)        QNX Software Systems
phone: +1 (613) 591-0931 (voice)        175 Terence Matthews Cr.
       +1 (613) 591-3579 (fax)          Kanata, Ontario, Canada K2M 1W8
Re: A timer with pulse  
On Wed, Apr 01, 2009 at 12:19:10PM -0400, Oleh Derevenko wrote:
> 
> > Yes, it's possible, though we try our darndest to make sure it doesn't
> > happen. There's memory that the kernel pre-allocates for just
> > this occasion (the kernel critical heap stuff in nano_alloc.c). You should
> > only have a critical heap allocation failure if your server process
> > is failing to process the pulses in a timely manner.
> 
> Well, there is a single kernel and single critical heap while there can be lots of processes and any of them can 
schedule timers and those timers can expire at the same time.

We only expire a maximum of 50 timers on each clock tick (to minimize
latency), so we should still have plenty of critical heap.

> Perhaps it's better to use timers with signal delivery instead of pulses because as far as I can guess, signal 
delivery does not require memory allocation.

Actually, signals use the same internal machinery as pulses and go through
that exact same code path - they queue on to lists associated with a
process or thread rather than a channel, but otherwise they're treated
identically. Now, they are somewhat more likely to be processed quickly
since a pulse can only be delivered when a thread does a MsgReceive() while
signals can be sent whatever the process is doing (modulo masking them).

-- 
Brian Stecher (bstecher@qnx.com)        QNX Software Systems
phone: +1 (613) 591-0931 (voice)        175 Terence Matthews Cr.
       +1 (613) 591-3579 (fax)          Kanata, Ontario, Canada K2M 1W8
Re: A timer with pulse  
> Actually, signals use the same internal machinery as pulses and go through
> that exact same code path - they queue on to lists associated with a
> process or thread rather than a channel, but otherwise they're treated
> identically. Now, they are somewhat more likely to be processed quickly
> since a pulse can only be delivered when a thread does a MsgReceive() while
> signals can be sent whatever the process is doing (modulo masking them).
> 
After some more thinking on the problem I've come to the conclusion that it's not realistic to use signals in my 
situation. I have a pool of threads and a single timer which can be re-scheduled (scheduled for different time) while 
provious timer has not expired yet. In this situation with pulses, if timer_settime() is called right at expiration time
 when pulse is already queued but not extracted from channel yet, if new timer is scheduled for zero delay I'll have two
 pulses in channel. But in that situation I'll be able to detect that previous pulse has been already queued by zero 
value of former time to expire.
With signals this approach does not work because it is not possible to predict which thread receives signal and if the 
thread already has the signal queued for it, another signal is discarded. So it's not possible to make a counter and 
ignore extra signals (like pulses) in multithreaded situation. It would be possible to do it only if there would be just
 one thread.
Re: A timer with pulse  
What about SIGEV_THREAD_INIT()?

Oleh Derevenko wrote:
>> Actually, signals use the same internal machinery as pulses and go through
>> that exact same code path - they queue on to lists associated with a
>> process or thread rather than a channel, but otherwise they're treated
>> identically. Now, they are somewhat more likely to be processed quickly
>> since a pulse can only be delivered when a thread does a MsgReceive() while
>> signals can be sent whatever the process is doing (modulo masking them).
>>
> After some more thinking on the problem I've come to the conclusion that it's not realistic to use signals in my 
situation. I have a pool of threads and a single timer which can be re-scheduled (scheduled for different time) while 
provious timer has not expired yet. In this situation with pulses, if timer_settime() is called right at expiration time
 when pulse is already queued but not extracted from channel yet, if new timer is scheduled for zero delay I'll have two
 pulses in channel. But in that situation I'll be able to detect that previous pulse has been already queued by zero 
value of former time to expire.
> With signals this approach does not work because it is not possible to predict which thread receives signal and if the
 thread already has the signal queued for it, another signal is discarded. So it's not possible to make a counter and 
ignore extra signals (like pulses) in multithreaded situation. It would be possible to do it only if there would be just
 one thread.
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post25868
> 

-- 
cburgess@qnx.com
Re: A timer with pulse  
My threads handle resource manager requests (a directory tree server). Therefore, to avoid need to expect signals 
everywhere I would like to only unmask signals for the fime of entry to dispatch_block(). And since those are resource 
manager threads I do not know whichever of them is idle right now and I do not want to bind to any specific thread.

Well, I thought signals are implemented as simple bitmasks with arrays for values for every thread/process and do not 
require memory allocation. :-/ Why do you need lists?
Re: A timer with pulse  
> 
> Well, I thought signals are implemented as simple bitmasks with arrays for 
> values for every thread/process and do not require memory allocation. :-/ Why 
> do you need lists?


Ah, right. There are signals with values which are queued asynchronously and are guaranteed to be all delivered.
Re: A timer with pulse  
Signals are queued only if you use SA_SIGINFO with sigaction(), except for signals generated by timers, which never
queue.

Oleh Derevenko wrote:
> My threads handle resource manager requests (a directory tree server). Therefore, to avoid need to expect signals 
everywhere I would like to only unmask signals for the fime of entry to dispatch_block(). And since those are resource 
manager threads I do not know whichever of them is idle right now and I do not want to bind to any specific thread.
> 
> Well, I thought signals are implemented as simple bitmasks with arrays for values for every thread/process and do not 
require memory allocation. :-/ Why do you need lists?
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post25882
> 

-- 
cburgess@qnx.com
Re: A timer with pulse  
> Signals are queued only if you use SA_SIGINFO with sigaction(), except for 
> signals generated by timers, which never
> queue.
> 
So, I don't quite get it... If you say that timer signals are allocated and inserted into the list and on the other hand
, there can never be two signals queued from the same timer (whether because of periodic timer or because of additional 
timer re-schedule) that means you have to scan through the list each time to find out if there is already a signal 
queued from the same timer. Is that correct?
Re: A timer with pulse  
>> What about SIGEV_THREAD_INIT()?


> My threads handle resource manager requests (a directory tree server). 

Well, on the other hand, since I have only one timer it could be possible to have a seperate dedicated thread just for 
handling timer signals and bind those explicitly to it. Perhaps this way it would be possible to work with signals 
instead of pulses.
But still, if signals are also allocated from heap there is not much difference really.
Re: A timer with pulse  
I believe Brian was referring to queued signals.

Oleh Derevenko wrote:
>>> What about SIGEV_THREAD_INIT()?
> 
> 
>> My threads handle resource manager requests (a directory tree server). 
> 
> Well, on the other hand, since I have only one timer it could be possible to have a seperate dedicated thread just for
 handling timer signals and bind those explicitly to it. Perhaps this way it would be possible to work with signals 
instead of pulses.
> But still, if signals are also allocated from heap there is not much difference really.
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post25892
> 

-- 
cburgess@qnx.com
Re: A timer with pulse  
If you are using a dedicated thread then you could use SIGEV_INTR, which merely sets a flag in your thread
if you are blocked in InterruptWait() at the time.

However using a non queued signal only allocates one pulse structure, so it's not that much different.

Oleh Derevenko wrote:
>>> What about SIGEV_THREAD_INIT()?
> 
> 
>> My threads handle resource manager requests (a directory tree server). 
> 
> Well, on the other hand, since I have only one timer it could be possible to have a seperate dedicated thread just for
 handling timer signals and bind those explicitly to it. Perhaps this way it would be possible to work with signals 
instead of pulses.
> But still, if signals are also allocated from heap there is not much difference really.
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post25892
> 

-- 
cburgess@qnx.com
Re: A timer with pulse  
> If you are using a dedicated thread then you could use SIGEV_INTR, which 
> merely sets a flag in your thread
> if you are blocked in InterruptWait() at the time.
> 
> However using a non queued signal only allocates one pulse structure, so it's 
> not that much different.
> 

The thread would be not only blocking in InterruptWait() all the time but could also be doing something useful once now 
and then. ;) And using SIGEV_INTR could unblock it from that useful job if timer is re-scheduled from handler. :) On the
 other hand, signals are automatically masked for the time of handler invocation and it is safe to re-schedule timer 
once again.
Re: A timer with pulse  
> > If you are using a dedicated thread then you could use SIGEV_INTR, which 
> > merely sets a flag in your thread
> > if you are blocked in InterruptWait() at the time.
> > 
> > However using a non queued signal only allocates one pulse structure, so 
> it's 
> > not that much different.
> > 
> 
> The thread would be not only blocking in InterruptWait() all the time but 
> could also be doing something useful once now and then. ;) And using 
> SIGEV_INTR could unblock it from that useful job if timer is re-scheduled from
>  handler. :) On the other hand, signals are automatically masked for the time 
> of handler invocation and it is safe to re-schedule timer once again.

Ah, sorry. I've mistaken SIGEV_INTR for SIGEV_UNBLOCK. :)
I have never written interrupt handlers. What if I don't call InterruptAttach? I do not really need to handle any 
interrupts.
Re: A timer with pulse  
> I have never written interrupt handlers. What if I don't call InterruptAttach?
>  I do not really need to handle any interrupts.

So, I guess, interrupt handler normally unblocks InterruptWait for the thread to do some additional processing after the
 interrupt has been received. And with timer there is no interrupt handler but the timer event unblock the function 
instead to indicate that the timer has expired.
Re: A timer with pulse  
I just checked more carefully and SIGEV_INTR can only be used with InterruptAttach/InterruptAttachEvent() - it needs
that to determine which thread to deliver the unblock to.

Oleh Derevenko wrote:
>> I have never written interrupt handlers. What if I don't call InterruptAttach?
>>  I do not really need to handle any interrupts.
> 
> So, I guess, interrupt handler normally unblocks InterruptWait for the thread to do some additional processing after 
the interrupt has been received. And with timer there is no interrupt handler but the timer event unblock the function 
instead to indicate that the timer has expired.
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post25910
> 

-- 
cburgess@qnx.com
Re: A timer with pulse  
> I just checked more carefully and SIGEV_INTR can only be used with 
> InterruptAttach/InterruptAttachEvent() - it needs
> that to determine which thread to deliver the unblock to.
> 
Well, how about delivering to the thread that created the timer?
Re: A timer with pulse  
Potentially it could be changed to do that, but it doesn't right now.

Oleh Derevenko wrote:
>> I just checked more carefully and SIGEV_INTR can only be used with 
>> InterruptAttach/InterruptAttachEvent() - it needs
>> that to determine which thread to deliver the unblock to.
>>
> Well, how about delivering to the thread that created the timer?
> 
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post25933
> 

-- 
cburgess@qnx.com
Re: A timer with pulse  
Well, there is a potential problem that the thread may exit while timer can still be active. Same as with interrupt 
handling thread, though. 

> Potentially it could be changed to do that, but it doesn't right now.
> 
> Oleh Derevenko wrote:
> >> I just checked more carefully and SIGEV_INTR can only be used with 
> >> InterruptAttach/InterruptAttachEvent() - it needs
> >> that to determine which thread to deliver the unblock to.
> >>
> > Well, how about delivering to the thread that created the timer?
> > 
> > _______________________________________________
> > OSTech
> > http://community.qnx.com/sf/go/post25933
> > 
> 
> -- 
> cburgess@qnx.com