1. 程式人生 > >Linux核心時間管理子系統——時鐘源

Linux核心時間管理子系統——時鐘源

struct clocksource {
        /*
         * Hotpath data, fits in a single cache line when the
         * clocksource itself is cacheline aligned.
         */
        cycle_t (*read)(struct clocksource *cs);
        cycle_t cycle_last;
        cycle_t mask;
        u32 mult;
        u32 shift;
        u64 max_idle_ns;
        u32 maxadj;
#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
        struct arch_clocksource_data archdata;
#endif

        const char *name;
        struct list_head list;
        int rating;
        int (*enable)(struct clocksource *cs);
        void (*disable)(struct clocksource *cs);
        unsigned long flags;
        void (*suspend)(struct clocksource *cs);
        void (*resume)(struct clocksource *cs);

        /* private: */
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
        /* Watchdog related data, used by the framework */
        struct list_head wd_list;
        cycle_t cs_last;
        cycle_t wd_last;
#endif
} ____cacheline_aligned;

read()

返回當前時鐘源的計數值,即cycle數。

rating

時鐘源的等級,越高越好。

mult和shift

用於將時鐘源的計數值換算為納秒,即(cycle * mult) >> shift 可以得到相應的納秒數。

mask

時鐘源的計數值用型別cycle_t表示,該型別其實就是無符號64位數。但是時鐘源實際的計數範圍可能小於64位,mask的作用就是表示真實的計數範圍。對於一個32位的時鐘源硬體,mask等於0xffffffff,即32個bit 1。這種方法的好處是即使時鐘源發生溢位,一樣可以通過簡單的計算得出實際經歷的cycle數。如下所示,假設上次讀時鐘源得到的計數值是cycle_last,這次讀取的計數值是cycle_now,則經歷的cycle數等於: (cycle_now - cycle_last) & mask 對於一個32位的時鐘源,假設cycle_last=0xffffffff,cycle_now=0,即發生了溢位,通過上面的等式依然可以得到經歷了一次cycle。

max_idle_ns

表示兩次讀取之間所允許的最大時間間隔。當兩次讀取間隔超過mask+1時就無法正確計算出經歷的cycle數,因此該數值需要小於mask+1個cycle所對應的納秒數。另一個限制因素來自於clocksource_cyc2ns()函式。該函式用於將cycle數換算成納秒。由於函式返回值是有符號64位數(s64),兩次讀取間隔的cycle數不能使最終的計算結果溢位。

時鐘源的註冊

核心提供了多個函式用於註冊新的時鐘源。其中帶_hz或_khz字尾的函式可以根據hz/khz引數自動計算mult和shift,簡化了呼叫者的負擔。
extern int clocksource_register(struct clocksource*);
static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)
註冊函式完成下面的工作: 1. 將新的clock source掛在連結串列clocksource_list上。連結串列上的時鐘源按rating從大到小排序。 2. 根據clock source的flags決定是否需要將新的clock source掛在連結串列watchdog_list上。詳見clock source watchdog一節。 3. 選擇具有最高rating的時鐘源並將其設定為當前時鐘源(curr_clocksource指向當前使用的時鐘源)。使用者可以通過sysfs強制指定某個時鐘源,詳見使用者介面一節。

Clock Source Watchdog

核心選擇rating最高的時鐘源作為watchdog時鐘源監測其他時鐘源的誤差。如果新註冊的時鐘源的flags包含CLOCK_SOURCE_MUST_VERIFY,表示該時鐘源需要經過watchdog的監測。如果兩者之間在0.5s內的誤差大於0.0625秒,則新註冊的時鐘源被認為是unstable的。如果誤差小於該標準,且滿足下面的情況,則新註冊的時鐘源被標記為CLOCK_SOURCE_VALID_FOR_HRES,即高精度時鐘。 1. 新註冊的時鐘源的flags包含CLOCK_SOURCE_IS_CONTINUOUS。 2. watchdog時鐘源的flags包含CLOCK_SOURCE_VALID_FOR_HRES。

時鐘源的其他API

下面的API用於suspend和resume所有註冊過的時鐘源。
void clocksource_suspend(void)
void clocksource_resume(void)

下面的API用於將時鐘源標記為unstable

void clocksource_mark_unstable(struct clocksource *cs)

核心啟動過程與時鐘源

clocksource_done_booting執行前

核心完成如下工作:
1. 各種時鐘源的註冊。 2. 時鐘源watchdog對需要監測的時鐘源進行檢測。 3. 對於不符合標準的時鐘源,在clocksource_watchdog中該時鐘源被mark成unstable。由於此時finished_booting=0,因此不會啟動核心執行緒clocksource_watchdog_kthread。該執行緒的作用將在後面描述。

clocksource_done_booting執行中

在該函式中finished_booting被標記為1。
直接執行clocksource_watchdog_kthread,該函式將所有unstable的時鐘源的rating設定為0,並重新呼叫clocksource_select選擇當前使用的時鐘源。

clocksource_done_booting執行後

clocksource_done_booting函式被標記為fs_initcall,表示該函式將在subsys_initcall之後,device_initcall執行之前被執行。
此時finished_booting已經被標記為1,當任何時鐘源被標記為unstable時,將啟動核心執行緒clocksource_watchdog_kthread,如前所述,函式將重新設定時鐘源的rating並選擇當前的時鐘源。

sysfs介面

當前可用的時鐘源 /sys/devices/system/clocksource/clocksource0/available_clocksource
當前所用的時鐘源 /sys/devices/system/clocksource/clocksource0/current_clocksource


相關推薦

Linux核心時間管理子系統——時鐘

struct clocksource { /* * Hotpath data, fits in a single cache line when the * clocksource itself is cacheline aligned.

Linux核心時間管理相關的介面

在核心經常會碰到一些要定時排程的任務,可以用timer處理,下面來看看都有哪些介面, /*******************************************************************/ linux/param.h HZ;//巨集,每

[linux]linux核心時間管理基礎

一,linux時間管理基礎http://blog.csdn.net/droidphone/article/details/7975694http://blog.csdn.net/smilingjames/article/details/6205540 linux所有時間基礎

Linux核心時間管理和定時器

轉自:http://blog.csdn.net/zhenwenxian/article/details/7643742 時間管理在核心中佔有非常重要的地位。相對於事件驅動,核心中有大量的函式都是基於時間驅動的。核心必須管理系統的執行時間以及當前的日期和時間。 首先搞

linux核心初始化步驟(十)-----時間管理子系統初始化

參考博文:https://blog.csdn.net/DroidPhone/article/details/8051405 時間管理子系統: /* 核心用jiffies變數記錄系統啟動以來經過的時鐘滴答數*/ Jiffies.c (kernel\time):core_initcall(ini

【原創】解BUG-xenomai核心linux核心時間子系統之間存在漂移

版權宣告:本文為本文為博主原創文章,轉載請註明出處。如有問題,歡迎指正。部落格地址:https://www.cnblogs.com/wsg1100/ ## 一、問題起源 >何為漂移?舉個例子兩顆32.768kHz晶振$C_1$和$C_2$,由於製造工藝原因或者使用時溫度、輔助元件引數等影響,與他們的實際

Linux程序包管理之yum安裝

文件夾 ide IT update 事務 lob dde 重新安裝 顯示 yum源安裝是我們工作中常用的一種方式,它是在Fedora和RedHat以及SUSE中基於rpm的軟件包管理器,它可以使系統管理人員交互和自動化地更細與管理RPM軟件包,能夠從指定的服務器自動下載RP

Linux軟件管理之src碼安裝編譯

可能 form 就是 參考 install 官方 dev fluent 幫助 在很多時候我們需要自定義軟件的特性,這時就需要用到源碼安裝。那麽,網上有很多編譯源碼的工具,那麽,我們怎麽知道別人使用的是什麽工具呢。其實我也不知道(*^▽^*)。 那麽本篇博客主要是寫C代碼的源

Linux核心電源管理綜述

資料:http://blog.csdn.net/bingqingsuimeng/article/category/1228414http://os.chinaunix.net/a2006/0519/1002/000001002210.shtmlhttp://www.ednchina.com/ART_44010

linux核心的I2C子系統

1、I2C匯流排彙總概念   (1)三根訊號線:SCL、SDA、GND   (2)同步、序列、電平、低速、近距離   (3)匯流排式結構,支援多個裝置掛接在同一條總線上   (4)主從式結構,通訊雙方必須一個為主(master)一個為從(slave),主裝置掌握每次通訊的主動權,從裝置按照主裝置的節奏

Linux 核心初級管理

Linux 核心初步管理     單核心體系設計,但充分借鑑了微核心設計體系的優點,微核心引入模組化機制;         核心組成部分:             kernel:核心核心,一般為bzImage,通常在/boot目錄下,名稱為vmlinuz-VERSION-RE

深入理解 Linux 核心---記憶體管理

核心中的函式以比較直接了當的方式獲得動態記憶體: __get_free_pages() 或 alloc_pages() 從分割槽頁框分配器獲得頁框。 kmem_cache_alloc() 或 kmalloc() 使用 slab 分配器為專用或通用物件分配塊。 vm

linux系統時間和硬體時鐘時間 FAQ

Linux有兩個時鐘, 一個是system time, 一個是hardware clock. 使用date和hwclock命令可分別檢視和設定系統時間和硬體時間. The Hardware Clock: 該時鐘通常稱為硬體時鐘,實時時鐘(RTC,real time cloc

linux核心時間操作

linux核心是通過定時器中斷來跟蹤時間流;使用"HZ"巨集表示1秒的時鐘中斷次數,並使用"jiffies"及"jiffies_64"變數來記錄時鐘中斷次數,在系統引導時計數器初始化為 0 1 核心時間比較api, 比較jiffies計數器#include <linu

arm-linux核心中串列埠時鐘頻率及波特率的設定

本人使用的核心版本為linux-2.6.32,採用的ARM處理器為cortex-A8,採用的串列埠為NS16550。串列埠的驅動直接編譯在核心中,當需要修改串列埠的時鐘頻率和波特率的時候, 需要修改以下地方。 1、在板子平臺目錄下平臺相關的標頭檔案路徑下串列埠的標頭檔案中,

LINUX核心記憶體管理kmalloc,vmalloc

1 #include <linux/init.h> 2 #include <linux/thread_info.h> 3 #include <linux/module.h> 4 #include <linux/sched.h> 5

深入淺出Linux核心記憶體管理基礎

1 背景 記憶體管理是Linux核心通過軟硬體協作來管理記憶體的分配及回收的一種方法。在Linux系統上電自檢(POST,Power-On-Self-Test)階段使用臨時記憶體,而系統啟動後正常執行階段的記憶體使用又有兩大類:(1)固定的記憶體分配,是永久的不變的,主要

Linux核心之mmc子系統-sdio

現在的Linux核心中,mmc不僅是一個驅動,而是一個子系統。這裡通過分析Linux3.2.0核心,結合TI的arm335x平臺及omap_hsmmcd host分析下mmc子系統,重點關注sdio及架構在其上的具體sdio IP驅動實現。 1.      Genera

linux 核心時間列印

struct timespec ts; ts = current_kernel_time(); printk(KERN_ALERT "i=%d, channel=%d, %ld %ld\n", i, channel, ts.tv_sec, ts.tv_nsec); stru

linux核心記憶體管理學習之二(實體記憶體管理--夥伴系統)

linux使用夥伴系統來管理實體記憶體頁。 一、夥伴系統原理 1. 夥伴關係 定義:由一個母實體分成的兩個各方面屬性一致的兩個子實體,這兩個子實體就處於夥伴關係。在作業系統分配記憶體的過程中,一個記憶體塊常常被分成兩個大小相等的記憶體塊,這兩個大小相等的記憶體塊就處於夥伴關