真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

基于linux0.11操作系統(tǒng)定時(shí)器的原理分析

今天就跟大家聊聊有關(guān)基于linux0.11操作系統(tǒng)定時(shí)器的原理分析,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、成都做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的廣南網(wǎng)站設(shè)計(jì)、移動媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

操作系統(tǒng)的定時(shí)器原理是,操作系統(tǒng)維護(hù)了一個定時(shí)器節(jié)點(diǎn)的鏈表,新增一個定時(shí)器節(jié)點(diǎn)時(shí),設(shè)置一個jiffies值,這是觸發(fā)定時(shí)中斷的頻率。linux0.11版本里是1秒觸發(fā)100次,即10毫秒一次。加入新增一個定時(shí)器的jiffies值是2,那經(jīng)過兩次定時(shí)中斷后就會被執(zhí)行。jiffies值在每次定時(shí)中斷時(shí)會加一。

_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        ...

下面是定時(shí)器的結(jié)構(gòu)圖

基于linux0.11操作系統(tǒng)定時(shí)器的原理分析

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

看完上述內(nèi)容,你們對基于linux0.11操作系統(tǒng)定時(shí)器的原理分析有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。


名稱欄目:基于linux0.11操作系統(tǒng)定時(shí)器的原理分析
本文地址:http://weahome.cn/article/pepghs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部