自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

鴻蒙內(nèi)核源碼分析(時(shí)間管理篇) | Tick是操作系統(tǒng)的基本時(shí)間單位

系統(tǒng)
文章由鴻蒙社區(qū)產(chǎn)出,想要了解更多內(nèi)容請(qǐng)前往:51CTO和華為官方戰(zhàn)略合作共建的鴻蒙技術(shù)社區(qū)https://harmonyos.51cto.com

[[390985]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

本篇說清楚時(shí)間概念

讀本篇之前建議先讀鴻蒙內(nèi)核源碼分析(總目錄)其他篇.

時(shí)間概念太重要了,在鴻蒙內(nèi)核又是如何管理和使用時(shí)間的呢?

時(shí)間管理以系統(tǒng)時(shí)鐘 g_sysClock 為基礎(chǔ),給應(yīng)用程序提供所有和時(shí)間有關(guān)的服務(wù)。

[[390986]]

● 用戶以秒、毫秒為單位計(jì)時(shí).

● 操作系統(tǒng)以Tick為單位計(jì)時(shí),這個(gè)認(rèn)識(shí)很重要. 每秒的tick大小很大程度上決定了內(nèi)核調(diào)度的次數(shù)多少.

● 當(dāng)用戶需要對(duì)系統(tǒng)進(jìn)行操作時(shí),例如任務(wù)掛起、延時(shí)等,此時(shí)需要時(shí)間管理模塊對(duì)Tick和秒/毫秒進(jìn)行轉(zhuǎn)換。

熟悉兩個(gè)概念:

● Cycle(周期):系統(tǒng)最小的計(jì)時(shí)單位。Cycle的時(shí)長由系統(tǒng)主時(shí)鐘頻率決定,系統(tǒng)主時(shí)鐘頻率就是每秒鐘的Cycle數(shù)。

● Tick(節(jié)拍):Tick是操作系統(tǒng)的基本時(shí)間單位,由用戶配置的每秒Tick數(shù)決定,可大可小.

怎么去理解他們之間的關(guān)系呢?看幾個(gè)宏定義就清楚了.

時(shí)鐘周期(振蕩周期)

在鴻蒙g_sysClock表示時(shí)鐘周期,是CPU的赫茲,也就是上面說的Cycle,這是固定不變的,由硬件晶振的頻率決定的. OsMain是內(nèi)核運(yùn)行的第一個(gè)C函數(shù),首個(gè)子函數(shù)就是 osRegister,完成對(duì)g_sysClock的賦值

CPU周期也叫(機(jī)器周期)

在鴻蒙宏OS_CYCLE_PER_TICK表示機(jī)器周期,Tick由用戶根據(jù)實(shí)際情況配置. 例如:主頻為1G的CPU,其振蕩周期為: 1吉赫 (GHz 109 Hz) = 1 000 000 000 Hz 當(dāng)Tick為100時(shí),則1 000 000 000/100 = 10000000 ,即一秒內(nèi)可產(chǎn)生1千萬個(gè)CPU周期.CPU就是用這1千萬個(gè)周期去執(zhí)行指令的.

指令周期

指令周期是執(zhí)行一條指令所需要的時(shí)間,一般由若干個(gè)機(jī)器周期組成。指令不同,所需的機(jī)器周期數(shù)也不同。 對(duì)于一些簡單的的單字節(jié)指令,在取指令周期中,指令取出到指令寄存器后,立即譯碼執(zhí)行,不再需要其它的機(jī)器周期。 對(duì)于一些比較復(fù)雜的指令,例如轉(zhuǎn)移指令、乘法指令,則需要兩個(gè)或者兩個(gè)以上的機(jī)器周期。 通常含一個(gè)機(jī)器周期的指令稱為單周期指令,包含兩個(gè)機(jī)器周期的指令稱為雙周期指令。

Tick硬中斷函數(shù)

  1. LITE_OS_SEC_BSS volatile UINT64 g_tickCount[LOSCFG_KERNEL_CORE_NUM] = {0};//tick計(jì)數(shù)器,系統(tǒng)一旦啟動(dòng),一直在++, 為防止溢出,這是一個(gè) UINT64 的變量 
  2. LITE_OS_SEC_DATA_INIT UINT32 g_sysClock;//系統(tǒng)時(shí)鐘,是絕大部分部件工作的時(shí)鐘源,也是其他所有外設(shè)的時(shí)鐘的來源  
  3. LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond;//每秒Tick數(shù),鴻蒙默認(rèn)是每秒100次,即:10ms 
  4. LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; //周期轉(zhuǎn)納秒級(jí) 
  5.  
  6. /* spinlock for task module */ 
  7. LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); //節(jié)拍器自旋鎖 
  8. #define TICK_LOCK(state)                       LOS_SpinLockSave(&g_tickSpin, &(state)) 
  9. /* 
  10.  * Description : Tick interruption handler 
  11.  *///節(jié)拍中斷處理函數(shù) ,鴻蒙默認(rèn)10ms觸發(fā)一次 
  12. LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) 
  13.     UINT32 intSave; 
  14.  
  15.     TICK_LOCK(intSave); 
  16.     g_tickCount[ArchCurrCpuid()]++;//當(dāng)前CPU核計(jì)數(shù)器 
  17.     TICK_UNLOCK(intSave); 
  18.  
  19. #ifdef LOSCFG_KERNEL_VDSO 
  20.     OsUpdateVdsoTimeval(); 
  21. #endif 
  22.  
  23. #ifdef LOSCFG_KERNEL_TICKLESS 
  24.     OsTickIrqFlagSet(OsTicklessFlagGet()); 
  25. #endif 
  26.  
  27. #if (LOSCFG_BASE_CORE_TICK_HW_TIME == YES) 
  28.     HalClockIrqClear(); /* diff from every platform */ 
  29. #endif 
  30.  
  31.     OsTimesliceCheck();//時(shí)間片檢查 
  32.  
  33.     OsTaskScan(); /* task timeout scan *///任務(wù)掃描 
  34.  
  35. #if (LOSCFG_BASE_CORE_SWTMR == YES) 
  36.     OsSwtmrScan();//定時(shí)器掃描,看是否有超時(shí)的定時(shí)器 
  37. #endif 
  38.  
  39. #ifdef __cplusplus 
  40. #if __cplusplus 
  41.   

解讀

● g_tickCount記錄每個(gè)CPU核tick的數(shù)組,每次硬中斷都觸發(fā) OsTickHandler,每個(gè)CPU核單獨(dú)計(jì)數(shù).

● OsTickHandler是內(nèi)核調(diào)度的動(dòng)力,其中會(huì)檢查任務(wù)時(shí)間片是否用完,定時(shí)器是否超時(shí).主動(dòng)delay的任務(wù)是否需要被喚醒,其本質(zhì)是個(gè)硬中斷,在HalClockInit硬時(shí)鐘初始化時(shí)創(chuàng)建的,具體在硬中斷篇中會(huì)詳細(xì)講解.

● TICK_LOCK是tick操作的自旋鎖,宏原型LOS_SpinLockSave在自旋鎖篇中已詳細(xì)介紹.

功能函數(shù)

  1. #define OS_SYS_MS_PER_SECOND   1000         //一秒多少毫秒 
  2. //獲取自系統(tǒng)啟動(dòng)以來的Tick數(shù) 
  3. LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID) 
  4.     UINT32 intSave; 
  5.     UINT64 tick; 
  6.  
  7.     /* 
  8.      * use core0's tick as system's timeline, 
  9.      * the tick needs to be atomic. 
  10.      */ 
  11.     TICK_LOCK(intSave); 
  12.     tick = g_tickCount[0];//使用CPU core0作為系統(tǒng)的 tick數(shù) 
  13.     TICK_UNLOCK(intSave); 
  14.  
  15.     return tick; 
  16. //每個(gè)Tick多少Cycle數(shù) 
  17. LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CyclePerTickGet(VOID) 
  18.     return g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND; 
  19. //毫秒轉(zhuǎn)換成Tick 
  20. LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec) 
  21.     if (millisec == OS_MAX_VALUE) { 
  22.         return OS_MAX_VALUE; 
  23.     } 
  24.  
  25.     return ((UINT64)millisec * LOSCFG_BASE_CORE_TICK_PER_SECOND) / OS_SYS_MS_PER_SECOND; 
  26. //Tick轉(zhuǎn)化為毫秒 
  27. LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 tick) 
  28.     return ((UINT64)tick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND; 

說明

● 在CPU篇中講過,0號(hào)CPU核默認(rèn)為主核,默認(rèn)獲取自系統(tǒng)啟動(dòng)以來的Tick數(shù)使用的是g_tickCount[0]

● 因每個(gè)CPU核的tick是獨(dú)立計(jì)數(shù)的,所以g_tickCount中各值是不一樣的.

● 系統(tǒng)的Tick數(shù)在關(guān)中斷的情況下不進(jìn)行計(jì)數(shù),因?yàn)镺sTickHandler本質(zhì)是由硬中斷觸發(fā)的,屏蔽硬中斷的情況下就不會(huì)觸發(fā)OsTickHandler,自然也就不會(huì)有g(shù)_tickCount[ArchCurrCpuid()]++的計(jì)數(shù),所以系統(tǒng)Tick數(shù)不能作為準(zhǔn)確時(shí)間使用.

● 追問下,什么情況下硬中斷會(huì)被屏蔽?

編程示例

前提條件:

● 使用每秒的Tick數(shù)LOSCFG_BASE_CORE_TICK_PER_SECOND的默認(rèn)值100。

● 配好OS_SYS_CLOCK系統(tǒng)主時(shí)鐘頻率。

時(shí)間轉(zhuǎn)換

  1. VOID Example_TransformTime(VOID) 
  2.     UINT32 ms; 
  3.     UINT32 tick; 
  4.  
  5.     tick = LOS_MS2Tick(10000);    // 10000ms轉(zhuǎn)換為tick 
  6.     dprintf("tick = %d \n",tick); 
  7.     ms = LOS_Tick2MS(100);        // 100tick轉(zhuǎn)換為ms 
  8.     dprintf("ms = %d \n",ms); 

時(shí)間轉(zhuǎn)換結(jié)果

  1. tick = 1000 
  2. ms = 1000 

時(shí)間統(tǒng)計(jì)和時(shí)間延遲

  1. LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick); 
  2. VOID Example_GetTime(VOID) 
  3.     UINT32 cyclePerTick; 
  4.     UINT64 tickCount; 
  5.  
  6.     cyclePerTick  = LOS_CyclePerTickGet(); 
  7.     if(0 != cyclePerTick) { 
  8.         dprintf("LOS_CyclePerTickGet = %d \n", cyclePerTick); 
  9.     } 
  10.  
  11.     tickCount = LOS_TickCountGet(); 
  12.     if(0 != tickCount) { 
  13.         dprintf("LOS_TickCountGet = %d \n", (UINT32)tickCount); 
  14.     } 
  15.  
  16.     LOS_TaskDelay(200);//延遲200個(gè)tick 
  17.     tickCount = LOS_TickCountGet(); 
  18.     if(0 != tickCount) { 
  19.         dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)tickCount); 
  20.     } 

時(shí)間統(tǒng)計(jì)和時(shí)間延遲結(jié)果

  1. LOS_CyclePerTickGet = 495000 //取決于CPU的頻率 
  2. LOS_TickCountGet = 1 //實(shí)際情況不一定是1的 
  3. LOS_TickCountGet after delay = 201 //實(shí)際情況不一定是201,但二者的差距會(huì)是200 

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2021-05-08 15:14:50

鴻蒙HarmonyOS應(yīng)用

2021-04-08 09:32:17

鴻蒙HarmonyOS應(yīng)用

2020-02-24 11:11:10

IT企業(yè)技術(shù)

2023-02-23 09:02:40

CIO領(lǐng)域管理

2013-10-11 13:31:10

2020-07-07 11:01:04

Linux工具命令

2013-10-11 14:18:54

2021-04-01 17:36:30

鴻蒙HarmonyOS應(yīng)用開發(fā)

2021-03-15 15:18:16

鴻蒙HarmonyOS應(yīng)用

2013-03-14 17:17:34

2024-12-27 09:46:10

2009-06-19 20:32:00

Linux

2021-03-18 13:00:51

JupyterPython編程語言

2012-07-31 09:55:50

時(shí)間管理管理

2023-01-17 16:05:50

程序員時(shí)間管理日程表

2021-03-11 11:14:39

鴻蒙HarmonyOS應(yīng)用

2024-11-15 12:24:53

2011-01-14 16:23:46

Linux內(nèi)核

2010-04-30 16:02:45

Unix操作系統(tǒng)

2009-12-25 17:05:50

Linux操作系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)