Re: arca-24 [Re: new arca-23 released]

Finn Arne Gangstad (finnag@guardian.no)
Sat, 21 Nov 1998 03:56:45 +0100 (MET)


On Fri, 20 Nov 1998, Andrea Arcangeli wrote:

> On Fri, 20 Nov 1998, Finn Arne Gangstad wrote:
>
> >If the timer was already pending, you have just DESTROYED its expires
> >value. This means you have no control over when it will expire at all,
>
> I don' t want to have control on its exipres value. Look at
> do_getitimer(). At do_getitimer() runtime, the other CPU could
> be running it_real_fn() and so we could have the same timer inserted two
> times in the timer list. This is the _only_ reason for adding that check.
> The other way is running the del_timer in do_getitimer() in a bh atomic
> context, but my way was more efficient because it would block nothing.

Maybe the solution for do_getitimer is something like this:

Make a new function timer_expires: (WARNING: untested code!)

int timer_expires(struct timer_list *timer, unsigned long *expires)
{
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&timerlist_lock, flags);
if (timer->prev) {
*expires = timer->expires;
ret = 1;
}
spin_unlock_irqrestore(&timerlist_lock, flags);
return ret;
}

and then change the code in do_getitimer to: (pseudo-diff format)

- register unsigned long val, interval;
+ register unsigned long interval;
+ unsigned long val;
switch (which) {
case ITIMER_REAL:
interval = current->it_real_incr;
val = 0;
- if (del_timer(&current->real_timer)) {
+ if (timer_expires(&current->real_timer, &val)) {
unsigned long now = jiffies;
- val = current->real_timer.expires;
- add_timer(&current->real_timer);
/* look out for negative/zero itimer.. */
if (val <= now)
val = now+1;
val -= now;
}
break;

(val <= now) should be replaced by !time_after(val, now)

This looks cleaner than the current race-prone code..

As for setitimer, it could use mod_timer instead of add_timer.

- Finn Arne

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/