CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics Principles of Computers 19 th Lecture Pavel Ježek, Ph.D.
Thread T1 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem;
Thread T1 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem;
Thread T1 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem;
Thread T1 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem;
Thread T1 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem;
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem;
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem;
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem;
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; Context Switch
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; Context Switch next prev OtherItem
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; next prev OtherItem
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; next prev OtherItem
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; next prev OtherItem
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; next prev OtherItem
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; Context Switch next prev OtherItem Still a valid doubly-linked list
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; next prev OtherItem
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; next prev OtherItem
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; next prev OtherItem
Threads T1 and T2 Inserting into A Doubly-Linked List next prev AfterThis next prev NewItem next prev BeforeThis T1: NewItem^.prev := AfterThis; T1: AfterThis^.next^.prev := NewItem; T2: OtherItem^.prev := AfterThis; T2: AfterThis^.next^.prev := OtherItem; T2: OtherItem^.next := AfterThis^.next; T2: AfterThis.next := OtherItem; T1: NewItem^.next := AfterThis^.next; T1: AfterThis.next := NewItem; next prev OtherItem
Is It Thread Safe? next prev AfterThis next prev NewItem next prev BeforeThis procedure InsertItem(AfterThis : Node; NewItem : Node) begin NewItem^.prev := AfterThis; AfterThis^.next^.prev := NewItem; NewItem^.next := AfterThis^.next; AfterThis.next := NewItem; end;
Is It Thread Safe? In Cooperative Multitasking? next prev AfterThis next prev NewItem next prev BeforeThis procedure InsertItem(AfterThis : Node; NewItem : Node) begin Yield; { allowed here } NewItem^.prev := AfterThis; AfterThis^.next^.prev := NewItem; no Yield here! NewItem^.next := AfterThis^.next; AfterThis.next := NewItem; Yield; { allowed here } end;
Is It Thread Safe? In Preemptive Multitasking? next prev AfterThis next prev NewItem next prev BeforeThis procedure InsertItem(AfterThis : Node; NewItem : Node) begin NewItem^.prev := AfterThis; AfterThis^.next^.prev := NewItem; NewItem^.next := AfterThis^.next; AfterThis.next := NewItem; end;
Critical Section Is It Thread Safe? In Preemptive Multitasking? next prev AfterThis next prev NewItem next prev BeforeThis procedure InsertItem(AfterThis : Node; NewItem : Node) begin NewItem^.prev := AfterThis; AfterThis^.next^.prev := NewItem; NewItem^.next := AfterThis^.next; AfterThis.next := NewItem; end;
Is It Thread Safe? In Preemptive Multitasking? next prev AfterThis next prev NewItem next prev BeforeThis procedure InsertItem(AfterThis : Node; NewItem : Node) begin asm cli; NewItem^.prev := AfterThis; AfterThis^.next^.prev := NewItem; NewItem^.next := AfterThis^.next; AfterThis.next := NewItem; asm sti; end;
Critical Section Is It Thread Safe? In Preemptive Multitasking? next prev AfterThis next prev NewItem next prev BeforeThis procedure InsertItem(AfterThis : Node; NewItem : Node) begin NewItem^.prev := AfterThis; AfterThis^.next^.prev := NewItem; NewItem^.next := AfterThis^.next; AfterThis.next := NewItem; end;
Is It Thread Safe? Using Locks? next prev AfterThis next prev NewItem next prev BeforeThis procedure InsertItem(AfterThis : Node; NewItem : Node) begin Lock(l); NewItem^.prev := AfterThis; AfterThis^.next^.prev := NewItem; NewItem^.next := AfterThis^.next; AfterThis.next := NewItem; Unlock(l); end;
Legend Data Thread lifetime Running thread Thread waiting for an unspecified event Thread waiting for a lock Thread ready to run Successful thread action Failed thread action Action asynchronous from the point of view of a target thread Unlocked lock Locked lock
Fighting for A Lock Lock A state: unlocked Lock A state: unlocked RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3
Fighting for A Lock Lock A state: unlocked Lock A state: unlocked RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A
Fighting for A Lock Lock A state: held by T1 Lock A state: held by T1 RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A
Fighting for A Lock Lock A state: held by T1 Lock A state: held by T1 RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A
Fighting for A Lock Lock A state: held by T1 Lock A state: held by T1 RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A
Fighting for A Lock Lock A state: held by T1 Lock A state: held by T1 RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A
Fighting for A Lock Lock A state: held by T1 Lock A state: held by T1 RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A
Fighting for A Lock Lock A state: held by T1 Lock A state: held by T1 RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A W. A
Fighting for A Lock Lock A state: held by T1 Lock A state: held by T1 RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A W. A unlock A
Fighting for A Lock Lock A state: unlocked Lock A state: unlocked RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A W. A unlock A
Fighting for A Lock Lock A state: unlocked Lock A state: unlocked RUNNING Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A W. A unlock A wake up
RUNNING RTR READY-TO-RUN RTR READY-TO-RUN RTR READY-TO-RUN RTR READY-TO-RUN Fighting for A Lock Lock A state: unlocked Lock A state: unlocked Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A W. A unlock A wake up
RUNNING RTR READY-TO-RUN RTR READY-TO-RUN RTR READY-TO-RUN RTR READY-TO-RUN Fighting for A Lock Lock A state: unlocked Lock A state: unlocked Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A W. A unlock A wake up RUN lock A
RUNNING RTR READY-TO-RUN RTR READY-TO-RUN RTR READY-TO-RUN RTR READY-TO-RUN Fighting for A Lock Lock A state: held by T2 Lock A state: held by T2 Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A W. A unlock A wake up RUN lock A
READY-TO-RUN RUNNING RTR READY-TO-RUN RTR READY-TO-RUN Fighting for A Lock Lock A state: held by T2 Lock A state: held by T2 Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A W. A unlock A wake up lock A RUNNING RUN lock A
READY-TO-RUN RUNNING RTR READY-TO-RUN RTR READY-TO-RUN Fighting for A Lock Lock A state: held by T2 Lock A state: held by T2 Thread 1 RUNNING Thread 2 RUNNING Thread 3 lock A WAITING for Lock A lock A W. A unlock A wake up lock A RUNNING RUN lock A WAITING for A
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: unlocked Lock A state: unlocked WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: unlocked Lock A state: unlocked WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A wake up
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A wake up RTR READY-TO-RUN RTR READY-TO-RUN preemption (forced context switch)
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A wake up RTR READY-TO-RUN RTR READY-TO-RUN RUNNING
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A wake up RTR READY-TO-RUN RTR READY-TO-RUN RUNNING wake up
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A wake up RTR READY-TO-RUN RTR READY-TO-RUN RUNNING wake up RTR READY-TO-RUN RTR READY-TO-RUN preemption (forced context switch)
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A wake up RTR READY-TO-RUN RTR READY-TO-RUN RUNNING wake up RTR READY-TO-RUN RTR READY-TO-RUN RUNNING RTR READY-TO-RUN RTR READY-TO-RUN
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A wake up RTR READY-TO-RUN RTR READY-TO-RUN RUNNING wake up RTR READY-TO-RUN RTR READY-TO-RUN RUNNING RTR READY-TO-RUN RTR READY-TO-RUN lock A
Priority Inversion Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 WAITING Thread 1 WAITING Thread 2 RUNNING Thread 3 lock A wake up RTR READY-TO-RUN RTR READY-TO-RUN RUNNING wake up RTR READY-TO-RUN RTR READY-TO-RUN RUNNING RTR READY-TO-RUN RTR READY-TO-RUN lock A WAITING for Lock A RUNNING context switch
Priority Inversion: Solution? Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAIT priority boost RTR READY-TO-RUN RTR READY-TO-RUN
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAITING for Lock A RTR READY-TO-RUN RTR READY-TO-RUN RUNNING
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T3 Lock A state: held by T3 Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAITING for Lock A RTR READY-TO-RUN RTR READY-TO-RUN RUNNING unlock A
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: unlocked Lock A state: unlocked Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAITING for Lock A RTR READY-TO-RUN RTR READY-TO-RUN RUNNING unlock A
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: unlocked Lock A state: unlocked Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAITING for Lock A RTR READY-TO-RUN RTR READY-TO-RUN RUNNING unlock A wake up
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: unlocked Lock A state: unlocked Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAITING for Lock A RTR READY-TO-RUN RTR READY-TO-RUN RUNNING unlock A RUN restore old priority RTR READY-TO-RUN RTR READY-TO-RUN
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: unlocked Lock A state: unlocked Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAITING for Lock A RTR READY-TO-RUN RTR READY-TO-RUN RUNNING unlock A RUN RTR READY-TO-RUN RTR READY-TO-RUN preemption (forced context switch) RUN RTR READY-TO-RUN RTR READY-TO-RUN
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: unlocked Lock A state: unlocked Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAITING for Lock A RTR READY-TO-RUN RTR READY-TO-RUN RUNNING unlock A RUN RTR READY-TO-RUN RTR READY-TO-RUN RUN RTR READY-TO-RUN RTR READY-TO-RUN lock A
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Lock A state: held by T1 Lock A state: held by T1 Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAITING for Lock A RTR READY-TO-RUN RTR READY-TO-RUN RUNNING unlock A RUN RTR READY-TO-RUN RTR READY-TO-RUN RUN RTR READY-TO-RUN RTR READY-TO-RUN lock A
Solution? Priority Boost Priority Level 0 (highest) Priority Level 1 Priority Level 2 Priority Level 3 Priority Level 4 (lowest) Thread 1 Thread 2 Thread 3 READY-TO-RUN RUNNING lock A READY-TO-RUN WAITING for Lock A RTR READY-TO-RUN RTR READY-TO-RUN RUNNING unlock A RUN RTR READY-TO-RUN RTR READY-TO-RUN RUNNING READY-TO-RUN Lock A state: held by T1 Lock A state: held by T1 lock A