linux時間子系統(三)
2.2.3 timekeeper初始化 void __init timekeeping_init(void) { struct clocksource *clock; unsigned long flags; struct timespec now, boot;
read_persistent_clock(&now); read_boot_clock(&boot);
raw_spin_lock_irqsave(&xtime_lock, flags); write_seqcount_begin(&xtime_seq);
ntp_init();
clock = clocksource_default_clock(); if (clock->enable) clock->enable(clock); timekeeper_setup_internals(clock);
xtime.tv_sec = now.tv_sec; xtime.tv_nsec = now.tv_nsec; raw_time.tv_sec = 0; raw_time.tv_nsec = 0; if (boot.tv_sec == 0 && boot.tv_nsec == 0) { boot.tv_sec = xtime.tv_sec; boot.tv_nsec = xtime.tv_nsec; } set_normalized_timespec(&wall_to_monotonic, -boot.tv_sec, -boot.tv_nsec); total_sleep_time.tv_sec = 0; total_sleep_time.tv_nsec = 0; write_seqcount_end(&xtime_seq); raw_spin_unlock_irqrestore(&xtime_lock, flags); } 從初始化函式中可以看到,核心首先通過read_persistent_clock函式,從RTC硬體中獲取RTC time。如果不存在RTC硬體,則RTC time被初始化為0。之後,初始化xtime,raw_time,wall_to_monotonic和total_sleep_time。 2.2.4 時間更新2.2.4.1 xtime和raw_time更新 static void timekeeping_forward_now(void) { cycle_t cycle_now, cycle_delta; struct clocksource *clock; s64 nsec;
clock = timekeeper.clock; cycle_now = clock->read(clock); cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; clock->cycle_last = cycle_now;
nsec = clocksource_cyc2ns(cycle_delta, timekeeper.mult, timekeeper.shift);
/* If arch requires, add in gettimeoffset() */ nsec += arch_gettimeoffset();
timespec_add_ns(&xtime, nsec);
nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); timespec_add_ns(&raw_time, nsec); } 在本函式中,首先計算當前時刻與上一次呼叫read回撥函式時刻clocksoure計數值的差值,記為cycle_delta。之後,在計算xtime的調整時長時,使用的是timekeeper結構中的mult和shift欄位,而在計算raw_time的調整時長時,使用的是clocksource的mult和shift欄位。因timekeeper的mult欄位會被ntp調整,所以說xtime受ntp調整的影響而raw_time不受ntp調整的影響。 2.2.4.2 total_sleep_time/monotonic timestatic void __timekeeping_inject_sleeptime(struct timespec *delta) { xtime = timespec_add(xtime, *delta); wall_to_monotonic = timespec_sub(wall_to_monotonic, *delta); total_sleep_time = timespec_add(total_sleep_time, *delta); } 在休眠結束時會呼叫__timekeeping_inject_sleeptime來調整時間。由於xtime是牆上時間,所以必須加上休眠時間。monotonic time不受休眠時間的影響,所以需要在wall_to_monotonic中減去相應的休眠時間,這樣xtime與wall_to_monotonic的和所表示的monotonic time的值就沒有發生跳變。在最後,更新total_sleep_time的值。 由於monotonic time的值是xtime與wall_to_monotonic之和,所以除了休眠時間和使用do_settimeofday調整時間時需要調整wall_to_monotonic外,其他時候,monotonic time隨xtime增長而增長。所以大部分時間我們不需要調整wall_to_monotonic變數的值。 |
相關文章
- Linux 系統時間和硬體時間Linux
- 修改linux系統時間Linux
- linux同步系統時間Linux
- linux修改系統時間Linux
- linux 修改系統時間Linux
- linux系統時間設定Linux
- Linux設定系統時間Linux
- Linux系統時間同步方法。Linux
- linux調整系統時間Linux
- Linux系統如何更改時間時區Linux
- Linux時間設定系統時間、硬體時間和時間服務Linux
- Linux系統中檔案時間常用的三種型別!Linux型別
- 【原創】解BUG-xenomai核心與linux核心時間子系統之間存在漂移AILinux
- 調整linux系統時間和時區Linux
- Linux系統自動更新時間Linux
- linux系統時間修改及同步Linux
- Linux怎樣修改系統時間Linux
- linux下的系統時間、硬體時間設定Linux
- Linux時間子系統之八:動態時鐘框架(CONFIG_NO_HZ、tickless)Linux框架
- 直播系統程式碼,linux date修改系統時間Linux
- Linux時間子系統之七:定時器的應用--msleep(),hrtimer_nanosleep()Linux定時器NaN
- Linux時間子系統之八:動態時鐘框架(CONFIG_NO_HZ、tickless)【轉】Linux框架
- Linux檢視系統開機時間Linux
- ntpdate重新整理linux系統時間Linux
- windows以及linux獲取系統時間WindowsLinux
- Linux系統修改日期及時間Linux
- Linux系統時間與RTC設定Linux
- Linux時間子系統之七:定時器的應用--msleep(),hrtimer_nanosleep()【轉】Linux定時器NaN
- Linux調整系統時間和時區的方法Linux
- Linux系統時間同步方法小結(NTP)Linux
- Linux程式設計(獲取系統時間)Linux程式設計
- linux核心--子系統Linux
- 【原創】Linux中斷子系統(三)-softirq和taskletLinux
- Linux下如何檢視系統啟動時間和執行時間Linux
- 修改系統時間
- Linux驅動之GPIO子系統和pinctrl子系統Linux
- 系統時間和硬體時間同步
- linux學習筆記之小談時鐘時間,使用者CPU時間,系統CPU時間 .Linux筆記