中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于linux0.11操作系統定時器的原理分析

發布時間:2021-12-03 15:15:10 來源:億速云 閱讀:215 作者:柒染 欄目:大數據

今天就跟大家聊聊有關基于linux0.11操作系統定時器的原理分析,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

操作系統的定時器原理是,操作系統維護了一個定時器節點的鏈表,新增一個定時器節點時,設置一個jiffies值,這是觸發定時中斷的頻率。linux0.11版本里是1秒觸發100次,即10毫秒一次。加入新增一個定時器的jiffies值是2,那經過兩次定時中斷后就會被執行。jiffies值在每次定時中斷時會加一。

_timer_interrupt:  push %ds    # save ds,es and put kernel data space  push %es    # into them. %fs is used by _system_call  push %fs  pushl %edx    # we save %eax,%ecx,%edx as gcc doesn't  pushl %ecx    # save those across function calls. %ebx  pushl %ebx    # is saved as we use that in ret_sys_call  pushl %eax  movl $0x10,%eax  mov %ax,%ds  mov %ax,%es  movl $0x17,%eax  mov %ax,%fs  incl _jiffies        ...

下面是定時器的結構圖

基于linux0.11操作系統定時器的原理分析

#define TIME_REQUESTS 64
// 定時器數組,其實是個鏈表static struct timer_list {  long jiffies;  void (*fn)();  struct timer_list * next;} timer_list[TIME_REQUESTS], * next_timer = NULL;
void add_timer(long jiffies, void (*fn)(void)){  struct timer_list * p;
 if (!fn)    return;  // 關中斷,防止多個進程”同時“操作  cli();  // 直接到期,直接執行回調  if (jiffies <= 0)    (fn)();  else {    // 遍歷定時器數組,找到一個空項    for (p = timer_list ; p < timer_list + TIME_REQUESTS ; p++)      if (!p->fn)        break;    // 沒有空項了    if (p >= timer_list + TIME_REQUESTS)      panic("No more time requests free");    // 給空項賦值    p->fn = fn;    p->jiffies = jiffies;    // 在數組中形成鏈表    p->next = next_timer;    // next_timer指向第一個節點,即最早到期的    next_timer = p;    /*      修改鏈表,保證超時時間是從小到大的順序      原理:        每個節點都是以前面一個節點的到時時間為坐標,節點里的jiffies即超時時間        是前一個節點到期后的多少個jiffies后該節點到期。    */    while (p->next && p->next->jiffies < p->jiffies) {      // 前面的節點比后面節點大,則前面節點減去后面節點的值,算出偏移值,下面準備置換位置      p->jiffies -= p->next->jiffies;      // 先保存一下      fn = p->fn;      // 置換兩個節點的回調      p->fn = p->next->fn;      p->next->fn = fn;      jiffies = p->jiffies;      // 置換兩個節點是超時時間      p->jiffies = p->next->jiffies;      p->next->jiffies = jiffies;      /*        到這,第一個節點是最快到期的,還需要更新后續節點的值,其實就是找到一個合適的位置        插入,因為內核是用數組實現的定時器隊列,所以是通過置換位置實現插入,        如果是鏈表,則直接找到合適的位置,插入即可,所謂合適的位置,        就是找到第一個比當前節點大的節點,插入到他前面。      */      p = p->next;    }    /*      內核這里實現有個bug,當當前節點是最小時,需要更新原鏈表中第一個節點的值,,      否則會導致原鏈表中第一個節點的過期時間延長,修復代碼如下:      if (p->next && p->next->jiffies > p->jiffies) {        p->next->jiffies = p->next->jiffies - p->jiffies;      }        即更新原鏈表中第一個節點相對于新的第一個節點的偏移,剩余的節點不需要更新,因為他相對于      他前面的節點的偏移不變,但是原鏈表中的第一個節點之前前面沒有節點,所以偏移就是他自己的值,      而現在在他前面插入了一個節點,則他的偏移是相對于前面一個節點的偏移    */  }  sti();}// 定時中斷處理函數void do_timer(long cpl){  extern int beepcount;  extern void sysbeepstop(void);
 if (beepcount)    if (!--beepcount)      sysbeepstop();  // 當前在用戶態,增加用戶態的執行時間,否則增加該進程的系統執行時間  if (cpl)    current->utime++;  else    current->stime++;  // next_timer為空說明還沒有定時節點  if (next_timer) {    // 第一個節點減去一個jiffies,因為其他節點都是相對第一個節點的偏移,所以其他節點的值不需要變    next_timer->jiffies--;    // 當前節點到期,如果有多個節點超時時間一樣,即相對第一個節點偏移是0,則會多次進入while循環    while (next_timer && next_timer->jiffies <= 0) {      void (*fn)(void);            fn = next_timer->fn;      next_timer->fn = NULL;      // 下一個節點      next_timer = next_timer->next;      // 執行定時回調函數      (fn)();    }  }  if (current_DOR & 0xf0)    do_floppy_timer();  // 當前進程的可用時間減一,不為0則接著執行,否則可能需要重新調度  if ((--current->counter)>0) return;  current->counter=0;  // 是系統進程則繼續執行  if (!cpl) return;  // 進程調度  schedule();}

看完上述內容,你們對基于linux0.11操作系統定時器的原理分析有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

麻城市| 荔浦县| 龙井市| 绥芬河市| 探索| 平邑县| 宁武县| 邵阳市| 昌江| 瓦房店市| 香港| 黄石市| 北川| 徐水县| 长治县| 平阳县| 崇义县| 乡城县| 通江县| 西乌| 同德县| 察雅县| 永仁县| 武定县| 汝城县| 平邑县| 呼和浩特市| 迁西县| 富源县| 安丘市| 咸丰县| 阿克陶县| 军事| 沁源县| 德庆县| 长治市| 隆林| 建昌县| 岳阳市| 吉木萨尔县| 萍乡市|