[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: non-monotonic do_gettimeofday?



On Friday 06 September 2002 17.16, Akshay Adhikari wrote:
> right, though out of curiosity, here's a couple of questions:
>
> -from an execution time point of view it doesnt make a difference, right?
> (or will the compiler possibly inline do_gettimeoffset in case it is
> shorter?)

I guess not, it would just make it easier from a maintenance point of view
to keep it similar to the other archs.
I found that the same thing is missing in do_settimeofday() etc.
I'll give the file a look...

> -how long is the timer interrupt (and in general, any level
> triggered interrupt) signalled? Just curious to know how long we would
> have to do a cli() to miss an interrupt...

Until it's cleared, and since it is set every 10 ms (HZ=100) - anything doing 
cli() for that long should be considered a bug:-)

> thanks,
> akshay

/Johan

> On Fri, 6 Sep 2002, Johan Adolfsson wrote:
> > On Friday 06 September 2002 16.15, Akshay Adhikari wrote:
> > > Right, changed it, and it works... thanks!
> > > akshay
> >
> > Great, but perhaps we should handle that in do_gettimeofday()
> > as they do it on i386 instead?
> >
> > void do_gettimeofday(struct timeval *tv)
> > {
> >         unsigned long flags;
> >
> >         save_flags(flags);
> >         cli();
> >         *tv = xtime;
> >         tv->tv_usec += do_gettimeoffset();
> > +        {
> > +                unsigned long lost = jiffies - wall_jiffies;
> > +                if (lost)
> > +                        usec += lost * (1000000 / HZ);
> > +        }
> >         restore_flags(flags);
> >         while (tv->tv_usec >= 1000000) {
> >                 tv->tv_usec -= 1000000;
> >                 tv->tv_sec++;
> >         }
> > }
> >
> > /Johan
> >
> > > On Fri, 6 Sep 2002, Johan Adolfsson wrote:
> > > > On Friday 06 September 2002 15.17, Akshay Adhikari wrote:
> > > > > here is a modified version of do_gettimeoffset and do_gettimeofday
> > > > > in time.c v.1.11, which seems to have drastically reduced the
> > > > > number of time warps, possibly because it accounts for unexcecuted
> > > > > timer bottom halves...
> > > >
> > > > Yes, you're right - we didn't handle that, but you missed one case I
> > > > think,
> > > >
> > > > see below:
> > > > > (assumption is that HZ is 100, but that can be changed easily..)
> > > >
> > > > To be clear you can write (1000000/HZ), the compiler will optimise it
> > > > so no division will take place at runtime anyway.
> > > >
> > > > > static unsigned long do_slow_gettimeoffset(void)
> > > > > {
> > > > >         unsigned long count;
> > > > >         unsigned long usec_count = 0;
> > > > >
> > > > >         static unsigned long count_p = LATCH;    /* for the first
> > > > > call after boot */
> > > > >         static unsigned long jiffies_p = 0;
> > > > >
> > > > >         unsigned long jiffies_t;
> > > > >
> > > > >         count = *R_TIMER0_DATA;
> > > > >         jiffies_t = jiffies;
> > > > >
> > > > >         usec_count = cris_timer0_value_us[count];
> > > > >         if( jiffies_t == jiffies_p ) {
> > > > >                 if( count > count_p ) {
> > > > >                         /*printk(KERN_WARNING "warp %ld to %ld\n",
> > > > > count_p, count);*/
> > > > >                         usec_count +=
> > > > > (jiffies_t-wall_jiffies+1)*10000; }
> > > >
> > > > Here you misses one case were wall_jiffies isn't handled.
> > > >
> > > > >         }
> > > > >
> > > > >         else
> > > > >                 usec_count+= (jiffies_t-wall_jiffies)*10000;
> > > >
> > > > I suggest changing the intire if statement to the following and
> > > > allways take care of the wall_jiffies:
> > > >
> > > >          if( jiffies_t == jiffies_p ) {
> > > >                  if( count > count_p ) {
> > > >                          /*printk(KERN_WARNING "warp %ld to %ld\n",
> > > > 		 count_p, count);*/
> > > >                          usec_count += (1000000/HZ);
> > > >                  }
> > > >          }
> > > >
> > > >          usec_count+= (jiffies_t-wall_jiffies)*(1000000/HZ);
> > > >
> > > > >         jiffies_p = jiffies_t;
> > > > >         count_p = count;
> > > > >         return usec_count;
> > > > > }