時間子係統6_高分辨率定時器框架初始化
// 高分辨率定時器框架初始化
// 調用路徑:start_kernel->hrtimers_init
// 函數任務:
// 1.創建cpu時鍾基礎
// 2.注冊監聽cpu狀態變化
// 3.注冊高分辨率模式下的定時器軟中斷
// 注:
// 1.高分辨率定時器框架的通用部分總是編譯進內核
// 2.高分辨率定時器框架初始為未激活狀態,由低分辨率定時器軟中斷中切換到高分辨率
1.1 void __init hrtimers_init(void)
{
//通知clockevent設備管理,創建cpu時鍾基礎
hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE,
(void *)(long)smp_processor_id());
//注冊監聽cpu 狀態信息
register_cpu_notifier(&hrtimers_nb);
//高分辨率定時功能通過預處理編譯進內核
#ifdef CONFIG_HIGH_RES_TIMERS
//注冊高分辨率模式下的定時器軟中斷
open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq);
#endif
}
// cpu狀態監聽控製塊
2.1 static struct notifier_block __cpuinitdata hrtimers_nb = {
.notifier_call = hrtimer_cpu_notify,
};
// 處理cpu狀態變化
// 函數任務:
// 1.cpu up,初始化cpu的時鍾基礎
// 2.針對熱插拔cpu
// 2.1 cpu dying、frozen,選擇cpu,接管do_timer
// 2.2 cpu dead、frozen
// 2.2.1 通知clockevent設備管理,cpu dead
// 2.2.2 遷移dead cpu上的hrtimer到本cpu
3.1 static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
int scpu = (long)hcpu;
switch (action)
{
//cpu up,初始化此cpu的時鍾基礎
case CPU_UP_PREPARE:
case CPU_UP_PREPARE_FROZEN:
init_hrtimers_cpu(scpu);
break;
//下列情況隻針對熱插拔cpu
#ifdef CONFIG_HOTPLUG_CPU
case CPU_DYING:
case CPU_DYING_FROZEN:
//選擇cpu接管do_timer
clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu);
break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
//通知clockevent設備管理,cpu dead
clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &scpu);
//遷移cpu上的定時任務到本cpu
migrate_hrtimers(scpu);
break;
#endif
default:
break;
}
return NOTIFY_OK;
}
// 初始化cpu的時鍾基礎
// 函數任務:
// 1.初始化REALTIME、MONOTOMIC兩個時鍾基礎
// 2.更新時鍾基礎到期時間為KTIME_MAX,即沒有hrtimer會到期
// 3.更新高分辨率定時器未激活狀態
// 調用路徑:init_hrtimers_cpu->init_hrtimers_cpu
4.1 static void __cpuinit init_hrtimers_cpu(int cpu)
{
//per cpu時鍾基礎設備,用於維護該cpu的hrtimer
struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
int i;
raw_spin_lock_init(&cpu_base->lock);
//初始化cpu時鍾基礎
for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++)
cpu_base->clock_base[i].cpu_base = cpu_base;
hrtimer_init_hres(cpu_base);
}
4.2 static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base)
{
//下一次事件到期的絕對時間,KTIME_MAX表示沒有hrtimer會到期
base->expires_next.tv64 = KTIME_MAX;
//高分辨率未激活狀態
base->hres_active = 0;
}
// cpu時鍾基礎數據結構
// 提供兩種時鍾基礎
// CLOCK_MONOTOMIC,係統啟動時從0開始,不會跳變,始終單調的運行
// CLOCK_REALTIME,係統的實際時間,當係統時間改變時,會發生跳變
5.1 struct hrtimer_cpu_base {
raw_spinlock_t lock;
struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES];//當前cpu的時鍾基礎
#ifdef CONFIG_HIGH_RES_TIMERS
ktime_t expires_next; //下一次事件到期的絕對時間
int hres_active; //高分辨率狀態
int hang_detected; //最近一次hrtimer檢測到掛起
unsigned long nr_events; //中斷事件總數
unsigned long nr_retries; //有效的中斷事件總數
unsigned long nr_hangs; //中斷掛起的次數
ktime_t max_hang_time; //中斷處理程序hrtimer_interrupt可花費的最大時間
#endif
};
// 時鍾基礎數據結構
// hrtimer組織成紅黑樹的形式
5.2 struct hrtimer_clock_base {
struct hrtimer_cpu_base *cpu_base;
clockid_t index; //用於區分CLOCK_MONOTONIC,CLOCK_REALTIME
struct rb_root active; //所有活躍的hrtimer組織在紅黑樹中,active指向其樹根
struct rb_node *first; //第一個到期的hrtimer
ktime_t resolution; //時鍾基礎的分辨率,納秒為單位
ktime_t (*get_time)(void); //讀取該時鍾基礎的時間
ktime_t softirq_time; //在軟中斷中開始運行hrtimer的時間
#ifdef CONFIG_HIGH_RES_TIMERS
ktime_t offset; //時鍾相對於單調時鍾的偏移
#endif
};
最後更新:2017-04-03 14:54:29
上一篇:
時間子係統2_tick device管理機製
下一篇:
時間子係統8_動態時鍾(NO_HZ)
天氣預報執行計劃及完成程度+簡單而又不簡單獲取當前時間和解析農曆時間的純JAVA代碼
每年14PB數據存儲需求,海量交通安全數據如何安放?
判斷用戶輸入的數字是一個合法的電話號碼的正則表達式
PostgreSQL Oracle兼容性 - 計算字符長度與字節長度(char(?) 與varchar(?)空格如何計算長度)
[WCF權限控製]基於Windows用戶組的授權方式[下篇]
生產者消費者模式淺析
SQL Server vs Oracle 簡單語法比較
VS2010運行速度優化
2009.06.18 20:00天體15號球場連中六個三分,四個NBA三分,要多鍛煉!
“分布式事務”的理解(適用於訪問多個數據庫之間)