SIGEV_SIGNAL & \
SIGEV_THREAD & \
SIGEV_THREAD_ID)
+
+#define REQUEUE_PENDING 1
/*
* The timer ID is turned into a timer address by idr_find().
* Verifying a valid ID consists of:
timr->it_overrun_last = timr->it_overrun;
timr->it_overrun = -1;
- timr->it_requeue_pending = 0;
+ ++timr->it_requeue_pending;
add_timer(&timr->it_timer);
}
* without an info block. In this case, we will not get a call back to
* do_schedule_next_timer() so we do it here. This should be rare...
- * An interesting problem can occure if, while a signal, and thus a call
+ * An interesting problem can occur if, while a signal, and thus a call
* back is pending, the timer is rearmed, i.e. stopped and restarted.
* We then need to sort out the call back and do the right thing. What
* we do is to put a counter in the info block and match it with the
* timers copy on the call back. If they don't match, we just ignore
- * the call back. Note that we do allow the timer to be deleted while
- * a signal is pending. The standard says we can allow that signal to
- * be delivered, and we do.
+ * the call back. The counter is local to the timer and we use odd to
+ * indicate a call back is pending. Note that we do allow the timer to
+ * be deleted while a signal is pending. The standard says we can
+ * allow that signal to be delivered, and we do.
*/
-static int pendcount = 1;
static void timer_notify_task(struct k_itimer *timr)
{
info.si_code = SI_TIMER;
info.si_tid = timr->it_id;
info.si_value = timr->it_sigev_value;
- if (timr->it_incr){
- /*
- * Don't allow a call back counter of zero...
- * and avoid the test by using 2.
- */
- pendcount += 2;
- timr->it_requeue_pending = info.si_sys_private = pendcount;
- }
- if( timr->it_sigev_notify & SIGEV_THREAD_ID & MIPS_SIGEV){
+ if (timr->it_incr)
+ info.si_sys_private = ++timr->it_requeue_pending;
+
+ if (timr->it_sigev_notify & SIGEV_THREAD_ID & MIPS_SIGEV)
ret = send_sig_info(info.si_signo, &info, timr->it_process);
- }else
+ else
ret = send_group_sig_info(info.si_signo, &info,
timr->it_process);
switch (ret) {
posix_time_before(&timr->it_timer, &now))
timr->it_timer.expires = expires = 0;
if (expires) {
- if (timr->it_requeue_pending ||
+ if (timr->it_requeue_pending & REQUEUE_PENDING ||
(timr->it_sigev_notify & SIGEV_NONE))
while (posix_time_before(&timr->it_timer, &now))
posix_bump_timer(timr);
#else
del_timer(&timr->it_timer);
#endif
- timr->it_requeue_pending = 0;
+ timr->it_requeue_pending = (timr->it_requeue_pending + 2) &
+ ~REQUEUE_PENDING;
timr->it_overrun_last = 0;
timr->it_overrun = -1;
/*