Peterson s Algorithm

Similar documents
Programming Paradigms for Concurrency Lecture 2 - Mutual Exclusion

Mutual Exclusion. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Lecture 7: Mutual Exclusion 2/16/12. slides adapted from The Art of Multiprocessor Programming, Herlihy and Shavit

Mutual Exclusion. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

What We'll Cover Today

Mutual Exclusion. 1 Formal problem definitions. Time notion CSE /17/2015. Outline of this lecture:

Solution: a lock (a/k/a mutex) public: virtual void unlock() =0;

Mutual Exclusion: Classical Algorithms for Locks

DD2451 Parallel and Distributed Computing --- FDD3008 Distributed Algorithms

Programming Paradigms for Concurrency Lecture 3 Concurrent Objects

10/28/11. DD2451 Overview. DD2451 Overview. FDD 3008 Overview. Course Material

Unit 6: Indeterminate Computation

Advanced Multiprocessor Programming

Concurrent Computing

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

Lecture Topics. Announcements. Today: Concurrency: Mutual Exclusion (Stallings, chapter , 5.7)

Chapter 6: Process [& Thread] Synchronization. CSCI [4 6] 730 Operating Systems. Why does cooperation require synchronization?

Shared-Memory Computability

Process Synchronization

! Why is synchronization needed? ! Synchronization Language/Definitions: ! How are locks implemented? Maria Hybinette, UGA

CSCI [4 6] 730 Operating Systems. Example Execution. Process [& Thread] Synchronization. Why does cooperation require synchronization?

Pre- and post- CS protocols. CS 361 Concurrent programming Drexel University Fall 2004 Lecture 7. Other requirements for a mutual exclusion algorithm

Part III Synchronization Software and Hardware Solutions

Models of concurrency & synchronization algorithms

SPIN, PETERSON AND BAKERY LOCKS

Process Synchronization. Mehdi Kargahi School of ECE University of Tehran Spring 2008

Process Synchronization

Coarse-grained and fine-grained locking Niklas Fors

Spin Locks and Contention. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Concurrency: Mutual Exclusion and Synchronization

CS370 Operating Systems

Chapter 5: Process Synchronization. Operating System Concepts Essentials 2 nd Edition

Atomicity and Virtualization. Atomicity. Critical section. Edsger s perspective. Virtualizing a resource requires managing concurrent accesses

Concurrent Skip Lists. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

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

MULTITHREADING AND SYNCHRONIZATION. CS124 Operating Systems Fall , Lecture 10

Sequen&al Consistency and Linearizability

Operating Systems. Designed and Presented by Dr. Ayman Elshenawy Elsefy

CS 361 Concurrent programming Drexel University Fall 2004 Lecture 8. Proof by contradiction. Proof of correctness. Proof of mutual exclusion property

Example Threads. compile: gcc mythread.cc -o mythread -lpthread What is the output of this program? #include <pthread.h> #include <stdio.

Chapter 5: Process Synchronization. Operating System Concepts 9 th Edition

Concurrency: Mutual Exclusion and

Chapter 6: Process Synchronization

Chapter 6: Synchronization. Chapter 6: Synchronization. 6.1 Background. Part Three - Process Coordination. Consumer. Producer. 6.

Semaphores. May 10, Mutual exclusion with shared variables is difficult (e.g. Dekker s solution).

Thread Synchronization: Foundations. Properties. Safety properties. Edsger s perspective. Nothing bad happens

Chapter 7: Process Synchronization. Background. Illustration

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

Spin Locks and Contention

Background. The Critical-Section Problem Synchronisation Hardware Inefficient Spinning Semaphores Semaphore Examples Scheduling.

Spin Locks and Contention. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Synchronization Principles

Chapter 6: Process Synchronization. Module 6: Process Synchronization

Process Management And Synchronization

Chapter 6: Process Synchronization

Module 6: Process Synchronization. Operating System Concepts with Java 8 th Edition

CS370 Operating Systems

Chapter 5: Process Synchronization. Operating System Concepts 9 th Edition

Process Synchronization

Chapter 7: Process Synchronization. Background

Implementing Mutual Exclusion. Sarah Diesburg Operating Systems CS 3430

Announcements. Office hours. Reading. W office hour will be not starting next week. Chapter 7 (this whole week) CMSC 412 S02 (lect 7)

1 The comparison of QC, SC and LIN

EECE.4810/EECE.5730: Operating Systems Spring 2017 Homework 2 Solution

Module 6: Process Synchronization

Lesson 6: Process Synchronization

Process Synchronization

Process Synchronization

Chapter 6: Synchronization

Algorithmic Verification. Algorithmic Verification. Model checking. Algorithmic verification. The software crisis (and hardware as well)

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

Introduction to Concurrency and Multicore Programming. Slides adapted from Art of Multicore Programming by Herlihy and Shavit

Synchronization. Race Condition. The Critical-Section Problem Solution. The Synchronization Problem. Typical Process P i. Peterson s Solution

Lecture Topics. Announcements. Today: Concurrency (Stallings, chapter , 5.7) Next: Exam #1. Self-Study Exercise #5. Project #3 (due 9/28)

Background. Old Producer Process Code. Improving the Bounded Buffer. Old Consumer Process Code

Dept. of CSE, York Univ. 1

COMP Parallel Computing. CC-NUMA (2) Memory Consistency

Part II Process Management Chapter 6: Process Synchronization

CS4411 Intro. to Operating Systems Exam 1 Fall points 9 pages

Background. Module 6: Process Synchronization. Bounded-Buffer (Cont.) Bounded-Buffer. Background

Concurrency Control. [R&G] Chapter 17 CS432 1

Chapter 6 Synchronization

PESIT Bangalore South Campus

Linked Lists: Locking, Lock- Free, and Beyond. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Synchronization. CS 475, Spring 2018 Concurrent & Distributed Systems

Synchronization API of Pthread Mutex: lock, unlock, try_lock CondVar: wait, signal, signal_broadcast. Synchronization

Universality of Consensus. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Constant RMR Transformation to Augment Reader-Writer Locks with Atomic Upgrade/Downgrade Support

Linked Lists: Locking, Lock-Free, and Beyond. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

DD2451 Parallel and Distributed Computing --- FDD3008 Distributed Algorithms

Lecture 3: Synchronization & Deadlocks

Lecture 5 Threads and Pthreads II

Concurrency Control. Conflict Serializable Schedules. Example. Chapter 17

STUDENT NAME: STUDENT ID: Problem 1 Problem 2 Problem 3 Problem 4 Problem 5 Total

Operating Systems CMPSC 473. Synchronization February 21, Lecture 11 Instructor: Trent Jaeger

Introduction. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit. Art of Multiprocessor Programming

Distributed Computing through Combinatorial Topology MITRO207, P4, 2017

Nondeterministic Programming

Midterm on next week Tuesday May 4. CS 361 Concurrent programming Drexel University Fall 2004 Lecture 9

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

Transcription:

Peterson s Algorithm public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } 24/03/10 Art of Multiprocessor Programming 1

Mutual Exclusion public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; If thread 0 in critical section, flag[0]=true, victim = 1 If thread 1 in critical section, flag[1]=true, victim = 0 Cannot both be true 24/03/10 Art of Multiprocessor Programming 2

Deadlock Free public void lock() { while (flag[j] && victim == i) {}; Thread blocked only at while loop only if it is the victim One or the other must not be the victim 24/03/10 Art of Multiprocessor Programming 3

Starvation Free Thread i blocked only if j repeatedly re-enters so that flag[j] == true and victim == i When j re-enters it sets victim to j. So i gets in public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } 24/03/10 Art of Multiprocessor Programming 4

The Filter Algorithm for n Threads There are n-1 waiting rooms called levels At each level At least one enters level At least one blocked if many try ncs cs Only one thread makes it through 24/03/10 Art of Multiprocessor Programming 5

Filter class Filter implements Lock { volatile int[] level; // level[i] for thread i volatile int[] victim; // victim[l] for level L } public Filter(int n) { level = new int[n]; victim = new int[n]; level for (int i = 1; i < n; i++) { level[i] = 0; }} 0 2 n-1 0 0 4 0 0 0 0 0 1 2 4 Thread 2 at level 4 24/03/10 Art of Multiprocessor Programming 6 n-1 victim

Filter class Filter implements Lock { public void lock(){ for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (( k!= i level[k] >= L) && victim[l] == i ); }} public void unlock() { level[i] = 0; }} 24/03/10 Art of Multiprocessor Programming 7

Filter class Filter implements Lock { public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (( k!= i) level[k] >= L) && victim[l] == i); }} public void release(int i) { level[i] = 0; }} One level at a time 24/03/10 Art of Multiprocessor Programming 8

Filter class Filter implements Lock { public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (( k!= i) level[k] >= L) && victim[l] == i); // busy wait }} public void release(int i) { level[i] = 0; }} Announce intention to enter level L 24/03/10 Art of Multiprocessor Programming 9

Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (( k!= i) level[k] >= L) && victim[l] == i); }} public void release(int i) { level[i] = 0; }} Give priority to anyone but me 24/03/10 Art of Multiprocessor Programming 10

Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; Wait as long as someone else is at same or higher level, and I m designated victim while (( k!= i) level[k] >= L) && victim[l] == i); }} public void release(int i) { level[i] = 0; }} 24/03/10 Art of Multiprocessor Programming 11

Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (( k!= i) level[k] >= L) && victim[l] == i); }} public void release(int i) { level[i] = 0; }} Thread enters level L when it completes the loop 24/03/10 Art of Multiprocessor Programming 12

Claim Start at level L=0 At most n-l threads enter level L Mutual exclusion at level L=n-1 ncs L=0 L=1 L=n-2 cs L=n-1 24/03/10 Art of Multiprocessor Programming 13

Induction Hypothesis No more than n-l+1 at level L-1 Induction step: by contradiction Assume all at level L-1 enter level L A last to write victim[l] B is any other thread at level L ncs cs assume L-1 has n-l+1 L has n-l prove 24/03/10 Art of Multiprocessor Programming 14

Proof Structure Last to write victim[l] A ncs cs B Assumed to enter L-1 n-l+1 = 4 n-l+1 = 4 By way of contradiction all enter L Show that A must have seen B at level L and since victim[l] == A could not have entered 24/03/10 Art of Multiprocessor Programming 15

From the Code (1) write B (level[b]=l)write B (victim[l]=b) public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (( k!= i) level[k] >= L) && victim[l] == i) {}; }} 24/03/10 Art of Multiprocessor Programming 16

From the Code (2) write A (victim[l]=a)read A (level[b]) public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (( k!= i) level[k] >= L) && victim[l] == i) {}; }} 24/03/10 Art of Multiprocessor Programming 17

By Assumption (3) write B (victim[l]=b)write A (victim[l]=a) By assumption, A is the last thread to write victim[l] 24/03/10 Art of Multiprocessor Programming 18

Combining Observations (1) write B (level[b]=l)write B (victim[l]=b) (3) write B (victim[l]=b)write A (victim[l]=a) (2) write A (victim[l]=a)read A (level[b]) 24/03/10 Art of Multiprocessor Programming 19

Combining Observations (1) write B (level[b]=l)write B (victim[l]=b) (3) write B (victim[l]=b)write A (victim[l]=a) (2) write A (victim[l]=a)read A (level[b]) 24/03/10 public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (( k!= i) level[k] >= L) && victim[l] == i) {}; }} Art of Multiprocessor Programming 20

Combining Observations (1) write B (level[b]=l)write B (victim[l]=b) (3) write B (victim[l]=b)write A (victim[l]=a) (2) write A (victim[l]=a)read A (level[b]) Thus, A read level[b] L, A was last to write victim[l], so it could not have entered level L! 24/03/10 Art of Multiprocessor Programming 21

No Starvation Filter Lock satisfies properties: Just like Peterson Alg at any level So no one starves But what about fairness? Threads can be overtaken by others 24/03/10 Art of Multiprocessor Programming 22

Bounded Waiting Want stronger fairness guarantees Thread not overtaken too much Need to adjust definitions. 24/03/10 Art of Multiprocessor Programming 23

Bounded Waiting Divide lock() method into 2 parts: Doorway interval: Written DA always finishes in finite steps Waiting interval: Written WA may take unbounded steps 24/03/10 Art of Multiprocessor Programming 24

r-bounded Waiting For threads A and B: If D A k D B j A s k-th doorway precedes B s j-th doorway Then CS A k CS B j+r A s k-th critical section precedes B s (j+r)-th critical section B cannot overtake A by more than r times First-come-first-served means r = 0. 24/03/10 Art of Multiprocessor Programming 25

Fairness Again Filter Lock satisfies properties: No one starves But very weak fairness Not r-bounded for any r! That s pretty lame 24/03/10 Art of Multiprocessor Programming 26

Bakery Algorithm Provides First-Come-First-Served How? Take a number Wait until lower numbers have been served Lexicographic order (a,i) > (b,j) If a > b, or a = b and i > j 24/03/10 Art of Multiprocessor Programming 27

Bakery Algorithm class Bakery implements Lock { } volatile boolean[] flag; volatile Label[] label; public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { } flag[i] = false; label[i] = 0; 24/03/10 Art of Multiprocessor Programming 28

Bakery Algorithm class Bakery implements Lock { } volatile boolean[] flag; volatile Label[] label; public Bakery (int n) { flag = new boolean[n]; f f t f f t f f label = new Label[n]; 0 0 4 0 0 5 0 0 for (int i = 0; i < n; i++) { } flag[i] = false; label[i] = 0; 0 2 CS 6 n-1 24/03/10 Art of Multiprocessor Programming 29

Bakery Algorithm class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ( k flag[k] && (label[i],i) > (label[k],k)); } 24/03/10 Art of Multiprocessor Programming 30

Bakery Algorithm class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; Doorway while ( k flag[k] && (label[i],i) > (label[k],k)); } 24/03/10 Art of Multiprocessor Programming 31

Bakery Algorithm class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; I m interested while ( k flag[k] && (label[i],i) > (label[k],k)); } 24/03/10 Art of Multiprocessor Programming 32

Bakery Algorithm class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ( k flag[k] && (label[i],i) > (label[k],k)); } Take increasing label (read labels in some arbitrary order) 24/03/10 Art of Multiprocessor Programming 33

Bakery Algorithm class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ( k flag[k] && (label[i],i) > (label[k],k)); } Someone is interested 24/03/10 Art of Multiprocessor Programming 34

Bakery Algorithm class Bakery implements Lock { boolean flag[n]; int label[n]; Someone is interested public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ( k flag[k] && (label[i],i) > (label[k],k)); } With lower (label,i) in lexicographic order 24/03/10 Art of Multiprocessor Programming 35

Bakery Algorithm class Bakery implements Lock { public void unlock() { flag[i] = false; } } 24/03/10 Art of Multiprocessor Programming 36

Bakery Algorithm class Bakery implements Lock { No longer interested public void unlock() { flag[i] = false; } } labels are always increasing 24/03/10 Art of Multiprocessor Programming 37

No Deadlock There is always one thread with earliest label Ties are impossible (why?) 24/03/10 Art of Multiprocessor Programming 38

First-Come-First-Served If DA D B then A s label is earlier write A (label[a]) read B (label[a]) write B (label[b]) read B (flag[a]) So B is locked out while flag[a] is true class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ( k flag[k] && (label[i],i) > (label[k],k)); } 24/03/10 Art of Multiprocessor Programming 39

Mutual Exclusion Suppose A and B in CS together Suppose A has earlier label When B entered, it must have seen flag[a] is false, or label[a] > label[b] class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ( k flag[k] && (label[i],i) > (label[k],k)); } 24/03/10 Art of Multiprocessor Programming 40

Mutual Exclusion Labels are strictly increasing so B must have seen flag[a] == false 24/03/10 Art of Multiprocessor Programming 41

Mutual Exclusion Labels are strictly increasing so B must have seen flag[a] == false Labeling B read B (flag[a]) write A (flag[a]) Labeling A 24/03/10 Art of Multiprocessor Programming 42

Mutual Exclusion Labels are strictly increasing so B must have seen flag[a] == false Labeling B read B (flag[a]) write A (flag[a]) Labeling A Which contradicts the assumption that A has an earlier label 24/03/10 Art of Multiprocessor Programming 43

Bakery Y2 32 K Bug class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ( k flag[k] && (label[i],i) > (label[k],k)); } 24/03/10 Art of Multiprocessor Programming 44

Bakery Y2 32 K Bug class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ( k flag[k] && (label[i],i) > (label[k],k)); } Mutex breaks if label[i] overflows 24/03/10 Art of Multiprocessor Programming 45

Deep Philosophical Question The Bakery Algorithm is Succinct, Elegant, and Fair. Q: So why isn t it practical? A: Well, you have to read N distinct variables 24/03/10 Art of Multiprocessor Programming 46

Shared Memory Shared read/write memory locations called Registers (historical reasons) Come in different flavors Multi-Reader-Single-Writer (Flag[]) Multi-Reader-Multi-Writer (Victim[]) Not interesting: SRMW and SRSW 24/03/10 Art of Multiprocessor Programming 47

Theorem At least N MRSW (multi-reader/singlewriter) registers are needed to solve deadlock-free mutual exclusion. N registers like Flag[] 24/03/10 Art of Multiprocessor Programming 48

Proving Algorithmic Impossibility C To show no algorithm exists: assume by way of contradiction one does, show a bad execution that violates properties: in our case assume an alg for deadlock free mutual exclusion using < N registers write CS 24/03/10 Art of Multiprocessor Programming 49

Proof: Need N-MRSW Registers Each thread must write to some register A B C write write CS CS CS can t tell whether A is in critical section 24/03/10 Art of Multiprocessor Programming 50

Upper Bound Bakery algorithm Uses 2N MRSW registers So the bound is (pretty) tight But what if we use MRMW registers? Like victim[]? 24/03/10 Art of Multiprocessor Programming 51

Bad News Theorem At least N MRMW multireader/multi-writer registers are needed to solve deadlock-free mutual exclusion. (So multiple writers don t help) 24/03/10 Art of Multiprocessor Programming 52

Theorem (First 2-Threads) Theorem: Deadlock-free mutual exclusion for 2 threads requires at least 2 multi-reader multi-writer registers Proof: assume one register suffices and derive a contradiction 24/03/10 Art of Multiprocessor Programming 53

Two Thread Execution A B Write(R) R CS CS Threads run, reading and writing R Deadlock free so at least one gets in 24/03/10 Art of Multiprocessor Programming 54

Covering State for One Register B Write(R) B has to write to the register before entering CS, so stop it just before 24/03/10 Art of Multiprocessor Programming 55

Proof: Assume Cover of 1 A B Write(R) CS A runs, possibly writes to the register, enters CS 24/03/10 Art of Multiprocessor Programming 56

Proof: Assume Cover of 1 A B CS B Runs, first obliterating any trace of A, then also enters the critical section Write(R) CS 24/03/10 Art of Multiprocessor Programming 57

Theorem Deadlock-free mutual exclusion for 3 threads requires at least 3 multireader multi-writer registers 24/03/10 Art of Multiprocessor Programming 58

Proof: Assume Cover of 2 A B C Write(R B ) Write(R C ) Only 2 registers 24/03/10 Art of Multiprocessor Programming 59

Run A Solo A B C Write(R B ) Write(R C ) CS Writes to one or both registers, enters CS 24/03/10 Art of Multiprocessor Programming 60

Obliterate Traces of A A B C Write(R B ) Write(R C ) CS Other threads obliterate evidence that A entered CS 24/03/10 Art of Multiprocessor Programming 61

Mutual Exclusion Fails A B C Write(R B ) Write(R C ) CS CS CS looks empty, so another thread gets in 24/03/10 Art of Multiprocessor Programming 62

Proof Strategy Proved: a contradiction starting from a covering state for 2 registers Claim: a covering state for 2 registers is reachable from any state where CS is empty 24/03/10 Art of Multiprocessor Programming 63

Covering State for Two A B Write(R A ) Write(R B ) If we run B through CS 3 times, B must return twice to cover some register, say R B 24/03/10 Art of Multiprocessor Programming 64

Covering State for Two A B Write(R A ) Write(R B ) Start with B covering register RB for the 1 st time Run A until it is about to write to uncovered RA Are we done? 24/03/10 Art of Multiprocessor Programming 65

Covering State for Two A B Write(R A ) Write(R B ) NO! A could have written to R B So CS no longer looks empty 24/03/10 Art of Multiprocessor Programming 66

Covering State for Two A B Write(R A ) Write(R B ) Run B obliterating traces of A in RB Run B again until it is about to write to RB Now we are done 24/03/10 Art of Multiprocessor Programming 67

Inductively We Can Show A B C Write(R A ) Write(R B ) Write(R C ) There is a covering state Where k threads not in CS cover k distinct registers Proof follows when k = N-1 24/03/10 Art of Multiprocessor Programming 68

Summary of Lecture In the 1960 s many incorrect solutions to starvation-free mutual exclusion using RW-registers were published Today we know how to solve FIFO N thread mutual exclusion using 2N RW- Registers 24/03/10 Art of Multiprocessor Programming 69

Summary of Lecture N RW-Registers inefficient Because writes cover older writes Need stronger hardware operations do not have the covering problem In next lectures - understand what these operations are 24/03/10 Art of Multiprocessor Programming 70

This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License. You are free: to Share to copy, distribute and transmit the work to Remix to adapt the work Under the following conditions: Attribution. You must attribute the work to The Art of Multiprocessor Programming (but not in any way that suggests that the authors endorse you or your use of the work). Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license. For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to http://creativecommons.org/licenses/by-sa/3.0/. Any of the above conditions can be waived if you get permission from the copyright holder. Nothing in this license impairs or restricts the author's moral rights. 24/03/10 Art of Multiprocessor Programming 71