]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Cleanups for posix timer hang fix
authorGeorge Anzinger <george@mvista.com>
Tue, 15 Apr 2003 12:37:17 +0000 (05:37 -0700)
committerSteve French <cifs.adm@hostme.bitkeeper.com>
Tue, 15 Apr 2003 12:37:17 +0000 (05:37 -0700)
Clean up "pendcount" locking (or rather - lack there-of) by making it a
per-timer thing and thus automatically protected by the timer lock.

Fix whitespace damage.

kernel/posix-timers.c

index 9d22317865f427e8f4b4a55d6601d529a81cb393..54fe15f5c0b3dfaf1da7ff4b31949bbd3cd1912f 100644 (file)
@@ -87,6 +87,8 @@ static spinlock_t idr_lock = SPIN_LOCK_UNLOCKED;
                      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:
@@ -245,7 +247,7 @@ static void schedule_next_timer(struct k_itimer *timr)
 
        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);
 }
 
@@ -286,16 +288,16 @@ exit:
  * 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)
 {
@@ -310,17 +312,12 @@ 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) {
@@ -617,7 +614,7 @@ do_timer_gettime(struct k_itimer *timr, struct itimerspec *cur_setting)
                        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);
@@ -779,7 +776,8 @@ do_timer_settime(struct k_itimer *timr, int flags,
 #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;
        /*