Building Concurrency Primitives

Similar documents
CS238P: Operating Systems. Lecture 12: Synchronization. Anton Burtsev March, 2018

143A: Principles of Operating Systems. Lecture 11: Synchronization. Anton Burtsev November, 2018

Scheduling II. q q q q. Proportional-share scheduling Multilevel-feedback queue Multiprocessor scheduling Next Time: Memory management

CS5460/6460: Operating Systems. Lecture 11: Locking. Anton Burtsev February, 2014

LAB 2: PROCESS SYNCHRONIZATION IN XV6

This is an open book, open notes exam. But no online or in-class chatting.

Changes made in this version not seen in first lecture:

Problem Set 2. CS347: Operating Systems

CS5460/6460: Operating Systems. Lecture 9: First process. Anton Burtsev January, 2014

Chapter 5. Scheduling. Multiplexing. Code: Context switching

FINE-GRAINED SYNCHRONIZATION. Operating Systems Engineering. Sleep & Wakeup [chapter #5] 15-Jun-14. in the previous lecture.

Problem Set: xv6. Lecture Notes on Operating Systems. 1. Consider the following lines of code in a program running on xv6.

Scheduling. Today. Next Time. ! Introduction to scheduling! Classical algorithms. ! Process interaction & communication

Project 3 Improved Process Management

CS3210: Coordination. Tim Andersen

Operating Systems Synchronization and Signals

Quiz I Solutions MASSACHUSETTS INSTITUTE OF TECHNOLOGY Fall Department of Electrical Engineering and Computer Science

[537] Virtual Machines. Tyler Harter

CSE 451: Operating Systems Winter Lecture 7 Synchronization. Steve Gribble. Synchronization. Threads cooperate in multithreaded programs

CS3210: Processes and switching 1. Taesoo Kim

Concurrency Control. Unlocked. The lock is not held by any thread of control and may be acquired.

CS5460/6460: Operating Systems. Lecture 14: Scalability techniques. Anton Burtsev February, 2014

Processes (Intro) Yannis Smaragdakis, U. Athens

CSE 451: Operating Systems Winter Lecture 7 Synchronization. Hank Levy 412 Sieg Hall

10/17/ Gribble, Lazowska, Levy, Zahorjan 2. 10/17/ Gribble, Lazowska, Levy, Zahorjan 4

CS3210: Multiprocessors and Locking

Recap: Thread. What is it? What does it need (thread private)? What for? How to implement? Independent flow of control. Stack

Synchronization 2: Locks (part 2), Mutexes

Processes and Threads

1 Programs and Processes

238P: Operating Systems. Lecture 14: Process scheduling

Synchronization I. Jo, Heeseung

Processes & Threads. Today. Next Time. ! Process concept! Process model! Implementing processes! Multiprocessing once again. ! More of the same J

Synchronising Threads

Compile and execute fifo1.cpp listed above. Try the Balady's anomaly examples discussed in class. Did you observe the Belady's anomaly?

Synchronization 1. Synchronization

Operating Systems. Synchronization

Kernel Critical Sections

CS3210: Processes and Switching

CS3210: Isolation Mechanisms

Process & Thread Management II. Queues. Sleep() and Sleep Queues CIS 657

Process & Thread Management II CIS 657

Intro to Threads. Two approaches to concurrency. Threaded multifinger: - Asynchronous I/O (lab) - Threads (today s lecture)

Midterm Exam March 13, 2013 CS162 Operating Systems

CMSC421: Principles of Operating Systems

Locks. Dongkun Shin, SKKU

Concurrency. On multiprocessors, several threads can execute simultaneously, one on each processor.

Kernels and Locking. Luca Abeni

Threads. Concurrency. What it is. Lecture Notes Week 2. Figure 1: Multi-Threading. Figure 2: Multi-Threading

Concurrency. On multiprocessors, several threads can execute simultaneously, one on each processor.

Lecture 5: Synchronization w/locks

Synchronization 1. Synchronization

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

MULTITHREADING AND SYNCHRONIZATION. CS124 Operating Systems Fall , Lecture 10

Lecture. DM510 - Operating Systems, Weekly Notes, Week 11/12, 2018

Synchronization I. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

CMSC 412 Project #3 Threads & Synchronization Due March 17 th, 2017, at 5:00pm

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

Multiprocessors and Locking

CS533 Concepts of Operating Systems. Jonathan Walpole

Administrivia. p. 1/20

Lecture 9: Multiprocessor OSs & Synchronization. CSC 469H1F Fall 2006 Angela Demke Brown

Implementing Locks. Nima Honarmand (Based on slides by Prof. Andrea Arpaci-Dusseau)

The Process Abstraction. CMPU 334 Operating Systems Jason Waterman

by Marina Cholakyan, Hyduke Noshadi, Sepehr Sahba and Young Cha

Introduction. This project will focus primarily on processes.

3. Process Management in xv6

[537] Locks and Condition Variables. Tyler Harter

Misc. Notes. In BVT, switch from i j only if E j E i C/w i. In BVT, Google is example of W better then L. For lab, recall PDE and PTE bits get ANDed

COL331/COL633 Major Exam Operating Systems Sem II, Answer all 14 questions (12 pages) Max. Marks: 41

Dealing with Issues for Interprocess Communication

[537] Locks. Tyler Harter

CS3733: Operating Systems

Processes. Today. Next Time. ! Process concept! Process model! Implementing processes! Multiprocessing once again. ! Scheduling processes

CS 111. Operating Systems Peter Reiher

4. The Abstraction: The Process

Implementing Mutual Exclusion. Sarah Diesburg Operating Systems CS 3430

Administrivia. Review: Thread package API. Program B. Program A. Program C. Correct answers. Please ask questions on Google group

1 RCU. 2 Improving spinlock performance. 3 Kernel interface for sleeping locks. 4 Deadlock. 5 Transactions. 6 Scalable interface design

Processes Prof. James L. Frankel Harvard University. Version of 6:16 PM 10-Feb-2017 Copyright 2017, 2015 James L. Frankel. All rights reserved.

Precept 2: Non-preemptive Scheduler. COS 318: Fall 2018

What are they? How do we represent them? Scheduling Something smaller than a process? Threads Synchronizing and Communicating Classic IPC problems

Synchronization. Disclaimer: some slides are adopted from the book authors slides with permission 1

Processes. q Process concept q Process model and implementation q Multiprocessing once again q Next Time: Scheduling

Chapter 6: Process Synchronization. Operating System Concepts 8 th Edition,

Operating Systems. Lecture 4 - Concurrency and Synchronization. Master of Computer Science PUF - Hồ Chí Minh 2016/2017

CS 471 Operating Systems. Yue Cheng. George Mason University Fall 2017

Synchronization for Concurrent Tasks

Processes. Dr. Yingwu Zhu

OS Structure. User mode/ kernel mode (Dual-Mode) Memory protection, privileged instructions. Definition, examples, how it works?

CS 333 Introduction to Operating Systems. Class 4 Concurrent Programming and Synchronization Primitives

Concurrency: Mutual Exclusion (Locks)

Synchronization. CS61, Lecture 18. Prof. Stephen Chong November 3, 2011

ECE 391 Exam 1 Review Session - Spring Brought to you by HKN

CROWDMARK. Examination Midterm. Spring 2017 CS 350. Closed Book. Page 1 of 30. University of Waterloo CS350 Midterm Examination.

Chapter 6: Synchronization. Operating System Concepts 8 th Edition,

Review: Thread package API

Prof. Dr. Hasan Hüseyin

Systèmes d Exploitation Avancés

First Midterm Exam September 28, 2017 CS162 Operating Systems

Transcription:

Building Concurrency Primitives Science Computer Science CS 450: Operating Systems Sean Wallace <swallac6@iit.edu>

Previously 1. Decided concurrency was a useful (sometimes necessary) thing to have. 2. Assumed the presence of concurrent programming primitives (e.g., locks). 3. Showed how to use these primitives in concurrent programming scenarios. 2

but how are these primitives actually constructed? - as usual: responsibility is shared between kernel and hardware. 3

Agenda The mutex lock xv6 concurrency mechanisms Code review: implementation & usage 4

The mutex lock 5

Thread A a1 count = count + 1 Thread B b1 count = count + 1 allocated use acquire count TA TB 6

Basic requirement: Prevent other threads from entering their crucial section while one thread holds the lock I.e., execute critical section in mutex 7

Lock-polling spinlock struct spinlock { int locked; ; void acquire(struct spinlock *l) { while (1) { if (!l->locked) { l->locked = 1; break; void release(struct spinlock *l) { l->locked = 0; 8

if (!l->locked) { /* test */ l - > l o c k e d = 1; /* set */ break; Problem: thread can be preempted between test & set operations Again, must guarantee execution of test & set in mutex Using a lock!? 9

Time for an alternative strategy! 10

Recognize that preemption is carried out by a hardware interrupt so, disable interrupts! 11

x86: interrupt flag (IF) in FLAGS register Cleared/set by cli/sti instructions Restored by iret instruction Note: above are all privileged operations i.e., must be performed by kernel 12

One possible setup: begin_mutex(); user /* critical section */ end_mutex(); kernel asm("cli"); asm("sti"); 13

Horrible idea! User code cannot be preempted; kernel effectively neutered Also, prohibits all concurrency (not just for related critical sections) 14

Should only block interrupts in kernel space, and minimize blocked timeframe void acquire(struct spinlock *l) { int done = 0; while (!done) { asm("cli"); if (!l->locked) { done = l->locked = 1; break; asm("sti"); void release(struct spinlock *l) { l->locked = 0; 15

But! Preventing interrupts only helps to avoid concurrency due to preemption Insufficient on a multiprocessor system! Where we have true parallelism Each processor has its own interrupts 16

(fail) asm("cli"); if (!l->locked) { done = l->locked = 1; asm("sti"); 17

Instead of a general mutex, recognize that all we need is to make test (read) & set (write) operations on lock atomic asm("cli"); if (!l->locked) { done = l->locked = 1; asm("sti"); 18

E.g., x86 atomic exchange instruction (xchg) Atomically swaps register/memory content Guarantees no out-of-order execution # note: pseudo-assembly! loop: movl $1, %eax # set up "new" value in reg xchgl l->locked, %eax # swap values in reg & lock test %eax, %eax jne loop # spin if old value!= 0 19

xv6: spinlock.c void acquire(struct spinlock *lk) {... if(holding(lk)) panic("acquire"); while(xchg(&lk->locked, 1)!= 0);... void release(struct spinlock *lk) { if(!holding(lk)) panic("release"); lk->pcs[0] = 0; lk->cpu = 0; xchg(&lk->locked, 0);... 20

xv6 uses spin locks internally e.g., to protect proc array in scheduler: void scheduler(void) {... acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[nproc]; p++){ if(p->state!= RUNNABLE) continue; proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); proc = 0; release(&ptable.lock); Maintains mutex across parallel execution of scheduler on separate CPUs 21

In theory, scheduler execution may also be interrupted by the clock which causes the current thread to yield: // Give up the CPU for one scheduling round. void yield(void) { acquire(&ptable.lock); //DOC: yieldlock proc->state = RUNNABLE; sched(); release(&ptable.lock); 22

Ok, right? void scheduler(void) { acquire(&ptable.lock);... release(&ptable.lock); void yield(void) { acquire(&ptable.lock);... release(&ptable.lock); 23

No! Designed to enforce mutex between threads. If one thread tries to acquire a lock more than once, it will have to wait for itself to release the lock which it can t/won t. Deadlock! 24

xv6 s (ultra-conservative) policy: Never hold a lock when interrupts are enabled Corollary: Can only enable interrupts when all locks have been released (may hold more than one at any time) 25

void acquire(struct spinlock *lk) { pushcli(); if(holding(lk)) panic("acquire"); while(xchg(&lk->locked, 1)!= 0);... void release(struct spinlock *lk) { if(!holding(lk)) panic("release");... xchg(&lk->locked, 0); popcli(); void pushcli(void) { int eflags; eflags = readeflags(); cli(); if(cpu->ncli++ == 0) cpu->intena = eflags & FL_IF; void popcli(void) { if(readeflags()&fl_if) panic("popcli - interruptible"); if(--cpu->ncli < 0) panic("popcli"); if(cpu->ncli == 0 && cpu->intena) sti(); 26

Spinlock usage: When to lock? How long to hold onto a lock? 27

Spinlocks are very inefficient! Lock polling is indistinguishable from application logic (e.g., scheduling) Scheduler will allocate entire time quanta to perform lock polling 28

Would like blocking logic I.e., threads block on some condition and are not re-activated until necessary - Push notification vs. continuous polling 29

xv6 implements sleep and wakeup mechanism for blocking threads on semantic channels (proc.c) distinct scheduler state (SLEEPING) prevents re-activation 30

void sleep(void *chan, struct spinlock *lk) { if(proc == 0) panic("sleep"); if(lk == 0) panic("sleep without lk"); // Must acquire ptable.lock in order to // change p->state and then call sched. // Once we hold ptable.lock, we can be // guaranteed that we won't miss any wakeup // (wakeup runs with ptable.lock locked), // so it's okay to release lk. if(lk!= &ptable.lock){ //DOC: sleeplock0 acquire(&ptable.lock); //DOC: sleeplock1 release(lk); // Go to sleep. proc->chan = chan; proc->state = SLEEPING; sched(); // Tidy up. proc->chan = 0; // Reacquire original lock. if(lk!= &ptable.lock){ //DOC: sleeplock2 release(&ptable.lock); acquire(lk); // Wake up all processes sleeping on chan. void wakeup(void *chan) { acquire(&ptable.lock); wakeup1(chan); release(&ptable.lock); //PAGEBREAK! // Wake up all processes sleeping on chan. // The ptable lock must be held. static void wakeup1(void *chan) { struct proc *p; for(p = ptable.proc; p < &ptable.proc[nproc]; p++) if(p->state == SLEEPING && p->chan == chan) p->state = RUNNABLE; 31

Sample usage: wait (synchronize on termination, reap child) / exit (process termination) 32

// Wait for a child process to exit // and return its pid. // Return -1 if this process has no children. int wait(void) { struct proc *p; int havekids, pid; // Exit the current process. Does not return. // An exited process remains in the zombie state // until its parent calls wait() to find out it exited. void exit(void) { struct proc *p; int fd; acquire(&ptable.lock); for(;;){ havekids = 0; for(p = ptable.proc; p < &ptable.proc[nproc]; p++){ if(p->parent!= proc) continue; havekids = 1; if(p->state == ZOMBIE){ // Found one. pid = p->pid; kfree(p->kstack); p->kstack = 0; freevm(p->pgdir); p->state = UNUSED; p->pid = 0; p->parent = 0; p->name[0] = 0; p->killed = 0; release(&ptable.lock); return pid; if(!havekids proc->killed){ release(&ptable.lock); return -1; if(proc == initproc) panic("init exiting"); // Close all open files. for(fd = 0; fd < NOFILE; fd++){ if(proc->ofile[fd]){ fileclose(proc->ofile[fd]); proc->ofile[fd] = 0; iput(proc->cwd); proc->cwd = 0; acquire(&ptable.lock); // Parent might be sleeping in wait(). wakeup1(proc->parent); // Pass abandoned children to init. for(p = ptable.proc; p < &ptable.proc[nproc]; p++){ if(p->parent == proc){ p->parent = initproc; if(p->state == ZOMBIE) wakeup1(initproc); sleep(proc, &ptable.lock); 33 proc->state = ZOMBIE; sched(); panic("zombie exit");