Messages in this thread | | | Date | Tue, 18 Nov 2003 10:53:29 +0100 | From | "Ihar 'Philips' Filipau" <> | Subject | Re: [Q] jiffies overflow & timers. |
| |
Richard B. Johnson wrote: >>Richard B. Johnson wrote: >> >>>Use jiffies as other modules use it: >>> >>> tim = jiffies + TIMEOUT_IN_HZ; >>> while(time_before(jiffies, tim)) >>> { >>> if(what_im_waiting_for()) >>> break; >>> current->policy |= SCHED_YIELD; >>> schedule(); >>> } >>>// >>>// Note that somebody could have taken the CPU for many seconds >>>// causing a 'timeout', therefore, you need to add one more check >>>// after loop-termination: >>>// >>> if(what_im_waiting_for()) >>> good(); >>> else >>> timed_out(); >>> >>>Overflow is handled up to one complete wrap of jiffies + TIMEOUT. It's >>>only the second wrap that will fail and if you are waiting several >>>months for something to happen in your code, the code is broken. >>>
time_before(a,b) == (((long)a - (long)b) < 0)
Can you explain me this games with signs there? Or this code expected to work reliably for timeouts < (ULONG_MAX/2)? time_before/time_after - do implicit conversion to signed types, while jiffies/friends are all unsigned. If one day gcc will be fixed - and it will truncate data here as I expect it to do - this will not work at all. Or this is a feature of 2-complement archs? (ldd2 again is silent on this topic - and I'm totally confused...)
> > schedule() is the kernel procedure that gives the CPU to somebody > while your code is waiting for something to happen. You cannot > call that in an interrupt or when a lock is held. >
It is state machine, it is event driven - there is nothing that can yield CPU to someone else, because in first place it does not take CPU ;-))) Right now it is run from tasklet - so ksoftirqd context.
Ok. Thinking about this gave me hints to understand userspace implementation of timers, which was used with my network layers before I have started kernel port. Idea is simple: all times absolute (think struct timeval). all given timer events are put into let us say binary heap, with timeval used as key. Check for expiration == O(1) - and this check is called in "while(1) { schedule(); }" loop. If we have NO expired timer - we are fast to yield CPU to someone else. Slow case of dequeueing from heap (what is O(log(n))) is really slow by definition - we are dequeueing event from heap and it needs to be processed.
Looks Ok to me. Clearer/cleaner/safer than games with sign & ./kernel/timer.c implementation (internal_add_timer/cascade_timers/run_timer_list - what all those mess is about?).
-- Ihar 'Philips' Filipau / with best regards from Saarbruecken. -- _ _ _ "... and for $64000 question, could you get yourself |_|*|_| vaguely familiar with the notion of on-topic posting?" |_|_|*| -- Al Viro @ LKML |*|*|*|
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |