《Linux內核分析》MOOC課程之從迷你Linux內核角度理解進程時間輪片調度(未完)



代碼分析函數

  1. mypcb.hspa


  2. mymain.c線程

    上面這段代碼主要完成了對0號進程的初始化,即pid置爲0,狀態state置爲0(即runnable狀態),進程入口及當前進程的線程的ip指向my_process,線程的sp指向當前進程的進程堆棧,因爲目前只有0號進程,因此next指針指向本身造成一個單PCB鏈表。指針

    上面這段代碼主要是擴充循環鏈表,使用memcpy()複製0號進程的狀態給建立的從1號到MAX_TASK_NUM-1號進程,並與0號進程一塊兒構成一個循環PCB鏈表。
    進程

    上面這段代碼功能是從循環PCB鏈表的task[0]啓動0號進程,是經過使用了gcc的內聯彙編來實現的。接下來咱們具體分析該過程:圖片

    初始堆棧狀態:ip

    movl %1, %%esp
    gcc

    push1 %1
    循環

    pushl %0
    gc

    ret

    popl %%ebp

    其實這段彙編代碼是不會被執行的,由於ret \n\t後eip指向了0號進程的起始地址。

    上面這段代碼實現每循環1千萬次打印一下當前進程的pid,而後判斷時鐘中斷是否將調度標誌(my_need_sched)置爲1,若是是1則將調度標誌置爲0,調用my_schedule(),避免消息機制,而後再打印一次當前進程的pid。

  3. myinterrupt.c

    my_time_handler()實現被調用每千次且調度標誌(my_need_sched)不爲1時,打印「>>>my_timer_handler here<<<」且將調度標誌置爲1,以便於my_schedule()在my_process()中可被調用。

    上面這段代碼爲進程調度函數容錯處理及next和prev指針的定義與初始化。

    假設如今0號進程正在運行,而1號進程爲unrunnable狀態即next->state爲-1,則進入建立進程分支:

    先將next->state置爲0,指向下一進程,打印進程切換關係,而後執行彙編內容,從堆棧角度分析該內聯彙編執行過程:

    堆棧初始狀態

    pushl %%ebp

    movl %%esp, %0

    movl %%2, %%esp

    movl %%2, %%ebp

    movl $1f, %1

    pushl %3

    ret

上面這段代碼功能爲,若是當前進程所在PCB循環鏈表的下一個結點的狀態state的值爲零即下一進程狀態爲runnable時,切換到下一進程,再打印下切換關係。具體的上下文切換過程用gcc內聯彙編寫的,下面來經過圖片分析:

寄存器初始狀態

……

未完,待續

相關文章
相關標籤/搜索