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
- 【原創】解BUG-xenomai核心與linux核心時間子系統之間存在漂移AILinux
- 直播系統程式碼,linux date修改系統時間Linux
- Linux系統時間同步方法小結(NTP)Linux
- 【原創】Linux中斷子系統(三)-softirq和taskletLinux
- Linux 獲取系統開機/啟動時間Linux
- linux系統中 SElinux安全子系統Linux
- Linux中斷子系統Linux
- linux系統時間程式設計(8) UTC秒數轉本地字串時間Linux程式設計字串
- Linux驅動之GPIO子系統和pinctrl子系統Linux
- Android 校正系統時間的三種解決方案Android
- Linux ubi子系統原理分析Linux
- linux 如何建立定時任務?crontab -e 定時任務使用的時間是系統時間Linux
- Linux如何檢視系統/伺服器的執行時間及啟動時間?Linux伺服器
- linux系統時間程式設計(6) 日曆時間tm轉字串strftime函式Linux程式設計字串函式
- MES車間電子看板系統
- Linux系統檢查使用者賬戶到期時間Linux
- 趣談Linux作業系統-劉超-極客時間Linux作業系統
- Shell指令碼——Linux系統中的時間猜數字指令碼Linux
- 獲取系統時間
- linux系統時間程式設計(9) 計算程式片段執行時間clock函式Linux程式設計函式
- Linux Media 子系統鏈路分析Linux
- linux usb 子系統(二)- host driverLinux
- Windows linux子系統 使用說明WindowsLinux
- Windows10系統如何重置/登出Linux子系統WindowsLinux
- 如何系統學習Linux運維?怎麼時間規劃?Linux運維
- 雲伺服器Linux系統設定時間同步設定伺服器Linux
- windows系統安裝時間修改,win10修改系統安裝時間WindowsWin10
- 嵌入式Linux—輸入子系統Linux
- Arm-Linux子系統的互相NotifyLinux
- 【linux】驅動-11-gpio子系統Linux
- 【linux】驅動-10-pinctrl子系統Linux