A very simple kernel ITV Multiprogramming and Real-Time Programs Anders P. Ravn May 2009.

Slides:



Advertisements
Similar presentations
Calling sequence ESP.
Advertisements

Christo Wilson Project 2: User Programs in Pintos
A very simple kernel Anders P. Ravn April A kernel specification /* kernel.h Interface to a lightweight kernel that implements concurrent processes.
CS 4284 Systems Capstone Godmar Back Processes and Threads.
1 Operating Systems, 122 Practical Session 5, Synchronization 1.
Tips for R3: Process Initialization When we create processes to represent our 5 test procedures we must correctly initialize its context by placing values.
Software Engineering Lecture 5 Multiprogramming and Scheduling ASPI8-4 Anders P. Ravn March 2004.
CSE 451: Operating Systems
1 Storage Registers vs. memory Access to registers is much faster than access to memory Goal: store as much data as possible in registers Limitations/considerations:
Machine-Level Programming III: Procedures Apr. 17, 2006 Topics IA32 stack discipline Register saving conventions Creating pointers to local variables CS213.
Project 2 Roadmap. Background – Context Switching One processor and multiple threads running concurrently – How?!! Give each thread a small time quantum.
1 Function Calls Professor Jennifer Rexford COS 217 Reading: Chapter 4 of “Programming From the Ground Up” (available online from the course Web site)
– 1 – , F’02 ICS05 Instructor: Peter A. Dinda TA: Bin Lin Recitation 4.
Low-level Programming TSW November 2009 Anders P. Ravn Aalborg University.
Ceng Operating Systems Chapter 2.1 : Processes Process concept Process scheduling Interprocess communication Deadlocks Threads.
CS-502 Fall 2006Processes in Unix, Linux, & Windows 1 Processes in Unix, Linux, and Windows CS502 Operating Systems.
Stack Activation Records Topics IA32 stack discipline Register saving conventions Creating pointers to local variables February 6, 2003 CSCE 212H Computer.
Concurrency - 1 Tasking Concurrent Programming Declaration, creation, activation, termination Synchronization and communication Time and delays conditional.
Recursion and Implementation of Functions
OPERATING SYSTEMS DESIGN AND IMPLEMENTATION Third Edition ANDREW S. TANENBAUM ALBERT S. WOODHULL Yan hao (Wilson) Wu University of the Western.
ESP int f(int x) {.... } int g(int y) { …. f(2); …. } int main() { …. g(1); …. } EIP 100: 200: 250: 300: 350:
Fall 2008CS 334: Computer SecuritySlide #1 Smashing The Stack A detailed look at buffer overflows as described in Smashing the Stack for Fun and Profit.
Introduction to Processes CS Intoduction to Operating Systems.
1 Carnegie Mellon Stacks : Introduction to Computer Systems Recitation 5: September 24, 2012 Joon-Sup Han Section F.
Multiprogramming CSE451 Andrew Whitaker. Overview Multiprogramming: Running multiple programs “at the same time”  Requires multiplexing (sharing) the.
Fabián E. Bustamante, Spring 2007 Machine-Level Programming III - Procedures Today IA32 stack discipline Register saving conventions Creating pointers.
1 Chapter 2.1 : Processes Process concept Process concept Process scheduling Process scheduling Interprocess communication Interprocess communication Threads.
Recitation 2: Outline Assembly programming Using gdb L2 practice stuff Minglong Shao Office hours: Thursdays 5-6PM Wean Hall.
Module R3 Process Scheduling. Module R3 involves the creation of a simple “Round Robin” dispatcher. The successful completion of this module will require.
Linux Processes Travis Willey Jeff Mihalik. What is a process? A process is a program in execution A process includes: –program counter –stack –data section.
Chapter 4 Process Abstraction Chien-Chung Shen CIS, UD
Low Level Programming Lecturer: Duncan Smeed The Interface Between High-Level and Low-Level Languages.
12/22/ Thread Model for Realizing Concurrency B. Ramamurthy.
CS412/413 Introduction to Compilers and Translators Spring ’99 Lecture 11: Functions and stack frames.
Compiler Construction Code Generation Activation Records
1 Assembly Language: Function Calls Jennifer Rexford.
1 Critical Section Problem CIS 450 Winter 2003 Professor Jinhua Guo.
Calling Procedures C calling conventions. Outline Procedures Procedure call mechanism Passing parameters Local variable storage C-Style procedures Recursion.
Discussions on hw3 Objective –To implement multitasking of 3 Tiny-UNIX processes on the SAPC –Each process tries to output data to the COM2 output port.
Virtualizing the CPU: Processes 1. How to provide the illusion of many CPUs? CPU virtualizing – The OS can promote the illusion that many virtual CPUs.
Recitation 3: Procedures and the Stack
Instructions for test_function
Reading Condition Codes (Cont.)
Storage Allocation Mechanisms
C function call conventions and the stack
Anton Burtsev February, 2017
ICS143A: Principles of Operating Systems Lecture 13: Context switching
Threading and Project 2 (Some slides taken from Sec. 3 Winter 2006)
Machine-Level Programming 4 Procedures
Processes in Unix, Linux, and Windows
System Structure and Process Model
Assembly Language Programming II: C Compiler Calling Sequences
Thread Implementations; MUTEX
Machine-Level Programming III: Procedures Sept 18, 2001
Discussions on HW2 Objectives
Understanding Program Address Space
Multithreaded Programming
Jonathan Walpole Computer Science Portland State University
Discussions on HW2 Objectives
Thread Implementations; MUTEX
CSE 451: Operating Systems Autumn 2003 Lecture 7 Synchronization
CSE 451: Operating Systems Autumn 2005 Lecture 7 Synchronization
CSE 451: Operating Systems Winter 2003 Lecture 7 Synchronization
Low-Level Thread Dispatching on the x86
Outline Chapter 2 (cont) Chapter 3: Processes Virtual machines
Chapter 3: Process Concept
“Way easier than when we were students”
Runtime Stack Activation record for hanoi;
Presentation transcript:

A very simple kernel ITV Multiprogramming and Real-Time Programs Anders P. Ravn May 2009

A kernel specification /* kernel.h Interface to a lightweight kernel that implements concurrent processes and a release primitive `pause'. Anders P. Ravn, DTU, Denmark 24 April 1998 */ typedef void (*Program)(void); /* A program text is a function without parameters*/ typedef void * Thread; /* identifier for a process */ extern Thread create(Program p,unsigned int stacksize); /* creates a process with a stack of the specified size and starts it executing the program. If there is insufficient memory, the result is NULL */ extern void pause(void); /* release the processor */

Multiprogramming #include ”kernel.h” void process() { /* do something */ pause(); /* do something */ } void main() { Thread p1, p2; p1 = create(&process,2000); /* p1 is started */ p2 = create(&process,1000); /* p2 is started */ /* the kernel will see to it that main is left when both p1 and p2 has exited */ }

A kernel implementation I typedef unsigned long Register; typedef struct x {struct x* next; Register esp;} Threaddescriptor; static Threaddescriptor* ready; /* queue of threads linked cyclically; ready points to last, the first is current */ #define current ready->next esp1esp2esp3 ready: current

A kernel implementation II void pause() { Register sp; __asm__(” pushal movl %esp,%sp"); /* sp -> |saved registers... | eip return from call */ DISABLE; /* scheduling */ current->esp = sp; ready = current; sp = current->esp; __asm__(" movl %sp,%esp popal" ); ENABLE; } esp1esp2esp3 ready: current stack1 stack2

A kernel implementation III pause:pushl %ebp movl %esp,%ebp pushal movl %esp,%ecx sp = esp movl ready,%eax movl (%eax),%edx current->esp movl %ecx,4(%edx) = sp movl %edx,ready ready = current movl (%edx),%edx movl 4(%edx),%ecx sp = current->esp movl %ecx,%esp popal leave ret

A kernel implementation IV pause: pushal movl ready,%eax movl (%eax),%edx current->esp movl %esp,4(%edx) = esp movl %edx,ready ready = current movl (%edx),%edx movl 4(%edx),%esp esp = current->esp popal ret

Critical regions void enter_crit(Gate g) /* enter critical region */ {}; void leave_crit(Gate g) /* leave critical region */ {}; void init_crit(Gate g) {}; extern void await(Gate g, Boolean *b) /* wait in a critical region for a condition b to become true */ {while (!*b) { // leave_crit pause(); // enter crit } };

Stop Process void stop(void) {/* called implicitly when a process exits its program Entry: esp -> |... | dummy must not be used ebp -> | old ebp | <- stack before entry to stop */ Register dummy; Proc thisp; Register cursp; thisp = current; if (thisp == initproc) {/* set up for final exit from multiprogramming esp -> | saved registers |... ebp = saved ebp saved ebp -> | final.oldebp ebp -> | final.eip |... */ __asm__(" pushal movl %esp,%0" : "=g" (cursp) ); ((SavedRegisters *)cursp)->ebp = (Register)ebp; initproc->esp = cursp; *(ebp+1) = final.eip; *ebp = final.oldebp; }; DISABLE /* remove current process */ #if TEST printf("Stop process %x\n",current); #endif current = thisp->next; if (head == thisp) {head = NULL; #if TEST printf("Stop kernel\n"); #endif /* exit for final program, prepared above */ cursp = initproc->esp;} else /* activate current */ cursp = current->esp; __asm__(" movl %0,%esp popal" : : "g" (cursp) ); ENABLE return;};

Stop Process II thisp = current; if (thisp == initproc) {/* set up for final exit from multiprogramming esp -> | saved registers |... ebp = saved ebp saved ebp -> | final.oldebp ebp -> | final.eip |... */ __asm__(" pushal movl %esp,%0" : "=g" (cursp) ); ((SavedRegisters *)cursp)->ebp = (Register)ebp; initproc->esp = cursp; *(ebp+1) = final.eip; *ebp = final.oldebp; };

Stop Process III DISABLE /* remove current process */ current = thisp->next; if (head == thisp) {head = NULL; /* exit for final program, prepared above */ cursp = initproc->esp;} else /* activate current */ cursp = current->esp; __asm__(" movl %0,%esp popal" : : "g" (cursp) ); ENABLE return;};

Create Process #define descriptor sizeof(Processdescriptor) #define overhead descriptor +sizeof(SavedRegisters) +2*sizeof(ReturnInfo) #define stopentry (Register) &stop Thread create(Program p,unsigned int stacksize) {Proc newp; Register *sp, bp; if ((head == NULL) && ((newp = (Proc)malloc(descriptor)) != NULL) ) { /* At this point, the process state is as follows: esp -> | ebp -> | old ebp old frame pointer | eip return from call of create... old ebp -> | old2 ebp | eip return from call of initial process |... stack of caller */

Create Process II /* save call of initial process in "final" initialize return to call "stop" on final exit */ __asm__(" movl %ebp,%0" : "=g" (ebp) ); (Register) ebp = *ebp; final.oldebp = *ebp; final.eip = *(ebp+1); *(ebp+1) = stopentry; /* save identity of initial process */ initproc = newp; DISABLE /* enter process descriptor in queue */ head = newp->next = newp; ENABLE };

Create Process III if ( ( newp = (Proc)malloc(stacksize+overhead)) != NULL) { /* create new process The state when activated shall be: newp -> | next ProcessDescriptor | sp... sp-> | saved registers fp -> | 0 sfp-> | p entry return address when activated | stopentry exit address | <- newp+stacksize+overhead immediately when p is entered, we have: ebp = 0 esp-> | stopentry exit address | <- newp+stacksize+overhead */ sp = (Register*)((unsigned int)newp+stacksize+overhead); *(--sp) = stopentry; *(--sp) = (Register)p; *(--sp) = 0; bp = (Register)sp; (Register)sp -= sizeof(SavedRegisters); ((SavedRegisters *)sp)->old_esp = ((SavedRegisters *)sp)->ebp = bp; newp->esp = (Register)sp; DISABLE newp->next = current; current = newp; head = newp; ENABLE #if TEST printf("Created new process\nhead %x %x %x %x esp %x ebp %x\n", head, head->next, (head->next)->next, ((head->next)->next)->next,sp,bp); #endif (Register)sp = bp; #if TEST printf("->... %x %x %x\n", *sp,*(sp+1),*(sp+2)); #endif }; return (Thread) newp; };

Create Process IV sp = (Register*)((unsigned int)newp+stacksize+overhead); *(--sp) = stopentry; *(--sp) = (Register)p; *(--sp) = 0; bp = (Register)sp; (Register)sp -= sizeof(SavedRegisters); ((SavedRegisters *)sp)->old_esp = ((SavedRegisters *)sp)->ebp = bp; newp->esp = (Register)sp; DISABLE newp->next = current; current = newp; head = newp; ENABLE (Register)sp = bp; }; return (Thread) newp; };

Create Process #define descriptor sizeof(Processdescriptor) #define overhead descriptor+sizeof(SavedRegisters)+2*sizeof(ReturnInfo) #define stopentry (Register) &stop Thread create(Program p,unsigned int stacksize) {Proc newp; Register *sp, bp; if ((head == NULL) && ((newp = (Proc)malloc(descriptor)) != NULL) ) { /* At this point, the process state is as follows: esp -> | ebp -> | old ebp old frame pointer | eip return from call of create... old ebp -> | old2 ebp | eip return from call of initial process |... stack of caller */ /* save call of initial process in "final" initialize return to call "stop" on final exit */ __asm__(" movl %ebp,%0" : "=g" (ebp) ); (Register) ebp = *ebp; final.oldebp = *ebp; final.eip = *(ebp+1); *(ebp+1) = stopentry; /* save identity of initial process */ initproc = newp; DISABLE /* enter process descriptor in queue */ head = newp->next = newp; ENABLE #if TEST printf("Initial process created\nhead %x current %x ebp %x final %x %x\n", head,current, ebp, final.oldebp, final.eip); #endif }; if ( ( newp = (Proc)malloc(stacksize+overhead)) != NULL) { /* create new process The state when activated shall be: newp -> | next ProcessDescriptor | sp... sp-> | saved registers fp -> | 0 sfp-> | p entry return address when activated | stopentry exit address | <- newp+stacksize+overhead immediately when p is entered, we have: ebp = 0 esp-> | stopentry exit address | <- newp+stacksize+overhead */ sp = (Register*)((unsigned int)newp +stacksize + overhead); *(--sp) = stopentry; *(--sp) = (Register)p; *(--sp) = 0; bp = (Register)sp; (Register)sp -= sizeof(SavedRegisters); ((SavedRegisters *)sp)->old_esp = ((SavedRegisters *)sp)->ebp = bp; newp->esp = (Register)sp; DISABLE newp->next = current; current = newp; head = newp; ENABLE #if TEST printf("Created new process\nhead %x %x %x %x esp %x ebp %x\n", head, head->next, (head->next)->next, ((head->next)->next)->next,sp,bp); #endif (Register)sp = bp; #if TEST printf("->... %x %x %x\n", *sp,*(sp+1),*(sp+2)); #endif }; return (Thread) newp; };