Announcements

• Posted stack.cc example on website CS 3204 • Project 0 is due Feb 1, 11:59pm Operating Systems • This project is done individually • Curator instructions will be posted on Lecture 5 website Godmar Back

CS 3204 Spring 20061/27/2006 2

Overview Context Switching

TimerTimer interrupt: interrupt: P1 P1 is is preempted, preempted, • Definitions contextcontext switch switch to to P2 P2 I/O device interrupt: • How does OS execute processes? Process 1 I/O device interrupt: P2’sP2’s I/O I/O complete complete – How do kernel & processes interact switchswitch back back to to P2 P2 Process 2 – How does kernel switch between processes user mode • Implementing Processes kernel mode •Next: Kernel System call: (trap): – Scheduling of threads System call: (trap): TimerTimer interrupt: interrupt: P2 P2 still still has has P2 starts I/O operation, blocks P2 starts I/O operation, blocks timetime left, left, no no context context switch switch – Synchronization of threads contextcontext switch switch to to process process 1 1

CS 3204 Spring 20061/27/2006 3 CS 3204 Spring 20061/27/2006 4

Switching Procedures Calling Conventions

• Inside kernel, context switch is implemented in • Caller saves caller-saved registers as needed schedule() function called from code • Caller pushes arguments, right-to-left on stack via push – Called when kernel decides to context switch • Callee executes: assembly instruction • Must understand how to switch procedures • Caller executes CALL – Saves callee-saved registers instruction: save address of if they’ll be destroyed (call/return) next instruction & jump to – Puts return value (if any) in • Dictated by procedure calling conventions callee eax • Callee returns via RET – Architecture-specific • Caller resumes: pop instruction: pop return address – Part of ABI (application binary interface), arguments off the stack from stack & jump to it implemented by • Caller restores caller-saved registers, if any – Pintos uses SVR4 ABI CS 3204 Spring 20061/27/2006 5 CS 3204 Spring 20061/27/2006 6

1 callee: Pintos Context Switch (1) Example pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax static void int globalvar; addl 8(%ebp), %eax schedule (void) leave { Stack int ret struct thread *cur = running_thread (); … callee(int a, int b) struct thread *next = next_thread_to_run (); next { caller: struct thread *prev = NULL; cur return a + b; pushl %ebp if (cur != next) esp &retlabel } movl %esp, %ebp pushl globalvar prev = switch_threads (cur, next); int pushl $5 retlabel: /* not in actual code */ caller(void) call callee schedule_tail (prev); { popl %edx } return callee(5, globalvar); popl %ecx } leave uint32_t thread_stack_ofs = offsetof (struct thread, stack); ret • threads/thread.c, threads/switch.S

CS 3204 Spring 20061/27/2006 7 CS 3204 Spring 20061/27/2006 8

Pintos Context Switch (2) Famous Quote For The Day switch_threads: # Save caller's register state. # Note that the SVR4 ABI allows us to destroy %eax, %ecx, %edx, # but requires us to preserve %ebx, %ebp, %esi, %edi. If the new process paused because it was swapped out, pushl %ebx; pushl %ebp; pushl %esi; pushl %edi Stack set the stack level to the last call to savu(u_ssav). This … # Get offsetof (struct thread, stack). means that the return which is executed immediately next mov thread_stack_ofs, %edx after the call to aretu actually returns from the last cur esp # Save current stack pointer to old thread's stack. &retlabel routine which did the savu. movl SWITCH_CUR(%esp), %eax ebx movl %esp, (%eax,%edx,1) ebp You are not expected to understand this. esi # Restore stack pointer from new thread's stack. esp edi movl SWITCH_NEXT(%esp), %ecx movl (%ecx,%edx,1), %esp • Source: Dennis Ritchie, Unix V6 slp.c ##definedefineSWITCH_CURSWITCH_CUR 20 20 #define SWITCH_NEXT 24 # Restore caller's register state. #define SWITCH_NEXT 24 (context-switching code) as per The Unix popl %edi; popl %esi; popl %ebp; popl %ebx ret Heritage Society (tuhs.org)

CS 3204 Spring 20061/27/2006 9 CS 3204 Spring 20061/27/2006 10

Pintos Context Switch (3) Pintos Kernel Stack 4 kB +------+ • One page of | kernel stack | • All state is stored on outgoing thread’s stack, and | | | restored from incoming thread’s stack memory captures | | | | V | – Each thread has a 4KB page for its stack a process’s kernel | grows downward | – Called “kernel stack” because it’s only used when thread | ... | executes in kernel mode | ... | stack + PCB | switch_threads’s | – Mode switch automatically switches to kernel stack | stack frame <---+ | • x86 does this in hardware, curiously. • Don’t allocate | | | | | | • switch_threads assumes that the thread that’s switched large objects on | | | in was suspended in switch_threads as well. | | | the stack: +------+------+ – Must fake that environment when switching to a thread for the | magic | | first time. void kernel_function(void) | : | | • Aside: none of the thread switching code uses privileged { | stack---+ | char buf[4096]; // DON’T | name | instructions: // KERNEL STACK OVERFLOW | status | – that’s what makes user-level threads (ULT) possible // guaranteed 0 kB +------+ }

CS 3204 Spring 20061/27/2006 11 CS 3204 Spring 20061/27/2006 12

2 Context Switching: Summary

• Context switch means to save the current and restore next process’s execution context • Context Switch != Mode Switch Intermezzo – Although mode switch often precedes context switch • Asynchronous context switch happens in interrupt handler Just enough on concurrency to – Usually last thing before leaving handler get through Project 0 • Have ignored so far when to context switch & A lot more later. why → next

CS 3204 Spring 20061/27/2006 13

Concurrency pthread_mutex example

/* Define a mutex and initialize it. */ • Access to shared resources must be mediated static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; – Specifically shared (non-stack) variables static int counter = 0; /* A global variable to protect. */ • Will hear a lot more about this /* Function executed by each thread. */ • For now, simplest way to protection is mutual static void * increment(void *_) exclusion via locks (aka mutexes) { • For Project 0, concurrency is produced by using int i; for (i = 0; i < 1000000; i++) { PThreads (POSIX Threads), so must use pthread_mutex_lock(&lock); counter++; PThread’s mutexes. pthread_mutex_unlock(&lock); – Just an API, idea is the same everywhere } }

CS 3204 Spring 20061/27/2006 15 CS 3204 Spring 20061/27/2006 16

3