250 likes | 265 Views
CS415 Minithreads Project 2 Context Switch and Stack Initialization. Ken Hopkinson hopkik@cs.cornell.edu. What You Have to Do. Lay the foundation for Minithreads, a user-level threads package, on Windows NT
E N D
CS415Minithreads Project 2 Context Switch and Stack Initialization Ken Hopkinson hopkik@cs.cornell.edu
What You Have to Do • Lay the foundation for Minithreads, a user-level threads package, on Windows NT • In this assignment we will be creating code for context switching and stack initialization
What we’ll cover • What order to do things in • How context switching works • How yielding between threads works • Minithread implementation hints
Thread Review • A process is a task plus at least one thread • A task consists of a code section, data section, and a set of operating system resources • A thread is basic unit of CPU utilization consisting of a program counter, a register set, and a stack space • These definitions can be found in sections 4 and 5 of your book where they are explained in more detail
Threads Continued • Threads can be based either at the user- or kernel-level • Kernel-level threads are scheduled by the Kernel (advantage), but require protected operating system actions to switch contexts (disadvantage) • User-level threads are managed by the threads’ parent process. Context switches are very fast and do not involve the operating system (advantage). The operating system only sees processes, not threads, so scheduling can be unfair and system calls from one thread will block all threads associated with its parent process as well. (disadvantage)
Minithreads Project 2 Part A • Windows NT lacks support for user-level threads • We will create our own user-level thread package, called Minithreads, in this course • In Project 1, you dissected setjmp/longjmp to learn how to change a program’s program counter, register set, and stack position (the components of a thread) • In Project 2 we will use this knowledge to implement context switching. We will also create multiple stacks and learn how to switch between them.
Project 2, step-by-step • Implement stack initialization • Implement context switching • Use test code to be sure you have done your work correctly • Note: Your responsibilities are limited to the minithread.h and minithread.c files. Everything else is there so that you can test your code.
Threads and their stacks • NT gives you an initial stack • Subsequent stacks must be allocated on the process’s heap using malloc 0 code 2000 heap stack 50000
Stack Space Alignment • Stack space needs to be aligned on 32-bit word boundaries • malloc allocates space properly aligned at its starting address • The ending allocated address is not necessarily aligned properly • Be sure to set the top of the stack to an aligned location at or below the end of the dynamically allocated stack space • Note: CS, DS, and SS are all initialized to the same value in VC++ so you do not need to worry about them even though malloc works from DS while stacks are in SS’s domain.
Stack Routines • allocate_stack(stack_pointer_t *stackbase, stack_pointer_t *stacktop): Allocate a new stack space of size STACK_SIZE. • stackbase points to the low end of the stack address range. • stacktop is the highest aligned address in the stack address range. • minithread_free_stack(stack_pointer_t *stackbase): Free an allocated stack • minithread_initialize_stack has been implemented for you
An initialized stack stack_base (lowest memory address) Stack initialized to look as if minithread_switch had been called final_proc addr base_arg1 stack_top base_arg2 final_proc addr final_arg1 original stack_top (highest memory address) final_arg2
Stack Initialization Limitations • Our context switching operates similarly to a setjmp followed by a longjmp • When a return occurs, the final_proc address is popped off of the stack but there is no restoration to the next frame • To do so, we would need a third procedure (or a modified final_proc) to restore stack space appropriately • It is not important to do so in Project2 since the final procedure there uses no arguments
Threads • minithread_type: Includes a stack base, stack top, and process context (to be filled in by you) • minithread_t *allocate_minithread(): Allocate a new minithread and return it • minithread_initialize_thread(minithread_t *thread, proc_t *base_proc): Initialize a new thread using the current register set for the register values. Exceptions: eip = the base_proc address. esp, ebp need to be set according to the new thread’s initialized stack
Context switching • minithread_switch(old_thread, new_thread) • Swaps execution contexts with a thread from the run queue • registers • program counter • stack pointer
old thread TCB new thread TCB Context switching ? old_thread_sp_ptr new_thread_sp_ptr ESP
old thread TCB new thread TCB Save old context ? old_thread_sp_ptr new_thread_sp_ptr ESP
old thread TCB new thread TCB Change stack pointers old_thread_sp_ptr new_thread_sp_ptr ESP
old thread TCB new thread TCB Restore new context old_thread_sp_ptr new_thread_sp_ptr ESP
Project 2 Part B • We briefly discussed Purify in the last lecture • It is a great tool for memory debugging effectively adding many of the valuable memory safety and management routines that Java provides • In Part B of Project 2, you will get some hands-on experience using Purify
Building the Purify.exe File • Get the purify.zip archive from the course web page • Place the buggy.c and purify.mak files in the same directory • Open buggy.c up and look at what it does • Type nmake /f purify.mak in that directory to build the purify.exe executable
Purifying Buggy.C • The buggy.c file has a number of memory problems • To find them, open Purify from the Rational Development Studio 1.5 section of the Programs menu on any of the Windows NT Machines in the Undergraduate Lab • Choose Run from the Purify menu setting the working directory and program executable appropriately when prompted
Part B Continued • Purify will begin by instrumenting the purify.exe executable • Purify will continue by running purify.exe noting any memory errors and warnings that it might find • In Part B, you are asked to answer questions based on the Purify output
Summary • Implement context switching • Implement stack initialization code • Create code to allocate and initialize three stacks, start threads of execution, and swap between them • Explore the Purify environment to help make life easier in future projects in Project 2 Part B • In Project 3, you will be building on Project 2 to create a simple (non-preemptive) user-level threads package