Operating Systems CMPSC 473 Signals Introduction to mutual

  • Slides: 17
Download presentation
Operating Systems CMPSC 473 Signals, Introduction to mutual exclusion September 28, 2010 - Lecture

Operating Systems CMPSC 473 Signals, Introduction to mutual exclusion September 28, 2010 - Lecture 9 Instructor: Bhuvan Urgaonkar

Today • Inter-process communication – Signals • Start discussion on process synchronization – Mutual

Today • Inter-process communication – Signals • Start discussion on process synchronization – Mutual exclusion problem • Project 2: Multi-threaded programming using pthreads out – Deadline: Oct 19

Inter-process Communication • Two forms of communication – Message passing • E. g. ,

Inter-process Communication • Two forms of communication – Message passing • E. g. , signals, interrupts, traps, emails, HTTP requests, … • We will study signals – Shared memory • E. g. , pipes, more general shared buffers, distributed shared memory

System calls related to signals • kill(signal_num, pid) - to send a signal •

System calls related to signals • kill(signal_num, pid) - to send a signal • signal(signal_num, handler) - to handle it

Signal Handling (more) • When does a process handle a signal? – Whenever it

Signal Handling (more) • When does a process handle a signal? – Whenever it gets scheduled next after the generation of the signal • We said the OS marks some members of the PCB to indicate that a signal is due – And we said the process will execute the signal handler when it gets scheduled – But its PC had some other address! • The address of the instruction the process was executing when it was scheduled last – Complex task due to the need to juggle stacks carefully while switching between user and kernel mode

Signal Handling (more) • Remember that signal handlers are functions defined by processes and

Signal Handling (more) • Remember that signal handlers are functions defined by processes and included in the user mode code segment – Executed in user mode in the process’s context • The OS forces the handler’s starting address into the program counter – The user mode stack is modified by the OS so that the process execution starts at the signal handler

User mode Normal program flow Kernel mode. . . (e. g. , interrupt handling)

User mode Normal program flow Kernel mode. . . (e. g. , interrupt handling) do_signal( ) handle_signal( ) setup_frame( ) Signal handler Return code on the stack • system_call( ) sys_sigreturn( ) restore_sigcontext( ) setup_frame: sets up the user-mode stack – Forces Signal handler’s address into PC and some “return code” – After the handler is done, this return code gets executed • It makes a system call such as sigreturn (in Linux) that does the following: – 1. Copies the hardware context of the normal program to KM Stack – 2. Restores the User mode stack to its original state • When the system call terminates, the normal program execution can continue

Signal Handling with Threads • • Recall: Signals are used in UNIX systems to

Signal Handling with Threads • • Recall: Signals are used in UNIX systems to notify a process that a particular event has occurred Recall: A signal handler is used to process signals - Signal is generated by particular event - Signal is delivered to a process - Signal is handled • Options: – – Deliver the signal to the thread to which the signal applies Deliver the signal to every thread in the process Deliver the signal to certain threads in the process Assign a specific thread to receive all signals for the process

Signal Handling (Visual) Signal due indicators Signal is not due PCB of P Signal

Signal Handling (Visual) Signal due indicators Signal is not due PCB of P Signal is due Kernel Runs SIGSEGV P handler; dumps cor Parent of P P’s signal and exits ISR run; assume Sys call done; assume handler runs P scheduled again. Par scheduled Timer interrupt System call (trap) Sched choses P Timer interrupt Calls kill() to Accesses illegal send a signal to Pmemory location (trap) time These are the events that P sees (its view of what is going on

The mutual exclusion problem • We will study it in the context of the

The mutual exclusion problem • We will study it in the context of the shared memory model

Example: Producer and Consumer Producer while (true) { /* produce an item and put

Example: Producer and Consumer Producer while (true) { /* produce an item and put in next. Produced */ while (count == BUFFER_SIZE); // do nothing buffer [in] = next. Produced; in = (in + 1) % BUFFER_SIZE; count++; } Consumer while (true) { while (count == 0); // do nothing next. Consumed = buffer[out]; out = (out + 1) % BUFFER_SIZE; count--; /* consume the item in next. Consumed } • Shared variables: buffer and count • Local variables: in, out, next. Produced, next. Consumed

Race Condition • count++ could be implemented as register 1 = count register 1

Race Condition • count++ could be implemented as register 1 = count register 1 = register 1 + 1 count = register 1 • count-- could be implemented as register 2 = count register 2 = register 2 - 1 count = register 2 • Consider this execution interleaving with “count = 5” initially: S 0: producer executes register 1 = count {register 1 = 5} S 1: producer executes register 1 = register 1 + 1 {register 1 = 6} S 2: consumer executes register 2 = count {register 2 = 5} S 3: consumer executes register 2 = register 2 - 1 {register 2 = 4} S 4: producer executes count = register 1 {count = 6 } S 5: consumer executes count = register 2 {count = 4}

Example: Producer and Consumer Producer while (true) { /* produce an item and put

Example: Producer and Consumer Producer while (true) { /* produce an item and put in next. Produced */ while (count == BUFFER_SIZE); // do nothing buffer [in] = next. Produced; in = (in + 1) % BUFFER_SIZE; count++; } • • • Consumer while (true) { while (count == 0); // do nothing next. Consumed = buffer[out]; out = (out + 1) % BUFFER_SIZE; count--; /* consume the item in next. Consumed } We would like these operations Shared variables: buffer and count to be mutually exclusive Local variables: in, out, next. Produced, next. Consumed Important: Think how producer-consumer applies to P 2 What about buffer manipulation? – Hint: Customer = Producer and Worker = Consumer

 • Mutual Exclusion We want to use mutual exclusion to synchronize access to

• Mutual Exclusion We want to use mutual exclusion to synchronize access to shared data – Meaning: Only one thread can access a shared resource at a time • Code that uses mutual exclusion to synchronize its execution is called a critical section – Only one thread at a time can execute code in the critical section – All other threads are forced to wait on entry – When one thread leaves the critical section, another can enter do { entry section CRITICAL SECTION exit section REMAINDER SECTION } while (TRUE);

 • • Example to Show Mut. Excl. is Nontrivial How about constructing a

• • Example to Show Mut. Excl. is Nontrivial How about constructing a “lock” s. t. before getting into critical section, we acquire it and after leaving critical section, we release it? Is there any trouble if we use a boolean flag as a lock? Consider P 1 and P 2 while (lock == 1) ; // Do nothing, just wait Doesn’t work! //position 1 lock = 1; . . // Critical Section. . . lock = 0; If P 1 interrupted at position 1, race condition might occur P 1 was waiting until lock == 0. Before it announces its turn (i. e. , sets lock = 1), suppose P 2 gets scheduled and sees that lock is 0 Before P 2 leaves its critical section (i. e. , sets lock = 0), suppose it gets descheduled Since P 1 was at position 1, it will set lock = 1 and also get into its critical section Now, two processes are in the critical section at the same time!

Peterson’s Solution • Two process solution • Assume that the LOAD and STORE instructions

Peterson’s Solution • Two process solution • Assume that the LOAD and STORE instructions are atomic; that is, cannot be interrupted. • The two processes share two variables: – int turn; – Boolean flag[2] • The variable turn indicates whose turn it is to enter the critical section. • The flag array is used to indicate if a process is ready to enter the critical section. flag[i] = true implies that process Pi is ready

Algorithm for Process Pi while (true) { flag[i] = TRUE; turn = j; while

Algorithm for Process Pi while (true) { flag[i] = TRUE; turn = j; while ( flag[j] && turn == j); CRITICAL SECTION flag[i] = FALSE; REMAINDER SECTION }