Messages in this thread | | | Date | Mon, 6 Jul 2009 22:31:39 +0200 (CEST) | From | Thomas Gleixner <> | Subject | Re: [PATCH] optimized ktime_get[_ts] for GENERIC_TIME=y |
| |
On Mon, 6 Jul 2009, Martin Schwidefsky wrote: > +ktime_t ktime_get(void) > +{ > + cycle_t cycle_now, cycle_delta; > + struct timespec time; > + unsigned long seq; > + s64 nsecs; > + > + do { > + seq = read_seqbegin(&xtime_lock); > + time.tv_sec = xtime.tv_sec + wall_to_monotonic.tv_sec; > + time.tv_nsec = xtime.tv_nsec + wall_to_monotonic.tv_nsec;
That's actually a violation of the timespec semantics. tv_nsec can end up greater than (10^9 - 1). Please use separate sec and nsec variables.
secs = xtime.tv_sec + wall_to_monotonic.tv_sec; nsecs = xtime.tv_nsec + wall_to_monotonic.tv_nsec;
> + /* read clocksource: */ > + cycle_now = clocksource_read(clock); > + > + /* calculate the delta since the last update_wall_time: */ > + cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; > + > + /* convert to nanoseconds: */ > + nsecs = cyc2ns(clock, cycle_delta);
So that needs to be changed to:
nsecs += cyc2ns(clock, cycle_delta);
> + > + } while (read_seqretry(&xtime_lock, seq)); > + nsecs += time.tv_sec * 1000000000ULL + time.tv_nsec; > + return (ktime_t) { .tv64 = nsecs };
This will break all 32bit architectures which do not have CONFIG_KTIME_SCALAR set.
With the above changes applied:
return ktime_add_ns(ktime_set(secs, 0), nsecs);
will do the trick. Might need some comments though :)
Thanks,
tglx
| |