Linux任務切換代碼(switch_to)詳解)

來源:互聯網
上載者:User
Copyright 2009 (c) benzus以下代碼來自Linux-1.0核心 include/linux/sched.h 檔案。(注意到Linux 0.11版的核心基本上也同樣是這段代碼,所以本文也同樣適用於0.11核心)01   #define switch_to(n) { \
02   struct (long a,b;} __tmp; \
03   __asm__("cmpl %%ecx,current \n\t" \
04   "je 1f\n\t" \
05   "xchgl %%ecx, current\n\t" \
06   "movw %%dx, %1\n\t" \
07   "ljmp *%0\n\t" \
08   "cmpl %%ecx, %2\n\t" \
09   "jne 1f\n\t" \
10   "clts\n" \
11 "1:" \
12 ::"m" (*&__tmp.a), "m" (*&__tmp.b), \
13 "m" (last_task_used_math),"d" _TSS(n), "c" ((long) task[n])); \
14 } 注釋:這是一個嵌入式彙編宏,作用是從當前任務切換到任務n,在進程發送器中被調用。下面我來逐行注釋它。第2行定義了一個結構,包含2個long類型整數。第3行將task[n]與current比較,其中task[n]是要切換到的任務,current是當前任務;第4行說明,如果要切換到的任務是當前任務,則跳到標號1,即結束,什麼也不做,否則繼續執行下面的代碼。第5行交換兩個運算元的值,相當於C代碼的:current = task[n] ,ecx = 被切換出去的任務(原任務);第6行將新任務的TSS選擇符賦值給 __tmp.b;第7行是理解任務切換機制的關鍵。長跳轉至 *&tmp,造成任務的切換。AT&T文法的ljmp相當於Intel文法的 jmp far SECTION : OFFSET,在這裡就是將(IP)<-__tmp.a,(CS)<-__tmp.b,它的絕對位址之前加星號("*")。當段間指令jmp所含指標的選擇符指示一個可用任務狀態段的TSS描述符時,將造成任務切換。那麼CPU怎麼識別描述符是TSS描述符而不是其他描述符呢?這是因為所有描述符(一個描述符是64位)中都有4位用來指示該描述符的類型,如描述符類型值是9或11都表示該描述符是TSS描述符。好了,CPU得到TSS描述符後,就會將其載入到任務寄存器TR中,然後根據TSS描述符的資訊(主要是基址)找到任務的tss內容(包括所有的寄存器資訊,如eip),根據其內容就可以開始新任務的運行。我們暫且把這個恢複所有寄存器狀態的過程稱為恢複寄存器現場。第8~10行是判斷原任務上次是否使用過副處理器,若是,則清除寄存器CR0的TS標誌。第2個痛點是:在第7行執行後,完成任務切換(即切換到新的任務裡執行);當任務切換回來後才會繼續執行第8行!下面詳解其原因。既然任務切換時CPU會恢複寄存器現場,那麼它當然也會儲存寄存器現場了。這些寄存器現場都會被寫入原任務的tss結構裡,值得注意的是,EIP會指向引起任務切換指令(第7行)的下一條指令(第8行),所以,很明顯,當原任務有朝一日再次被調度運行時,它將從EIP所指的地方(第8行)開始運行。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.