timer issue

Greetings! My program has 100 timers running. If a timer expired which will generate a signal and it was mapped to a same function handler. All the timers are mapped to one function handler.

The problem is if the timer expires one at a time, the function handler called at a time. But if the 2 timers expires at a time, the function handler is called one time only instead 2 times.

Is it possible to invoke the function handler as many times based on timer expirary happens simultaneoulsy?

Here is the piece of code implemented..

int timer_start(int timer_id, int expiry_time) { /* Variable Declaration */ struct timespec ts, tm, sleep; sigset_t mask; siginfo_t info; struct sigevent sigev; struct sigaction sa; /* Set the signal handler to handle the SIGRTMIN signal */ sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = timer_handler; if(sigaction(SIGRTMIN, &sa, NULL) == -1) { perror("Sig action failed"); return -1; } sigev.sigev_notify = SIGEV_SIGNAL; sigev.sigev_signo = SIGRTMIN; sigev.sigev_value.sival_int = timer_id; /* Set the timeout values in the timer */ if(timer_settime(tid, 0, &ival, NULL) == -1) { perror("timer_settime"); return -1; } return 1; }

void timer_handler(int sing_no, siginfo_t *info, void *context) { /* Variable declaration */ /* Call to initiate the configuration function call */ } If anyone knows the solution to this problem please let me know. Regards Uma

--------------------------------------- Posted through

formatting link

Reply to
umasankari
Loading thread data ...

Why is it called only once?

Reply to
DaveN

generate

timer

Are your interrupts edge-sensitive (wrong) or level-sensitive (right)?

--------------------------------------- Posted through

formatting link

Reply to
RCIngham

Signals act like event flags, not "counters". So, if you "set" one ("raise" one) twice -- without anything "clearing" (acknowledging) it in the intervening time -- there is no way to remember anything about the second "event".

Your OS is obviously not processing the signals as they are raised but, rather, at a more coarse granularity (e.g., between time slices, etc.)

E.g., if you raise the "flag" on your mailbox each time you put outgoing (postal) mail in it but the mailman doesn't come around to pick up the previous mail AND RESET THE FLAG, then you have no way of knowing how much mail is in the mailbox!

Your handler could examine all active timers to see how many actually have expired and iteratively service them all before returning.

[Disclaimer: I've not examined your code in any detail]
Reply to
D Yuniskis

One solution that works well (at least it works well for me):

Instead of trying to enforce a separate function handler invocation for each timer event, check for multiple timer events in each handler invocation.

In other words, the function handler should check for multiple events, and dispatch them all.

An added bonus is that invoking a function handler is "expensive", so doing it fewer times is better.

RK

Reply to
NeedCleverHandle

Unfortunately, the word "signal" in this context is so vague as to be largely useless. It sounds like he should be using a counting semaphore or message queue to "signal" the event but he's probably using something akin to a binary semaphore or an event flag.

Exactly.

As long as the flag is cleared before the polling is done it should work (and it would be less overhead that having the handler called once per event). But, like most things involving threads, if you don't do things in the right order, it will only work "most of the time."

--
Grant Edwards               grant.b.edwards        Yow! I'm rated PG-34!!
                                  at               
                              gmail.com
Reply to
Grant Edwards

The solution depends on your OS, and what you're trying to do. At worst you'll need to embellish the OS's timer resources with your own bit of code that keeps track of which timers need to pop off when, and have your timer routine check for _all_ of the timers that need servicing when it goes off. There's a distinct tradeoff between code complexity and overhead, here, but it's something that should at least work.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

Exactly. "Signal" as in sigaction(2) -- which he invokes.

What I suspect is happening is something akin to:

- jiffy comes along and updates the timer chain [these are software timers, not hardware counter-timers!]

- ALL active timers are processed at this time so all of those that are expiring "now" do so

- nothing "in the system" happens during the jiffy (it's either a *real* interrupt or a "chore" -- to avoid using the term "task :< -- that happens at a very high/atomic priority) so raising a signal(2) doesn't get *handled* -- yet

- jiffy finishes and, lo and behold, there is *a* signal pending (the flag on the mailbox has been raised... and raised... and raised... and it's *still* "raised" :> )

- the handler for that signal is invoked and it processes whichever timer was passed to it most recently (or, depending on the implementation, *least* recently -- i.e., first!)

- the handler processes the *one* timer and quits having done it's DESIGNED (erroneously) job

If implementation is as above, then either:

  • make the handler check all timers when it is invoked (there can be some optimizations here if you know what order any CONCURRENT timers are processed in -- so you know which ones you *don't* have to check -- but you have to be sure timers are handled before *more* timers can expire!!!)
  • make the signal(2) implementation allow *lists* of events to be recorded instead of simple "flags" (a list per flag)
  • make the signal(2) implementation *immediately* invoke the signal handler (i.e., as a true ASR -- easiest to model in your head; probably the most atrocious in terms of performance and unintended consequences -- since the signal handler is not of bounded complexity! (hint: imagine it being raised in a critical region))
  • make the timer system disallow multiple timers expiring concurrently (A Bad Option)
  • assign a unique signal per timer (in the OP's case, this would require a new signal(2) implementation as most systems limit number of signals to bits(long) or thereabouts)

Option number "1" is the least elegant but probably the most robust. It may require rethinking the timing system implementation to make checking the status of timers easier (e.g., use a bit vector to summarize running/expired)

Reply to
D Yuniskis
[grrrr... senility is setting in... :
Reply to
D Yuniskis

One "solution", in this case, is to have the handler REinstall itself before it terminates. Since this is a one-line-fix, it is probably worth trying -- to at least get a better handle on what's happening under the hood.

[issues like this are one reason I suggest folks *write* an MTOS instead of relying on "black box" implementations which, invariably, NEVER explain the inner workings in enough EXPLICIT detail for you to suss out these sorts of problem issues!]

OK. Done. Kaput. Fin. Finito.

Time to do the grocery shopping... :-(

Reply to
D Yuniskis

That's too bad. Unix signals aren't at all easy to use in a reliable manner. There are subtle but important differences between platforms, and AFAICT nobody _really_ knows what you're allowed to do in a handler and what your not allowed to do in a handler[1]. The thing that's especially bad about signals is that it's not difficult to come up with something that works most of the time on one platform. Something that works all of the time (even on one platform) takes a lot more work and planning.

IMO, using something like Linux's timerfd subsystem would be a lot easier to get right. Unfortunately, that's relatively recent and I don't know how portable it is.

Alternately, when you call timer_create() you can specify a callback function to be called when the timer expires. That might be more reliable than using a signal handler.

[1] OK, I'm being a little hyperbolic -- but not much.
--
Grant Edwards               grant.b.edwards        Yow! MY income is ALL
                                  at               disposable!
                              gmail.com
Reply to
Grant Edwards
[attributions elided]

Note that there is no guarantee that this is even *a* "UN*X" platform! :< It could very well be something that tries to present a UNIX/POSIX-ish API (to make it more appealing to developers) but has a vastly different implementation under the hood.

At a minimum, you/we need to know what the signal(2) semantics are, here. E.g., are they per thread? per process? dispatched to a *particular* thread vs. the thread that set the handler?

Etc.

I think the cleanest solution would be for the OP to use the equivalent of a signal per timer. I.e., the signal says: "*THIS* timer expired" instead of "*A* timer expired" (I think the OP would like the signal to be treated as "THIS" and is being distracted into thinking it's all *one* signal because of his desire to use a *single* common handler)

If that means a second layer of "flags" then so-be-it.

Way out on the asymptote?? ;-)

Reply to
D Yuniskis

Note that Linux queues real-time signals, i.e. if you send a real-time signal 10 times, the handler should be invoked 10 times, even if multiple signals arrive while blocked.

Reply to
Nobody

[Again, since we don't know the OP's OS, so this is mostly just idle speculation.]

It looks to me like you can specify a unique signal for each timer, _but_ there may be limits on the ranges allowed for signal numbers, and the behavior may differ depending on which number is chosen.

To get a similar effect, the sigevent structure you pass to the Posix timer_create() call can specify a callback function to be called instead of the signal assertion that the OP is using.

My reading of the Linux man pages is that the callback function will be called each time a timer expires (which seems to be what the OP wants), and you don't have to worry about either the vagueries of signal handling or the range of available signal numbers.

--
Grant Edwards               grant.b.edwards        Yow! It's a lot of fun
                                  at               being alive ... I wonder if
                              gmail.com            my bed is made?!?
Reply to
Grant Edwards

Up to a maximum of ??. Posix requires that it's at least 32 per process, but older Linux kernels also had a system-wide max. I just checked on my machine, and _POSIX_SIGQUEUE_MAX is 32. With 100 timers running, a max signal queue size of 32 sounds a bit iffy.

I think the callback option looks a lot easier to use, but I've not tried it. [Signals look easy to use at first too.]

--
Grant Edwards               grant.b.edwards        Yow! Let me do my TRIBUTE
                                  at               to FISHNET STOCKINGS ...
                              gmail.com
Reply to
Grant Edwards

As the name implies, _POSIX_SIGQUEUE_MAX is the value specified by POSIX.

Current Linux kernels use a resource limit, RLIMIT_SIGPENDING, which is a cumulative limit for a single UID. On my system, the value (as reported by "ulimit -i") is 15693.

Older kernels had a system-wide cumulative limit set by the /proc/sys/kernel/rtsig-max pseudo-file.

Reply to
Nobody

I have portable timer pool lib module that does just that. The callback runs in interrupt context, but is only expected to call a function with a few lines of code. Will work in any embedded system with a tick timer.

Nothing special, but has been used in many projects...

Regards,

Chris

Reply to
ChrisQ

As you can read here:

formatting link
_POSIX_SIGQUEUE_MAX should always be 32 and is only the minimum acceptable value for SIGQUEUE_MAX.

--
Gemaakt met Opera's revolutionaire e-mailprogramma:  
http://www.opera.com/mail/
(Remove the obvious prefix to reply.)
Reply to
Boudewijn Dijkstra

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.