操作系统课程设计之Pintos
資源下載地址:https://download.csdn.net/download/sheziqiong/86784890
 資源下載地址:https://download.csdn.net/download/sheziqiong/86784890
Pintos 的安裝和配置
sudo apt-get install qemu
git clone git://pintos-os.org/pintos-anon
編輯/utils/pintos(257 行):替換 kernel.bin 為完整路徑的 kernel.bin
編輯/utils/pintos(621 行):替換 qemu 為 qemu-system-x86_64
編輯/utils/Pintos.pm(362 行):替換 loader.bin 為完整路徑的 loader.bin
Threads
Mission1
該部分內容主要是需要我們修改 timer_sleep 函數
 首先查看原本 timer_sleep 代碼
通過查看相關教程及分析,可知 start 獲取了起始時間, 然后斷言必須可以被中斷, 不然會一直死循環下去。
while (timer_elapsed (start) < ticks)thread_yield();追蹤 thread_yield()函數及 schedule()函數,schedule 負責切換下一個線程進行 run,thread_yield 負責把當前線程放到就緒隊列里,然后重新 schedule(當 ready 隊列為空時線程會繼續在 CPU 執行)。 而 timer_sleep 則是在 ticks 時間內,如果線程出于 running 狀態就不斷把線程放到就緒隊列不讓他執行。由此可以發現它存在的問題:
 線程不斷在 CPU 就緒隊列和 running 隊列之間來回,占用了 CPU 資源。因此我們決定添加喚醒機制。
函數實現
修改 thread 結構體:
struct thread{/* Owned by thread.c. */tid_t tid; /* Thread identifier. */enum thread_status status; /* Thread state. */char name[16]; /* Name (for debugging purposes). */uint8_t *stack; /* Saved stack pointer. */int priority; /* Priority. */struct list_elem allelem; /* List element for all threads list. *//* Shared between thread.c and synch.c. */struct list_elem elem; /* List element. */#ifdef USERPROG/* Owned by userprog/process.c. */uint32_t *pagedir; /* Page directory. */ #endif/* Owned by thread.c. */unsigned magic; /* Detects stack overflow. */int64_t ticks_blocked; /* Time for blocked. */};添加了一個變量 ticks_blocked 用于記錄剩余阻塞時間。在 timer_sleep 函數中,將該線程阻塞并設置阻塞時間。這一過程需要解除中斷。
 修改 timer_sleep 函數
/* Timer interrupt handler. */
 static void
 timer_interrupt (struct intr_frame *args UNUSED)
 {
 ticks++;
 thread_tick ();
 thread_foreach(check_blocked_time,NULL);
 }
在頭文件也要添加關于 check_blocked_time 的聲明
void check_blocked_time(struct thread *t, void *aux);此時 Mission1 通過部分
pass tests/threads/alarm-single pass tests/threads/alarm-multiple pass tests/threads/alarm-simultaneous FAIL tests/threads/alarm-priority pass tests/threads/alarm-zero pass tests/threads/alarm-negative然后完成線程優先級的問題。通過發現 thread.c 中的 next_thread_to_run()函數,發現其中存在一個 ready_list。
static struct thread * next_thread_to_run (void) {if (list_empty (&ready_list))return idle_thread;elsereturn list_entry (list_pop_front (&ready_list), struct thread, elem); }查找 list.c 文件,發現了 list_max 函數,可用于根據比較函數查找 ready_list 中優先級最高的線程。構造比較函數,利用 list_max 和 list_entry 將優先級最高的線程移除并返回。
bool thread_compare_priority (const struct list_elem *a,const struct list_elem *b,void *aux UNUSED){return list_entry(a,struct thread,elem)->priority < list_entry(b,struct thread,elem)->priority; } static struct thread * next_thread_to_run (void) {if (list_empty (&ready_list))return idle_thread;else{struct list_elem *max_priority = list_max (&ready_list,thread_compare_priority,NULL);list_remove (max_priority);return list_entry (max_priority,struct thread,elem);} }此時,Mission1 部分全部通過。
pass tests/threads/alarm-single pass tests/threads/alarm-multiple pass tests/threads/alarm-simultaneous pass tests/threads/alarm-priority pass tests/threads/alarm-zero pass tests/threads/alarm-negativeMission2
從 priority-fifo 測試看起,改測試創建了一個一個優先級 PRI_DEFAULT+2 的主線程,并用這個線程創建了 16 個優先級 PRI_DEFAULT+1 的子線程,然后把主線程的優先級設置為優先級 PRI_DEFAULT。
 測試需要把 16 個線程跑完后結束主線程,但操作系統中線程是并行執行的,有可能最開始的一個線程在設置完優先級之后立刻結束了,而此時其他線程并未結束。因此在線程設置完優先級之后應該立刻重新調度,需要在 thread_set_priority()函數里添加 thread_yield()函數。
結語
斯坦福操作系統課程設計的難度很大,無論是從環境的配置和搭建,文檔的查詢和翻譯,相關資料的搜集和理解,都需要花費很多的功夫。通過 pintos 的自學,我能夠更清晰地理解操作系統中的線程到底是怎么一回事,需要考慮哪些因素:優先級的循環更新,嵌套調度,時間片的考量,關于線程鎖的概念,以及更復雜的隊列調度算法。受限于時間原因,這里只完成到 thread 部分。
資源下載地址:https://download.csdn.net/download/sheziqiong/86784890
 資源下載地址:https://download.csdn.net/download/sheziqiong/86784890
總結
以上是生活随笔為你收集整理的操作系统课程设计之Pintos的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 前端学习(1904)vue之电商管理系统
- 下一篇: QT 播放器之列表
