int do_settimeofday(struct timespec *tv) { unsigned long flags; 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_irqsave(&xtime_lock, flags);
nsec -= __get_nsec_offset();
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); /* 重新计算xtime: 用户设置的时间减去上一个周期到现在的nsec */ set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); /* 重新调整wall_to_monotonic */
clock->error = 0; ntp_clear();
update_vsyscall(&xtime, clock); write_sequnlock_irqrestore(&xtime_lock, flags); /* signal hrtimers about time change */ clock_was_set();
return 0; }
|