Oleh Derevenko(deleted)
03/31/2009 1:12 PM
post25696
|
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?
|
|
|
Brian Stecher
04/01/2009 9:29 AM
post25747
|
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
|
|
|
Oleh Derevenko(deleted)
04/01/2009 12:19 PM
post25775
|
> 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.
|
|
|
Adam Mallory
04/01/2009 12:36 PM
post25777
|
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
>
|
|
|
Oleh Derevenko(deleted)
04/01/2009 1:27 PM
post25784
|
> 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?
|
|
|
Brian Stecher
04/02/2009 8:37 AM
post25828
|
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
|
|
|
Brian Stecher
04/02/2009 8:31 AM
post25827
|
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
|
|
|
Oleh Derevenko(deleted)
04/02/2009 12:07 PM
post25868
|
> 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.
|
|
|
Colin Burgess(deleted)
04/02/2009 1:12 PM
post25880
|
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
|
|
|
Oleh Derevenko(deleted)
04/02/2009 1:25 PM
post25882
|
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?
|
|
|
Oleh Derevenko(deleted)
04/02/2009 1:32 PM
post25884
|
>
> 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.
|
|
|
Colin Burgess(deleted)
04/02/2009 1:33 PM
post25885
|
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
|
|
|
Oleh Derevenko(deleted)
04/02/2009 1:43 PM
post25890
|
> 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?
|
|
|
Oleh Derevenko(deleted)
04/02/2009 1:47 PM
post25892
|
>> 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.
|
|
|
Colin Burgess(deleted)
04/02/2009 1:48 PM
post25893
|
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
|
|
|
Colin Burgess(deleted)
04/02/2009 1:51 PM
post25895
|
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
|
|
|
Oleh Derevenko(deleted)
04/02/2009 1:59 PM
post25902
|
> 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.
|
|
|
Oleh Derevenko(deleted)
04/02/2009 2:11 PM
post25906
|
> > 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.
|
|
|
Oleh Derevenko(deleted)
04/02/2009 2:24 PM
post25910
|
> 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.
|
|
|
Colin Burgess(deleted)
04/02/2009 2:57 PM
post25914
|
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
|
|
|
Oleh Derevenko(deleted)
04/02/2009 4:22 PM
post25933
|
> 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?
|
|
|
Colin Burgess(deleted)
04/02/2009 4:53 PM
post25936
|
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
|
|
|
Oleh Derevenko(deleted)
04/03/2009 9:43 AM
post25965
|
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
|
|
|
|