linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* garbage returned from do_gettimeofday
@ 2002-09-18 23:00 anton wilson
  2002-09-19 15:53 ` anton wilson
  0 siblings, 1 reply; 4+ messages in thread
From: anton wilson @ 2002-09-18 23:00 UTC (permalink / raw)
  To: linux-kernel


I'm using do_gettimeofday in the scheduler, once per schedule.
Ocassioanlly, i'll get what seems to be a random garbage number.
For example:

tv_sec     tv_usec 
1032378775 627501
1032378775 627521
3433001412 1
1032378775 627573
1032378775 627617
1032378775 627638

or

1032379233 253008
1032379233 253028
3387638236 1
1032379233 253068
1032379233 253125


The garbage number tv_sec always seems to begin with a 3 and is followed by 9 
digits. The tv_usec garbage number is always 1.


Most of the code I changed in sched.c follows. It attempts to allow a normal
process to run in place of a SCHED_RR process with a certain limited 
frequency and within a certain window of time. A starvation threshold is 
added which allows a normal process to run disregarding the requested window. 
The patch is very constrained in it's application. It's for a program in 
which a fifo thread runs once every millisecond, and round robin threads take 
up the remainder of the time.

=====================================================

#define NORM_THRESH             1000             
#define NORM_STARVE             20000
#define NORM_WINDOW             800   

#ifdef CONFIG_SCHED_RR_NONSTARVE

int inline rr_should_yield(runqueue_t *rq, struct timeval now)
{
   unsigned long normdiff, secdiff, fifodiff;
   
   secdiff = now.tv_sec - rq->last_normal.tv_sec;
   normdiff = now.tv_usec - ((secdiff * 1000000) + rq->last_normal.tv_usec);

   if( normdiff > NORM_STARVE)
     {
       return 1;
     }

   secdiff = now.tv_sec - rq->last_fifo.tv_sec;
   fifodiff = now.tv_usec - ((secdiff * 1000000) + rq->last_fifo.tv_usec);
   
 
   if( (normdiff > NORM_THRESH) && (fifodiff > NORM_WINDOW) )
     {
       return 1;
     }
 
   return 0;   

}

#endif /*CONFIG_RT_NONSTARVE*/
/*
 * 'schedule()' is the main scheduler function.
 */
asmlinkage void schedule(void)
{
	task_t *prev, *next;
	runqueue_t *rq;
	prio_array_t *array;
	list_t *queue;
	int idx;
#ifdef CONFIG_SCHED_RR_NONSTARVE
        struct timeval now; /* schedule timestamp */
        int idx2;
#endif
#ifdef CONFIG_RT_SWITCH_PRINT
        int policy1;
        int policy2;
        struct timeval tv;
	unsigned long flags;
        int allowed = 0;
#endif


	if (unlikely(in_interrupt()))
		BUG();

need_resched:
	preempt_disable();
	prev = current;
	rq = this_rq();

	release_kernel_lock(prev, smp_processor_id());
	prev->sleep_timestamp = jiffies;
	spin_lock_irq(&rq->lock);
        
	/*
	 * if entering from preempt_schedule, off a kernel preemption,
	 * go straight to picking the next task.
	 */
	if (unlikely(preempt_get_count() & PREEMPT_ACTIVE))
		goto pick_next_task;

#if CONFIG_RR_RESCHED_SWITCH || CONFIG_SCHED_RR_NONSTARVE
        /*
         * Move a SCHED_RR task to end of RQ each time schedule is called
         */

        do_gettimeofday(&now); 

        if (prev->policy == SCHED_RR){

#ifdef CONFIG_SCHED_RR_NONSTARVE
            if(unlikely(rq->non_rt_starving)){

                  /* if all normal processes are expired
                   * we dequeue the round robin processes
                   * instead of putting them at the end
                   * of their queue in the active array
                   * This will trigger a active/expired switch
                   * eventually
                   */
                  printk("moving RR to expired\n");
              /*    dequeue_task(prev, rq->active);
                  prev->first_time_slice = 0;
                  enqueue_task(prev, rq->expired);*/
                  //rq->expired_timestamp = jiffies;
                  goto pick_next_task;
             }
#endif /*CONFIG_SCHED_RR_NONSTARVE*/

#ifdef CONFIG_RR_RESCHED_SWITCH
             dequeue_task(prev, rq->active);
             enqueue_task(prev, rq->active);
#endif /*CONFIG_RR_RESCHED_SWITCH*/

out_rr_move:
        }
#endif /*CONFIG_RR_RESCHED_SWITCH || CONFIG_SCHED_RR_NONSTARVE*/


	switch (prev->state) {
	case TASK_INTERRUPTIBLE:
		if (unlikely(signal_pending(prev))) {
			prev->state = TASK_RUNNING;
			break;
		}
	default:
		deactivate_task(prev, rq);
	case TASK_RUNNING:
		;
	}
pick_next_task:
	if (unlikely(!rq->nr_running)) {
#if CONFIG_SMP
		load_balance(rq, 1);
		if (rq->nr_running)
			goto pick_next_task;
#endif
		/*
		 * Pick a task from the batch queue if available.
		 */
		if (rq->nr_batch) {
			list_t *tmp = rq->batch_queue.next;

			next = list_entry(tmp, task_t, run_list);
			activate_batch_task(next, rq);
		} else
			next = rq->idle;
		rq->expired_timestamp = 0;
		goto switch_tasks;
	}

	array = rq->active;
	if (unlikely(!array->nr_active)) {
		/*
		 * Switch the active and expired arrays.
		 */
		rq->active = rq->expired;
		rq->expired = array;
		array = rq->active;
		rq->expired_timestamp = 0;
#ifdef CONFIG_SCHED_RR_NONSTARVE
		if(rq->non_rt_starving){
                rq->non_rt_starving = 0;
		printk("exchange!\n");
		}
#endif /* CONFIG_SCHED_RR_NONSTARVE*/
	}

	idx = sched_find_first_bit(array->bitmap);
	queue = array->queue + idx;
	next = list_entry(queue->next, task_t, run_list);


#ifdef CONFIG_SCHED_RR_NONSTARVE
        /*
         * if SCHED_RR task should yeild and next task is SCHED_RR
         *               let a SCHED_NORMAL process take the CPU
         */

        switch (next->policy){
           case SCHED_FIFO:
                rq->last_fifo = now;      
                break;
           case SCHED_NORMAL:
                rq->last_normal = now;
                break;
           case SCHED_RR:
               if( rr_should_yield(rq, now) ){

                    /*find non RT process*/
                    idx2 = find_next_bit(array->bitmap, MAX_PRIO,MAX_RT_PRIO);

                    /*if nothing found, they must be expired*/
                    if(idx2 == MAX_PRIO && EXPIRED_STARVING(rq)){
                       rq->non_rt_starving = 1;
	               goto switch_tasks;
		     }
			
                   /*use process list at idx2*/
                    if(idx2 < MAX_PRIO){
                      queue = array->queue + idx2;
                      next = list_entry(queue->next, task_t, run_list);
                      rq->last_normal = now;
                      printk("allowing %d\n", next->pid);     
                      allowed = 1;
                     }
                 }
           }
        

#endif /*CONFIG_SCHED_RR_NONSTARVE*/

switch_tasks:

#ifdef CONFIG_RT_SWITCH_PRINT

        policy1 = prev->policy;
        policy2 = next->policy;

        if(allowed || (policy1 != SCHED_NORMAL || policy2 != SCHED_NORMAL)){

             switch (policy1){
                case SCHED_FIFO:
                printk("[{%d} ",prev->pid);
                break;
                case SCHED_RR:
                printk("[(%d) ",prev->pid);
                break;
                default:
                printk("[%d ",prev->pid);
                }

             switch (policy2){
                case SCHED_FIFO:
                printk("{%d} - %lu %lu]\n",next->pid, now.tv_sec, 
now.tv_usec);
                break;
                case SCHED_RR:
                printk("(%d) - %lu %lu]",next->pid, now.tv_sec, now.tv_usec);
                break;
                default:
                printk("%d - %lu %lu]",next->pid, now.tv_sec, now.tv_usec);
                }
#ifdef CONFIG_RT_PRINT_DEFAULT
	     printk("\n");	
#endif /* CONFIG_RT_PRINT_DEFAULT*/


        }
#endif /*CONFIG_RT_SWITCH_PRINT */

	prefetch(next);
	clear_tsk_need_resched(prev);

	if (likely(prev != next)) {
		rq->nr_switches++;
		rq->curr = next;
	
		prepare_arch_switch(rq, next);
		prev = context_switch(prev, next);
		barrier();
		rq = this_rq();
		finish_arch_switch(rq, prev);
	} else
		spin_unlock_irq(&rq->lock);

	reacquire_kernel_lock(current);
	preempt_enable_no_resched();
	if (need_resched())
		goto need_resched;
}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: garbage returned from do_gettimeofday
  2002-09-18 23:00 garbage returned from do_gettimeofday anton wilson
@ 2002-09-19 15:53 ` anton wilson
  2002-09-19 22:34   ` anton wilson
  0 siblings, 1 reply; 4+ messages in thread
From: anton wilson @ 2002-09-19 15:53 UTC (permalink / raw)
  To: linux-kernel

On Wednesday 18 September 2002 07:00 pm, anton wilson wrote:
> I'm using do_gettimeofday in the scheduler, once per schedule.
> Ocassioanlly, i'll get what seems to be a random garbage number.
> For example:
>
> tv_sec     tv_usec
> 1032378775 627501
> 1032378775 627521
> 3433001412 1
> 1032378775 627573
> 1032378775 627617
> 1032378775 627638
>
> or
>
> 1032379233 253008
> 1032379233 253028
> 3387638236 1
> 1032379233 253068
> 1032379233 253125
>
>
> The garbage number tv_sec always seems to begin with a 3 and is followed by
> 9 digits. The tv_usec garbage number is always 1.
>

Even more stangely, I'll get a sequence of the same garbage time from 
do_gettimeofday, interleaved with good values:

tv_sec     tv_usec  jiffies 

1032450154 41056 -- 108690]
1032450154 42045 -- 108690]
1032450154 42056 -- 108690]
1032450154 43045 -- 108690]
1032450154 43056 -- 108690]

/*garbage starts here*/
3390722356 1 -- 108690]
1032450154 43090 -- 108690]
3390722356 1 -- 108690]
1032450154 43177 -- 108690]
3390722356 1 -- 108690]
1032450154 43204 -- 108690]
3390722356 1 -- 108690]
1032450154 43257 -- 108690]
3390722356 1 -- 108690]
1032450154 43287 -- 108690]
3390722356 1 -- 108690]
/*garbage values stop for now*/
1032450154 44064 -- 108690]


1032450154 44084 -- 108690]
1032450154 44212 -- 108690]
1032450154 45047 -- 108690]
1032450154 45059 -- 108690]
1032450154 46045 -- 108690]


I'm using 2.4.19 with rc2, low-latency, premptive, O(1), and kdb patches.

Anton

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: garbage returned from do_gettimeofday
  2002-09-19 15:53 ` anton wilson
@ 2002-09-19 22:34   ` anton wilson
  2002-09-20 16:43     ` george anzinger
  0 siblings, 1 reply; 4+ messages in thread
From: anton wilson @ 2002-09-19 22:34 UTC (permalink / raw)
  To: linux-kernel


>
> 1032450154 41056 -- 108690]
> 1032450154 42045 -- 108690]
> 1032450154 42056 -- 108690]
> 1032450154 43045 -- 108690]
> 1032450154 43056 -- 108690]
>
> /*garbage starts here*/
> 3390722356 1 -- 108690]
> 1032450154 43090 -- 108690]
> 3390722356 1 -- 108690]
> 1032450154 43177 -- 108690]
> 3390722356 1 -- 108690]
> 1032450154 43204 -- 108690]
> 3390722356 1 -- 108690]
> 1032450154 43257 -- 108690]
> 3390722356 1 -- 108690]
> 1032450154 43287 -- 108690]
> 3390722356 1 -- 108690]
> /*garbage values stop for now*/
> 1032450154 44064 -- 108690]
>
>
> 1032450154 44084 -- 108690]
> 1032450154 44212 -- 108690]
> 1032450154 45047 -- 108690]
> 1032450154 45059 -- 108690]
> 1032450154 46045 -- 108690]
>
>
> I'm using 2.4.19 with rc2, low-latency, premptive, O(1), and kdb patches.


hmm. The pre-emptive patch skipped my do_gettimeofday call and shot me in the 
foot. ..

Anton

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: garbage returned from do_gettimeofday
  2002-09-19 22:34   ` anton wilson
@ 2002-09-20 16:43     ` george anzinger
  0 siblings, 0 replies; 4+ messages in thread
From: george anzinger @ 2002-09-20 16:43 UTC (permalink / raw)
  To: anton wilson; +Cc: linux-kernel

anton wilson wrote:
> 
> >
> > 1032450154 41056 -- 108690]
> > 1032450154 42045 -- 108690]
> > 1032450154 42056 -- 108690]
> > 1032450154 43045 -- 108690]
> > 1032450154 43056 -- 108690]
> >
> > /*garbage starts here*/
> > 3390722356 1 -- 108690]
> > 1032450154 43090 -- 108690]
> > 3390722356 1 -- 108690]
> > 1032450154 43177 -- 108690]
> > 3390722356 1 -- 108690]
> > 1032450154 43204 -- 108690]
> > 3390722356 1 -- 108690]
> > 1032450154 43257 -- 108690]
> > 3390722356 1 -- 108690]
> > 1032450154 43287 -- 108690]
> > 3390722356 1 -- 108690]
> > /*garbage values stop for now*/
> > 1032450154 44064 -- 108690]
> >
> >
> > 1032450154 44084 -- 108690]
> > 1032450154 44212 -- 108690]
> > 1032450154 45047 -- 108690]
> > 1032450154 45059 -- 108690]
> > 1032450154 46045 -- 108690]
> >
> >
> > I'm using 2.4.19 with rc2, low-latency, premptive, O(1), and kdb patches.
> 
> hmm. The pre-emptive patch skipped my do_gettimeofday call and shot me in the
> foot. ..

Eh, better be a bit more specific and detailed before you go
to the doctor with that foot, else we might amputate :)

-g
> 
> Anton
> -
> 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/

-- 
George Anzinger   george@mvista.com
High-res-timers: 
http://sourceforge.net/projects/high-res-timers/
Preemption patch:
http://www.kernel.org/pub/linux/kernel/people/rml

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-09-20 16:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-09-18 23:00 garbage returned from do_gettimeofday anton wilson
2002-09-19 15:53 ` anton wilson
2002-09-19 22:34   ` anton wilson
2002-09-20 16:43     ` george anzinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).