/* * This version of gettimeofday has near microsecond resolution. */ void do_gettimeofday(struct timeval *tv) { unsigned long seq; unsigned long usec, sec; unsigned long max_ntp_tick = tick_usec - tickadj; do { seq = read_seqbegin(&xtime_lock); usec = do_gettimeoffset(); /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ if (unlikely(time_adjust < 0)) usec = min(usec, max_ntp_tick); 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; }
static int sbus_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; /* * 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 -= 1000 * (do_gettimeoffset() + (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ)); 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); time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; return 0; }
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 -= do_gettimeoffset() * NSEC_PER_USEC; nsec -= (jiffies - wall_jiffies) * TICK_NSEC; 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; }
int do_settimeofday(struct timespec *tv) { unsigned long flags; if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) return -EINVAL; local_irq_save(flags); local_irq_disable(); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. * Discover what correction gettimeofday * would have done, and then undo it! */ tv->tv_nsec -= do_gettimeoffset() * 1000; tv->tv_nsec -= (jiffies - wall_jiffies) * TICK_NSEC; while (tv->tv_nsec < 0) { tv->tv_nsec += NSEC_PER_SEC; tv->tv_sec--; } xtime.tv_sec = tv->tv_sec; xtime.tv_nsec = tv->tv_nsec; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_state = TIME_ERROR; /* p. 24, (a) */ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; local_irq_restore(flags); return 0; }
/* * This version of gettimeofday has near microsecond resolution. * * Note: Division is quite slow on CRIS and do_gettimeofday is called * rather often. Maybe we should do some kind of approximation here * (a naive approximation would be to divide by 1024). */ void do_gettimeofday(struct timeval *tv) { unsigned long flags; signed long usec, sec; local_irq_save(flags); usec = do_gettimeoffset(); /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ if (unlikely(time_adjust < 0) && usec > tickadj) usec = tickadj; sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; local_irq_restore(flags); while (usec >= 1000000) { usec -= 1000000; sec++; } tv->tv_sec = sec; tv->tv_usec = usec; }
static int sbus_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; /* * 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 -= 1000 * do_gettimeoffset(); 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(); return 0; }
void do_settimeofday(struct timeval *tv) { write_lock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. * Discover what correction gettimeofday * would have done, and then undo it! */ tv->tv_usec -= do_gettimeoffset(); if (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } xtime = *tv; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; write_unlock_irq (&xtime_lock); }
/* * This version of gettimeofday has near microsecond resolution. */ static inline void do_gettimeofday(struct timeval *tv) { #ifdef __i386__ cli(); *tv = xtime; tv->tv_usec += do_gettimeoffset(); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } sti(); #else /* not __i386__ */ cli(); *tv = xtime; sti(); #endif /* not __i386__ */ }
/* * The first time we set the timezone, we will warp the clock so that * it is ticking GMT time instead of local time. Presumably, * if someone is setting the timezone then we are running in an * environment where the programs understand about timezones. * This should be done at boot time in the /etc/rc script, as * soon as possible, so that the clock can be set right. Otherwise, * various programs will get confused when the clock gets warped. */ asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz) { static int firsttime = 1; //if (!suser()) // return -EPERM; if (tz) { sys_tz.tz_minuteswest = get_fs_long((unsigned long *) tz); sys_tz.tz_dsttime = get_fs_long(((unsigned long *) tz)+1); if (firsttime) { firsttime = 0; if (!tv) warp_clock(); } } if (tv) { int sec, usec; sec = get_fs_long((unsigned long *)tv); usec = get_fs_long(((unsigned long *)tv)+1); cli(); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. * Discover what correction gettimeofday * would have done, and then undo it! */ usec -= do_gettimeoffset(); if (usec < 0) { usec += 1000000; sec--; } xtime.tv_sec = sec; xtime.tv_usec = usec; time_status = TIME_BAD; time_maxerror = 0x70000000; time_esterror = 0x70000000; sti(); } return 0; }
void do_settimeofday(struct timeval *tv) { write_lock_irq(&xtime_lock); tv->tv_usec -= do_gettimeoffset(); tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); while (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } xtime = *tv; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; write_unlock_irq(&xtime_lock); }
/* Ok, my cute asm atomicity trick doesn't work anymore. * There are just too many variables that need to be protected * now (both members of xtime, wall_jiffies, et al.) */ void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; unsigned long usec, sec; unsigned long max_ntp_tick = tick_usec - tickadj; do { unsigned long lost; seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = do_gettimeoffset(); lost = jiffies - wall_jiffies; /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); if (lost) usec += lost * max_ntp_tick; } else if (unlikely(lost)) usec += lost * tick_usec; sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; sec++; } tv->tv_sec = sec; tv->tv_usec = usec; }
/* * This version of gettimeofday has near microsecond resolution. */ void do_gettimeofday(struct timeval *tv) { unsigned long flags; save_and_cli(flags); *tv = xtime; tv->tv_usec += do_gettimeoffset(); /* * xtime is atomically updated in timer_bh. lost_ticks is * nonzero if the timer bottom half hasnt executed yet. */ if (lost_ticks) tv->tv_usec += USECS_PER_JIFFY; restore_flags(flags); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } }
/* * timeofday services, for syscalls. */ void do_gettimeofday(struct timeval *tv) { unsigned long flags; read_lock_irqsave (&xtime_lock, flags); *tv = xtime; tv->tv_usec += do_gettimeoffset(); /* * xtime is atomically updated in timer_bh. jiffies - wall_jiffies * is nonzero if the timer bottom half hasnt executed yet. */ if (jiffies - wall_jiffies) tv->tv_usec += USECS_PER_JIFFY; read_unlock_irqrestore (&xtime_lock, flags); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } }
/* * This version of gettimeofday has near microsecond resolution. * * Note: Division is quite slow on CRIS and do_gettimeofday is called * rather often. Maybe we should do some kind of approximation here * (a naive approximation would be to divide by 1024). */ void do_gettimeofday(struct timeval *tv) { unsigned long flags; signed long usec, sec; local_irq_save(flags); local_irq_disable(); usec = do_gettimeoffset(); { unsigned long lost = jiffies - wall_jiffies; if (lost) usec += lost * (1000000 / HZ); } sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; local_irq_restore(flags); while (usec >= 1000000) { usec -= 1000000; sec++; } tv->tv_sec = sec; tv->tv_usec = usec; }
void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long usec, sec; read_lock_irqsave(&xtime_lock, flags); usec = do_gettimeoffset(); { unsigned long lost = jiffies - wall_jiffies; if (lost) usec += lost * (1000000 / HZ); } sec = xtime.tv_sec; usec += xtime.tv_usec; read_unlock_irqrestore(&xtime_lock, flags); while (usec >= 1000000) { usec -= 1000000; sec++; } tv->tv_sec = sec; tv->tv_usec = usec; }
u32 arch_gettimeoffset(void) { return do_gettimeoffset() * 1000; }