MIT6.828 HW8 uthreads
在這次作業中,我們將實現1個簡單的使用者級執行緒包。
Switching threads
下載uthread.c和uthread_switch.S到xv6目錄,在Makefile檔案的_forktest規則之後新增如下規則:
_uthread: uthread.o uthread_switch.o
$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _uthread uthread.o uthread_switch.o $(ULIB)
$(OBJDUMP) -S _uthread > uthread.asm
在UPROGS目標下新增uthread依賴項。
當你完成uthread_switch.S時,你將獲得如下的輸出:
~/classes/6828/xv6$ make CPUS=1 qemu-nox
dd if=/dev/zero of=xv6.img count=10000
10000+0 records in
10000+0 records out
5120000 bytes transferred in 0.037167 secs (137756344 bytes/sec)
dd if=bootblock of=xv6.img conv=notrunc
1+0 records in
1+0 records out
512 bytes transferred in 0.000026 secs (19701685 bytes/sec)
dd if=kernel of= xv6.img seek=1 conv=notrunc
307+1 records in
307+1 records out
157319 bytes transferred in 0.003590 secs (43820143 bytes/sec)
qemu -nographic -hdb fs.img xv6.img -smp 1 -m 512
Could not open option rom 'sgabios.bin': No such file or directory
xv6...
cpu0: starting
init: starting sh
$ uthread
my thread running
my thread 0x2A30
my thread running
my thread 0x4A40
my thread 0x2A30
my thread 0x4A40
my thread 0x2A30
my thread 0x4A40
....
uthread建立2個執行緒,然後互相交替執行。每個執行緒列印”my thread …”,然後退讓給其他執行緒機會去執行。
首先必須熟悉一下uthread.c檔案中的內容。uthread.c中有2個全域性變數current_thread和next_thread,是指向thread結構體的指標。而thread結構體的定義如下:
struct thread {
int sp; /* curent stack pointer */
char stack[STACK_SIZE]; /* the thread's stack */
int state; /* running, runnable, waiting */
};
每個thread都有1個stack和指向stack的指標sp,在記憶體中的佈局如下:
在main函式中,首先進行執行緒初始化,然後建立2個執行緒,並開始排程。其中main也是1個執行緒,但是隻在第1次排程時,被涉及,後面排程時,由於一直是running狀態,所以不會被排程。
int
main(int argc, char *argv[])
{
thread_init();
thread_create(mythread);
thread_create(mythread);
thread_schedule();
return 0;
}
thread_schedule函式實現從執行緒連結串列中尋找1個可執行的執行緒,然後進行切換執行。類似於程序排程,最後用thread_switch進行上下文儲存和替換工作。
static void
thread_schedule(void)
{
thread_p t;
/* Find another runnable thread. */
for (t = all_thread; t < all_thread + MAX_THREAD; t++) {
if (t->state == RUNNABLE && t != current_thread) {
next_thread = t;
break;
}
}
if (t >= all_thread + MAX_THREAD && current_thread->state == RUNNABLE) {
/* The current thread is the only runnable thread; run it. */
next_thread = current_thread;
}
if (next_thread == 0) {
printf(2, "thread_schedule: no runnable threads; deadlock\n");
exit();
}
if (current_thread != next_thread) { /* switch threads? */
next_thread->state = RUNNING;
thread_switch();
} else
next_thread = 0;
}
thread_switch函式就是我們要實現的內容,它的任務是儲存當前執行的執行緒狀態到current_thread指標指向的thread結構體,然後從next_thread指標指向的結構體中恢復將要執行的執行緒狀態,同時將current_thread指向next_thread指向的結構體,將next_thread的值清零。
thread_switch:
/* YOUR CODE HERE */
pushal
movl current_thread, %eax
movl %esp, (%eax)
movl next_thread, %ebx
movl %ebx, current_thread
movl (%ebx), %esp
popal
movl $0x0, next_thread
ret /* pop return address from stack */
首先將通用暫存器壓入堆疊,儲存sp到current_thread指標指向額結構體,然後從next_thread指標指向的結構體中恢復堆疊指標和通用暫存器,改變2個指標的值。
相關推薦
MIT6.828 HW8 uthreads
在這次作業中,我們將實現1個簡單的使用者級執行緒包。 Switching threads 下載uthread.c和uthread_switch.S到xv6目錄,在Makefile檔案的_forktest規則之後新增如下規則: _uthr
mit6.828資源獲取
list 修改 -m 簡單 code con www. OS upload 自己2017年9月到2月這段時間慢慢把5個lab磨完了,期間遇到了不少困難和疑惑,所以打算通過寫博客的形式來回憶,記錄和總結自己學習mit6.828的過程。 MIT6.828就不用我多介紹了, mi
MIT6.828 HW11: crash
在這次作業中,我們將探索xv6的log功能。主要就是建立1個crash,然後觀察recover的過程。 xv6的log重點是將檔案系統所有的磁碟更新操作原子化,比如在建立1個檔案時涉及到在目錄中新增新入口,並標記新檔案的inode為使用中。如果沒有lo
MIT6.828 HW6: Threads and Locking
這次作業我們將探索使用執行緒和鎖來並行程式設計Hash表。下載pc.c程式然後編譯執行。 其實pc.c程式主要工作是使用隨機數生成keys,然後利用線性hash將其插入5個雜湊槽中,最後再取出每個key。 當使用2個執行緒來執行時,將會把keys
MIT6.828 HW3: xv6 system calls
第1部分:System cakk tracing 主要任務是在進行系統呼叫時,打印出系統呼叫的名字和返回值。 當你實現後,啟動時輸出如下(執行sh.c): ... fork -> 2 exec -> 0 open -> 3 clo
MIT6.828 LAB4 Part C: Preemptive Multitasking and Inter-Process communication (IPC)
Lab 4的最後一部分就是實現搶佔式排程和程序間通訊。 Clock Interrupts and Preemption 先前的排程是程序資源放棄CPU,但是實際中沒有程序會這樣做的,而為了不讓某一程序耗盡CPU資源,需要搶佔式排程,也就需要硬
MIT6.828 HW9: barriers
在這次作業中我們將探索如何使用pthread庫提供的條件變數來實現1個barrier(屏障)。屏障就是程式中的某一個點必須所有執行緒都到達才能繼續執行。 下載barrier.c,編譯並執行。 $ gcc -g -O2 -pthread barri
MIT6.828 LAB6: Network Driver
抽了點空把LAB6重新整理一下,作為結束符~~。 Introduction 我們已經實現了1個檔案系統,當然OS還需要1個網路棧,在本次實驗中我們將實現1個網絡卡驅動,這個網絡卡基於Intel 82540EM晶片,也就是熟知的E1000網絡卡。
MIT6.828 HW10: big files
在這次作業中我們將實現增大xv6檔案大小的最大值。目前xv6檔案被限制擁有140sectors(扇區),這是由於1個xv6的inode含有12直接塊序號和1個間接塊序號(指向128個塊序號),故此總共12+128=140。而我們的任務就是改變實現支援2層間接
MIT6.828 虛擬地址轉化為實體地址——二級分頁
這個分頁,主要是在mit6.828的lab2的背景下來說的。 lab2主要講虛擬記憶體->實體記憶體的變換,通過一定的函式來實現軟體MMU的部分。 整個地址轉化的過程如下圖所示: 首先,明確一點,在程式裡面的所有地址,都是虛擬地址,程式裡面是不會出現實體地址的,就
6.828學習筆記 Exercise 1
rom ges 9.png 跳轉 bios 計算 長跳轉 物理 技術分享 1.The Rom BIOS 計算機啟動時物理地址為0x000ffff0,是在64KB的ROM BIOS的頂端。此時CS為0xf000 and
Mit6.824 Lab1-MapReduce
named 裏的 them 切片 我們 doc 感受 控制 高並發 前言 Mit6.824 是我在學習一些分布式系統方面的知識的時候偶然看到的,然後就開始嘗試跟課。不得不說,國外的課程難度是真的大,一周的時間居然要學一門 Go 語言,然後還要讀論文,進而做MapReduce
LeetCode題828 —— Unique Letter String
values ice pear enc 有趣 only value HERE font https://leetcode.com/problems/unique-letter-string/description/ A character is unique in stri
MIT-6.828 Lab1實驗報告
imp 彈出 遞歸調用 switch語句 kde 信息 編譯器 化工 x86匯編 Lab1:Booting a PC 概述 本文主要介紹lab1,從內容上分為三部分,part1簡單介紹了匯編語言,物理內存地址空間,BIOS。part2介紹了BIOS從磁盤0號扇區讀取boot
MIT6.031Software Construction學習筆記:(二)Specification
首先,什麼是 Specification? Specification,就是我們平時看到的API文件的說明,比如java BigInteger why Specification Specification 其實是作為使用者(呼叫這個API的人)和實現者(實現API的人)的一條分
《MIT 6.828 Homework 1: boot xv6》解題報告
本作業的網站連結:MIT 6.828 Homework 1: boot xv6 問題 Exercise: What is on the stack? While stopped at the above breakpoint, look at the registers and the stack
MIT 6.828課程引導部分的解讀
引導程式碼位於boot資料夾下,由一個16位與32位彙編混合的彙編檔案(boot.S)和一個C語言檔案(main.c)組成。 程式的入口在boot.S中,採用的是AT&T語法,下面先對這個檔案進行分析: #include <inc/mmu.h> 在inc資料夾下有一個mm
《MIT 6.828 Lab 1 Exercise 12》實驗報告
本實驗的網站連結:MIT 6.828 Lab 1 Exercise 12。 題目 Exercise 12. Modify your stack backtrace function to display, for each eip, the function name, source file na
MIT-6.828-JOS-lab5:File system, Spawn and Shell
依然 目前 相同 系統服務 ace 訪問 structure rst 根目錄 Lab 5: File system, Spawn and Shell tags: mit-6.828 os 概述 本lab將實現JOS的文件系統,只要包括如下四部分: 引入一個文件系統進程(
828. 獨特字串
828. 獨特字串 超時解法1:過了32個測試用例 class Solution { public: int uniqueLetterString(string S) { int ans = S.length(), len = 2, begin = 0; while (len&