void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; unsigned long usec, sec; do { /* * Turn off IRQs when grabbing xtime_lock, so that * the sys_timer get_offset code doesn't have to handle it. */ seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = get_timer_offset(); sec = xtime.tv_sec; usec += xtime.tv_nsec / NSEC_PER_USEC; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; sec++; } tv->tv_sec = sec; tv->tv_usec = usec; }
int do_settimeofday(struct timespec *tv) { time_t wtm_sec, sec = tv->tv_sec; long wtm_nsec, nsec = tv->tv_nsec; if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) return -EINVAL; write_seqlock_irq(&xtime_lock); /* * This is revolting. We need to set "xtime" correctly. However, the * value in this location is the value at the most recent update of * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ nsec -= get_timer_offset() * NSEC_PER_USEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; }
void do_gettimeofday(struct timeval *tv) { unsigned long seq; unsigned long usec, sec; unsigned long lost; do { seq = read_seqbegin(&xtime_lock); usec = get_timer_offset(); lost = jiffies - wall_jiffies; if (lost) usec += lost * (1000000 / HZ); sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; } while (read_seqretry(&xtime_lock, seq)); while (usec >= 1000000) { usec -= 1000000; sec++; } tv->tv_sec = sec; tv->tv_usec = usec; }