nachos instructional os and project 1 cs 170, tao yang
TRANSCRIPT
![Page 1: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/1.jpg)
Nachos Instructional OS and Project 1
CS 170, Tao Yang
![Page 2: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/2.jpg)
04/19/23 2
Why Nachos OS? Learn by reading and modifying simple
operating system code Extremely important OS experience Deep understanding of OS features/system calls
Where/when they can fail, or have poor performance
A skeletal OS that supports kernel threads, user-level processes MIPS instruction execution as a virtual
machine ~9K lines of C++ code.
![Page 3: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/3.jpg)
System Layers
Base Operating System (Linux for our class)
Nachos kernel threads
Thread 1 Thread 2 Thread N
Nachos OS modules(Threads mgm, File System, Code execution/memory mapping,
System calls/Interrupt)
Simulated MIPS Machine(CPU, Memory, Disk, Console)
User processUser process
![Page 4: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/4.jpg)
Project 1B Tasks 1-3
Linux
Nachos threads
Thread 1 Thread 2 Thread N
Nachos OS modules
Simulated MIPS Machine
main()
ThreadTest()
![Page 5: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/5.jpg)
04/19/23 5
Steps to Install Nachos Obtain and install Nachos source code.
Copy the source code from ~cs170/nachos2015.tar
Compile the source code with Makefile Run Nachos demo
Under the threads subdirectory (run threads)
Under the userprog subdirectory (compile/execute binary code)
![Page 6: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/6.jpg)
04/19/23 6
Nachos code directory machine --- Basic machine specification (MIPS
simulator as a virtual machine). threads --- threads management (Project 1). userprog -- binary code execution and system calls
(Project 2). vm -- virtual memory (empty, Project 3A). filesys -- file system (Project 3B) test -- binary code to be executed in this virtual
machine network -- networking protocol (not used in this class) bin -- utilities/tools (binary format conversion)
![Page 7: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/7.jpg)
04/19/23 7
Source code reading and Project 1
Objectives of next 2 weeks Scan through ~1,000 lines of code under
threads directory Learn how context switch is accomplished
among threads. Learn how thread scheduling is done. Learn how locks/synchronization are
implemented and used. Use Linux pthreads.
Complete Project 1
![Page 8: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/8.jpg)
int shared=1;main (){ Thread *t1 = new Thread("forked thread1"); Thread *t2 = new Thread("forked thread2");
t1->Fork(SimpleThread, 1); t2->Fork(SimpleThread, 2);
SimpleThread(3);}
SimpleThread(int i){ printf(“Hello %d. Shared %d\n”, i, shared); currentThread->Yield();}
Sample Example of Nacho Threads
Start to fork and execute a function in each child thread.
Parent also executes the same function
Function executed by threads
Create 2 new threads.
![Page 9: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/9.jpg)
04/19/23 9
Nachos Threads
Each thread has the following TCB (thread control block) from thread.h
int *stackTop; // stack pointerint machineState[18]; // copy of registersint *stack // bottom of stackThreadStatus status; //ready, running, or blockedchar *name;
Thread operations: Thread(char *debugName). Create a thread. Fork(VoidFunctionPtr func, int arg). Let a thread execute a
function. Yield(). Suspend the calling thread and select a new one for
execution. Sleep(). Suspend the current thread, change its state to
BLOCKED, and remove it from the ready list Finish()
![Page 10: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/10.jpg)
Nachos Thread States and Transitions
running(kernel)
readyblocked
Scheduler::Run
Scheduler::ReadyToRun
Thread::Sleep
Thread::Yield
![Page 11: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/11.jpg)
04/19/23 11
Semaphore object for thread synchronization
Disable and re-enable interrupts to achieve mutual exclusion (e.g., by calling Interrupt::SetLevel()).
Operations for a Semaphore object: Semaphore(char* debugName, int initialValue) P(): Decrement the semaphore's count,
blocking the caller if the count is zero. V() :Increment the semaphore's count,
releasing one thread if any are blocked waiting on the count.
![Page 12: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/12.jpg)
Semaphore Implementation with no busy waiting
Each semaphore has a waiting queue.
Two internal operations: Sleep– place the thread invoking the
operation on the waiting queue. Nachos: Thread:Sleep()
wakeup – remove one thread in the waiting queue and place it in the ready queue.
![Page 13: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/13.jpg)
Semaphore Implementation with no Busy waiting (Cont.)
P(semaphore *S) Disable-interrupt
S->value--; if (S->value < 0) { Add this thread to waiting-queue;
sleep(); } Enable-interrupt
V(semaphore *S) Disable-interrupt
S->value++; if (S->value <= 0) {
Remove x from waiting-queue;
wakeup(x); } Enable-interrupt
![Page 14: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/14.jpg)
04/19/23 14
Reading source code
Have a picture of overall components and their roles.
Be able to compile and run a simple case. Trace the code execution through a simple case
Basic/high level mechanism involved in execution.
Walk through a simple thread test case in Nachos.
Week 2 link in http://www.cs.ucsb.edu/~cs170/refer.html
![Page 15: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/15.jpg)
Project 1A: Concurrent Hash Table
Many pthreads
![Page 16: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/16.jpg)
What each thread test calls?Many pthreads
void *tfunc(void *arg){long k= (long) arg; //thread IDinti, b=NUMKEYS/NumberofThread;for (i= b *k; i< b*k+b && i<NUMKEYS; i++)
{test1(&hash, NUMKEYS, i,2);
}}void test1(HashMap *htable, int n, int k, int w){
int i, errorflag=0;for (i=0; i<n; i++)
(*htable).get(i);for (i=k-w; i<k+w; i++) (*htable).put(i,i);if((*htable).get(k)==-1)
errorflag=1;(*htable).remove(k);for (i=0; i<n; i++)
(*htable).get(i);(*htable).put(k,k);for (i=0; i<n; i++)
(*htable).get(i);}
get()put()remove()
![Page 17: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/17.jpg)
Coarse-grain synchronization of concurrent hash table access
Many pthreads
![Page 18: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/18.jpg)
Fine-grain synchronization
Many pthreads
![Page 19: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/19.jpg)
04/19/23 19
Part B of Project 1 Objectives
Tasks 1-3 under threads subdirectory. Gain experience with simple thread
programming (execute multiple Nachos threads with synchronization).
Implement locks and condition variables (missing from the file synch.cc).
Use for concurrent access of a hash table
![Page 20: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/20.jpg)
Project 1B Tasks 1-3
Linux
Nachos threads
Thread 1 Thread 2 Thread N
Nachos OS modules
Simulated MIPS Machine
main()
ThreadTest()
Hashtable
![Page 21: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/21.jpg)
04/19/23 21
Tasks 1/2/3: Nachos Files involved
Key files to read and modify (modify 3 files in red) main.cc, threadtest.cc -- a simple test of our thread routines.
TA Varun provides a sample change template for threadtest.cc
thread.h thread.cc -- Nachos thread data structure and operations. scheduler.h scheduler.cc -- The thread ready list. synch.h synch.cc -- synchronization routines. system.h, system.cc -- Nachos startup initialization /shutdown switch.h, switch.s -- assembly code for thread switching.
Other related files: synchlist.h, synchlist.cc -- synchronized access to lists using locks/conditions
(useful examples for your programming). list.h list.cc -- generic list management. utility.h utility.cc -- some useful definitions and debugging routines. interrupt.h interrupt.cc -- manage interrupts. time.h timer.cc -- clock emulation. stats.h stats.cc -- collect interesting statistics.
![Page 22: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/22.jpg)
04/19/23 22
Tasks of Project 1 (Part B)
Task 1 Synchronize hash table (fine-grain) with
semaphore Task 2.
Implement Lock code in synch.cc similar as Nachos semaphore code
Follow the Nachos semaphore implementation Synchronize hash table (fine-grain)
Task 3 Implement conditional variables Synchronize hash table (fine-grain)
![Page 23: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/23.jpg)
04/19/23 23
Key steps when Nachos executes
After you type ``nachos'' under threads subdirectory:
It is executing as a single Linux process. The main() calls
Initialize() to start up interrupt handling, create a scheduler for managing the ready queue.
ThreadTest() currentThread->Finish() to let other threads
continue to run.
![Page 24: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/24.jpg)
04/19/23 24
Current Nachos Threadtest.cc
void SimpleThread(int which) { int num, val;
for(num = 0; num < 5; num++) {printf("*** thread %d looped %d times\n", which,
num); c currentThread->Yield(); }} *** thread 0 looped 0 times
*** thread 1 looped 0 times*** thread 0 looped 1 times*** thread 1 looped 1 times*** thread 0 looped 2 times*** thread 1 looped 2 times*** thread 0 looped 3 times*** thread 1 looped 3 times*** thread 0 looped 4 times*** thread 1 looped 4 timesNo threads ready or runnable, and no pending interrupts.Assuming the program completed.Machine halting
void ThreadTest1() { Thread *t = new Thread("forked thread"); t->Fork(SimpleThread, 1); SimpleThread(0); }
![Page 25: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/25.jpg)
04/19/23 25
Key calling graph when Nachos executes under thread directory
All files are in threads directory.
main() inmain.cc
Initialize()in system.cc
ThreadTest ()in threadtest.cc
Thread:Yield ()in thread.cc
Thread:Fork ()in thread.cc
StackAllocate()in thread.cc
FindNextToRun ()in scheduler.cc
ReadyToRun ()in scheduler.cc
Run ()in scheduler.cc
SWITCH ()in switch.s
ThreadRoot ()in switch.s
func() such as SimpleThread()in ThreadTest.cc
currentThread->Finish ()in threadtest.cc
![Page 26: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/26.jpg)
04/19/23 26
Key Calling graph for Project 1 Task 1
All files are in thread directory.
main() inmain.cc
Initialize()in system.cc
ThreadTest ()in threadtest.cc
Thread:Yield ()in thread.cc
Thread:Fork ()in thread.cc
currentThread->Finish ()in threadtest.cc
Spawn multiple threads similar to ptest.cc in Part A(hashtable test)
Insert some Yield()
Semaphore P()/V()in synch.cc
![Page 27: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/27.jpg)
04/19/23 27
Nachos Scheduler object for thread scheduling
Decide which thread to run next Invoked when the current thread gives up CPU.
The current Nachos scheduling policy is round-robin: Select the front of ready queue list Append new threads to the end.
Key operations: ReadyToRun(Thread *thread).
Make thread ready to run and add to ready list.
Thread *FindNextToRun() Run(Thread *nextThread)
Nachos scheduler
![Page 28: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/28.jpg)
04/19/23 28
Thread Switching
Suspend current thread, save its state, and restore the state of new thread.
Switch(oldThread, newThread): Save all registers in oldThread's TCB.
to be used when the old thread is resumed.
Load new values into the registers from TCB of the new thread.
![Page 29: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/29.jpg)
04/19/23 29
Key operations of Nachos’ function SWITCH()
SWITCH ()in switch.s
Thread->Fork(func(), arg)
func(arg)
Call ThreadRoot ()in switch.s
Save current thread context
Load targetthread context
CallThreadFinish()
Call InterruptEnable()
Callfunc(arg)
![Page 30: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/30.jpg)
04/19/23 30
TCB of Nachos Threads
Each thread has the following TCB (thread control block) from thread.h
int *stackTop; // stack pointerint machineState[18]; // copy of registersint *stack // bottom of stackThreadStatus status; //ready, running, or blockedchar *name;
Thread operations: Thread(char *debugName). Create a thread. Fork(VoidFunctionPtr func, int arg). Let a thread execute a
function. Yield(). Suspend the calling thread and select a new one for
execution. Sleep(). Suspend the current thread, change its state to
BLOCKED, and remove it from the ready list Finish()
![Page 31: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/31.jpg)
04/19/23 31
Thread Switching
Switch(oldThread, newThread): Save all registers in oldThread's
TCB. to be used when the old thread is
resumed. Load new values into the
registers from TCB of the new thread.
int *stackTop;int machineState[18]int *stack ThreadStatus status;
int *stackTop;int machineState[18]int *stack ThreadStatus status;
![Page 32: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/32.jpg)
04/19/23 32
SWITCH(oldThread a0, nextThread a1)Save register values to current thread’s TCB
# a0 -- pointer to old thread’s TCB
sw sp, SP(a0) # save new stack pointer sw s0, S0(a0) sw s1, S1(a0) sw s2, S2(a0) sw s3, S3(a0) sw s4, S4(a0) sw s5, S5(a0) sw s6, S6(a0) sw s7, S7(a0) sw fp, FP(a0)sw ra, PC(a0) # save return address
sp
s0
s1
s2
…
stackTopmachineState[0]machineState[1]machineState[2]…
TCB
save
save
save
save
MIPS Registers
![Page 33: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/33.jpg)
04/19/23 33
SWITCH(oldThread a0, nextThread a1)
sw sp, SP(a0) # save new stack pointer sw s0, S0(a0) sw s1, S1(a0) sw s2, S2(a0) sw s3, S3(a0) sw s4, S4(a0) sw s5, S5(a0) sw s6, S6(a0) sw s7, S7(a0) sw fp, FP(a0)sw ra, PC(a0) # save return address
sp
s0
s1
s2
…
stackTopmachineState[0]machineState[1]machineState[2]…
TCB
save
save
save
save
MIPS Registers
switch.h#define SP 0#define S0 4#define S1 8#define S2 12#define S3 16#define S4 20#define S5 24#define S6 28#define S7 32#define FP 36#define PC 40
What is value of SP and S0?
![Page 34: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/34.jpg)
04/19/23 34
Load register values from new thread’s TCB
a1 -- pointer to new thread’sTCB
lw sp, SP(a1) # load the new stack pointer lw s0, S0(a1) lw s1, S1(a1) lw s2, S2(a1) …lw s7, S7(a1) lw fp, FP(a1) lw ra, PC(a1) # load the return address
j ra #Call ra which is ThreadRoot();
sp
s0
s1
s2
s3
stackTopmachineState[0]machineState[1]machineState[2]machineState[3]…
machineState[9]
ra
![Page 35: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/35.jpg)
04/19/23 35
Key operations of Nachos’ function SWITCH()
SWITCH ()in switch.s
Thread->Fork(func(), arg)
func(arg)
Call ThreadRoot ()in switch.s
Save current thread context
Load targetthread context
CallThreadFinish()
Call InterruptEnable()
Callfunc(arg)
ThreadRoot
![Page 36: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/36.jpg)
04/19/23 36
How TCB is initialized? # a0 -- pointer to old thread’s TCB a1 -- pointer to new thread’sTCB
lw sp, SP(a1) # load the new stack pointer lw s0, S0(a1) lw s1, S1(a1) lw s2, S2(a1) …lw s7, S7(a1) lw fp, FP(a1) lw ra, PC(a1) # load the return address
j ra #Call ra which is ThreadRoot();
sp
s0
s1
s2
s3
stackTopfunc() argThreadFinish()InterruptEnable()…
ThreadRoot() addr
ra
a1
![Page 37: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/37.jpg)
04/19/23 37
Which routine fills values of the new thread
TCB?
StackAllocate() in Thread::Fork()
machineState[PCState] = (int) ThreadRoot; // PCState=9machineState[StartupPCState] = (int) InterruptEnable;
//StartupPCState=3 =>s3machineState[InitialPCState] = (int) func; //InitialPCState=0 =>s0machineState[InitialArgState] = arg; //InitialArgState=1 =>s1machineState[WhenDonePCState] = (int) ThreadFinish;
//WhenDonePCState=2 =>s2
![Page 38: Nachos Instructional OS and Project 1 CS 170, Tao Yang](https://reader036.vdocuments.mx/reader036/viewer/2022081418/56649e0d5503460f94af6a2f/html5/thumbnails/38.jpg)
04/19/23 38
ThreadRoot() uses registers s0, s1,s2,s3 to execute targeted func()
jal StartupPC # call InterruptEnable() stored in register s3
move a0, InitialArg #move argument in s1 to a0
jal InitialPC # call main thread procedure func() stored in s0
jal WhenDonePC # when done, call ThreadFinish() in s2