Index: linux-2.6.9-rc3/kernel/sched.c
===================================================================
--- linux-2.6.9-rc3.orig/kernel/sched.c	2004-10-07 08:48:49.406489464 +1000
+++ linux-2.6.9-rc3/kernel/sched.c	2004-10-07 09:22:34.659604192 +1000
@@ -584,16 +584,21 @@ static inline void sched_info_switch(tas
 #endif /* CONFIG_SCHEDSTATS */
 
 /*
- * Get unsigned long long difference without overflowing unsigned long.
+ * Get nanosecond clock difference without overflowing unsigned long.
  */
-static unsigned long uldiff(unsigned long long v1, unsigned long long v2)
+static unsigned long ns_diff(unsigned long long v1, unsigned long long v2)
 {
 	unsigned long long vdiff;
 	if (unlikely(v1 < v2))
-		return 0;
-	vdiff = v1 - v2;
-	if (vdiff > 1 << 31)
-		vdiff = 1 << 31;
+		/*
+		 * Rarely the clock goes backwards. There should always be
+		 * a positive difference so return 1.
+		 */
+		vdiff = 1;
+	else
+		vdiff = v1 - v2;
+	if (vdiff > (1 << (BITS_PER_LONG - 1)))
+		vdiff = 1 << (BITS_PER_LONG - 1);
 	return (unsigned long)vdiff;
 }
 
@@ -730,7 +735,7 @@ static int effective_prio(task_t *p)
  */
 static void recalc_task_prio(task_t *p, unsigned long long now)
 {
-	unsigned long sleep_time = uldiff(now, p->timestamp);
+	unsigned long sleep_time = ns_diff(now, p->timestamp);
 	unsigned int rr = RR_INTERVAL();
 	unsigned int best_burst = burst(p);
 	unsigned int minrun = rr * (p->burst + 1) / (best_burst + 1) ? : 1;
@@ -1008,15 +1013,19 @@ static inline int wake_idle(int cpu, tas
 
 /*
  * cache_delay is the time preemption is delayed in sched_compute mode
- * and is set to 5*cache_decay_ticks
+ * and is set to 5*cache_decay_ticks on SMP or a nominal 10ms on UP.
  */
 static int cache_delay = 10 * HZ / 1000;
 
+/*
+ * Check to see if p preempts rq->curr and resched if it does. In compute
+ * mode we do not preempt for at least cache_delay and set rq->preempted.
+ */
 static void preempt(task_t *p, runqueue_t *rq)
 {
 	if (p->prio > rq->curr->prio)
 		return;
-	if (p->prio == rq->curr->prio && (p->totalrun || 
+	if (p->prio == rq->curr->prio && (p->totalrun ||
 		rt_task(rq->curr)))
 			return;
 	if (!sched_compute || rq->cache_ticks >= cache_delay ||
@@ -2160,6 +2169,15 @@ DEFINE_PER_CPU(struct kernel_stat, kstat
 
 EXPORT_PER_CPU_SYMBOL(kstat);
 
+static void time_slice_expired(task_t *p, runqueue_t *rq)
+{
+	set_tsk_need_resched(p);
+	dequeue_task(p, rq);
+	p->prio = effective_prio(p);
+	p->time_slice = RR_INTERVAL();
+	enqueue_task(p, rq);
+}
+
 /*
  * This function gets called by the timer code, with HZ frequency.
  * We call it with interrupts disabled.
@@ -2212,7 +2230,7 @@ void scheduler_tick(int user_ticks, int 
 	 */
 	if (unlikely(p->policy == SCHED_FIFO))
 		goto out;
-	debit = uldiff(rq->timestamp_last_tick, p->timestamp);
+	debit = ns_diff(rq->timestamp_last_tick, p->timestamp);
 	if (debit < NSJIFFY) {
 		p->totalrun += debit;
 		goto out;
@@ -2223,13 +2241,9 @@ void scheduler_tick(int user_ticks, int 
 	 * Tasks lose burst each time they use up a full slice().
 	 */
 	if (!--p->slice) {
-		set_tsk_need_resched(p);
-		dequeue_task(p, rq);
 		dec_burst(p);
 		p->slice = slice(p);
-		p->prio = effective_prio(p);
-		p->time_slice = RR_INTERVAL();
-		enqueue_task(p, rq);
+		time_slice_expired(p, rq);
 		goto out_unlock;
 	}
 	/*
@@ -2237,11 +2251,7 @@ void scheduler_tick(int user_ticks, int 
 	 * requeued with a lower priority && RR_INTERVAL time_slice.
 	 */
 	if (!--p->time_slice) {
-		set_tsk_need_resched(p);
-		dequeue_task(p, rq);
-		p->prio = effective_prio(p);
-		p->time_slice = RR_INTERVAL();
-		enqueue_task(p, rq);
+		time_slice_expired(p, rq);
 		goto out_unlock;
 	}
 	rq->cache_ticks++;
@@ -2373,6 +2383,10 @@ static inline int dependent_sleeper(int 
 }
 #endif
 
+/*
+ * Tasks that have yield()ed get queued at lowest priority but once queued
+ * run at their normal priority.
+ */
 static void adjust_yield_prio(runqueue_t *rq, task_t *p)
 {
 	int newprio = effective_prio(p);
@@ -2386,6 +2400,7 @@ static void adjust_yield_prio(runqueue_t
 			p->prio = newprio;
 	}
 }
+
 /*
  * schedule() is the main scheduler function.
  */
@@ -2428,7 +2443,7 @@ need_resched:
 	schedstat_inc(rq, sched_cnt);
 	now = sched_clock();
 
-	prev->runtime = uldiff(now, prev->timestamp);
+	prev->runtime = ns_diff(now, prev->timestamp);
 	spin_lock_irq(&rq->lock);
 
 	/*
@@ -3217,7 +3232,7 @@ asmlinkage long sys_sched_getaffinity(pi
 /**
  * sys_sched_yield - yield the current processor to other threads.
  *
- * this function yields the current CPU by dropping the priority of current
+ * This function yields the current CPU by dropping the priority of current
  * to the lowest priority and setting the PF_YIELDED flag.
  */
 asmlinkage long sys_sched_yield(void)
