linked lists: locking, lock- free, and beyond · lock and load • to move to successor entry for e...

167
Linked Lists: Locking, Lock- Free, and Beyond … Maurice Herlihy CS176 Fall 2003

Upload: others

Post on 24-Jan-2021

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

Linked Lists: Locking, Lock-Free, and Beyond …

Maurice HerlihyCS176

Fall 2003

Page 2: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 2

Linked Lists

• We can make effective spin locks– Correct– Work well under contention

• Are we done with concurrent data structures?

Page 3: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 3

Not Over Yet

• Contention– Solved by MCS or CLH locks

• Sequential Bottleneck– No “bag of tricks”

• Linked Lists– Simple data structure– Good testbed

Page 4: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 4

Set Interface

• Unordered collection of objects• No duplicates• Methods

– Add a new object– Remove an object– Test if object is present

Page 5: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 5

List-Based Setspublic interface Set {public boolean add(Object x);public boolean remove(Object x);public boolean contains(Object x);

}

Page 6: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 6

List Entrypublic class Entry {public Object object;public int key;public Entry next;

}

Page 7: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 7

List Entrypublic class Entry {public Object object;public int key;public Entry next;

}

Object of interest

Page 8: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 8

List Entrypublic class Entry {public Object object;public int key;public Entry next;

}

Sort by key value(usually hash code)

Page 9: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 9

List Entrypublic class Entry {public Object object;public int key;public Entry next;

}

Sorting makes iteasy to detect absence

Page 10: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 10

List Entrypublic class Entry {public Object object;public int key;public Entry next;

}

Reference to next entry

Page 11: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 11

List-Based Set

a b c

Sentinel node never deleted(minimum possible key)

Page 12: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 12

Adding an Entry

a b c

b

Page 13: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 13

Removing an Entry

a b c

Page 14: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 14

Nu, What About Concurrency?

• Our bag of tricks– Coarse-grained locks– Fine-grained locks– Optimistic synchronization– Lock-free synchronization

Page 15: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 15

Coarse-Grained Locking

• Easy, same as synchronized methods– “One lock to rule them all …”

• Simple, clearly correct– Deserves respect!

• Works poorly with contention– Queue locks help– But bottleneck still an issue

Page 16: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 16

Fine-grained Locking

• Requires careful thought– “Do not meddle in the affairs of wizards,

for they are subtle and quick to anger”• Split object into pieces

– Each piece has own lock– Methods that work on disjoint pieces

need not exclude each other

Page 17: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 17

Optimistic Synchronization

• Requires very careful thought– “Do not meddle in the affairs of dragons,

for you are crunchy and taste good with ketchup."

• Try it without synchronization– If you win, you win– If not, try it again with synchronization

Page 18: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 18

Lock-Free Synchronization

• Dump locking altogether …– “You take the red pill and you stay in

Wonderland and I show you how deep the rabbit-hole goes”

• No locks, just native atomic methods– Usually compareAndSet

Page 19: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 19

Hand-over-Hand locking

a b c

Page 20: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 20

Removing an Entry

a b c d

remove b

Page 21: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 21

Removing an Entry

a b c d

remove b

remove c

Page 22: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 22

Uh-oh

a b c d

remove b

remove c

Page 23: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 23

Problem

• To delete entry b– Swing entry a’s next field to c

• Problem is,– Someone could delete c concurrently

Page 24: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 24

Insight

• If an entry is locked– No one can delete entry’s successor

• If a thread locks– Entry to be deleted– And its predecessor– Then it works

Page 25: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 25

Hand-Over-Hand Again

a b c d

remove b

Found it!

Page 26: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 26

Removing an Entry

a b c d

remove b

remove c

Page 27: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 27

Removing an Entry

a b c d

remove b

remove c

Page 28: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 28

Remove method

public boolean remove(Object object) {int key = object.hashCode();Entry predEntry, currEntry;try {

…} finally {currEntry.unlock();predEntry.unlock();

}}

Page 29: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 29

Remove method

public boolean remove(Object object) {int key = object.hashCode();Entry prevEntry, currEntry;try {

…} finally {currEntry.unlock();prevEntry.unlock();

}}

Key used to order entry

Page 30: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 30

Remove method

public boolean remove(Object object) {int key = object.hashCode();Entry predEntry, currEntry;try {

…} finally {currEntry.unlock();prevEntry.unlock();

}}

Predecessor and current entries

Page 31: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 31

Remove method

public boolean remove(Object object) {int key = object.hashCode();Entry prevEntry, currEntry;try {

…} finally {currEntry.unlock();predEntry.unlock();

}}

Make sure locks released

Page 32: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 32

Remove method

public boolean remove(Object object) {int key = object.hashCode();Entry prevEntry, currEntry;try {

…} finally {currEntry.unlock();prevEntry.unlock();

}}

Everything else

Page 33: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 33

Remove method

try {predEntry = this.head;predEntry.lock();currEntry = predEntry.next;currEntry.lock();…

} finally { … }

Page 34: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 34

Remove method

try {predEntry = this.head;predEntry.lock();currEntry = predEntry.next;currEntry.lock();…

} finally { … }

lock previous

Page 35: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 35

Remove method

try {prevEntry = this.head;prevEntry.lock();currEntry = predEntry.next;currEntry.lock();…

} finally { … }

Lock current

Page 36: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 36

Remove method

try {prevEntry = this.head;prevEntry.lock();currEntry = prevEntry.next;currEntry.lock();…

} finally { … }

Traversing list

Page 37: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 37

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {predEntry.next = currEntry.next;return true;

}predEntry.unlock();predEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;

Page 38: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 38

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {prevEntry.next = currEntry.next;return true;

}prevEntry.unlock();prevEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;

Search key range

Page 39: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 39

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {prevEntry.next = currEntry.next;return true;

}prevEntry.unlock();prevEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;

At start of each loop: currEntry and predEntry

locked

Page 40: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 40

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {predEntry.next = currEntry.next;return true;

}prevEntry.unlock();prevEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;If entry found, remove it

Page 41: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 41

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {predEntry.next = currEntry.next;return true;

}prevEntry.unlock();prevEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;If entry found, remove it

Page 42: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 42

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {prevEntry.next = currEntry.next;return true;

}predEntry.unlock();prevEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;

Unlock predecessor

Page 43: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 43

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {prevEntry.next = currEntry.next;return true;

}prevEntry.unlock();prevEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;

Only one entry locked!

Page 44: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 44

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {prevEntry.next = currEntry.next;return true;

}prevEntry.unlock();predEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;

demote current

Page 45: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 45

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {prevEntry.next = currEntry.next;return true;

}prevEntry.unlock();prevEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;

Find and lock new current

Page 46: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 46

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {prevEntry.next = currEntry.next;return true;

}prevEntry.unlock();prevEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;

Lock invariant restored

Page 47: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 47

Remove: searching

while (currEntry.key <= key) {if (object == currEntry.object) {prevEntry.next = currEntry.next;return true;

}prevEntry.unlock();prevEntry = currEntry;currEntry = currEntry.next;currEntry.lock();

}return false;

Otherwise, error 404, dude!

Page 48: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 48

Why does this work?

• To remove entry e– Must lock e– Must lock e’s predecessor

• Therefore, if you lock an entry– It can’t be removed– And neither can its successor

Page 49: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 49

Lock and Load

• To move to successor entry for e– Lock e– Lock e.next– Unlock e

• While traversing– e cannot be removed– e.next cannot be removed

Don’t release e

Until next entry idenified and locked

Page 50: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 50

Adding Entries

• To add entry e– Must lock predecessor– Must lock successor

• Neither can be deleted– (Is successor lock actually required?)

Page 51: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 51

Drawbacks

• Better than coarse-grained lock– Threads can traverse in parallel

• Still not ideal– Long chain of acquire/release– Inefficient

Page 52: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 52

Optimistic Synchronization

• Find entries without locking• Lock entries• Check that everything is OK

Page 53: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 53

Removing an Entry

a b c d

remove c

return true

Page 54: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 54

What Can Go Wrong?

a b c d

remove c

remove b

Page 55: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 55

Check that Entry is Still Accessible

a b c d

remove c

Page 56: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 56

What Can Go Wrong?

a b c d

remove c

Add b’

b’

Page 57: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 57

What Can Go Wrong?

a b c d

remove c

b’

Page 58: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 58

Check that Entries Still Adjacent

a b c d

remove c

Page 59: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 59

Correctness

• If– Entry b and Entry c both locked– Entry b still accessible– Entry c still successor to b

• Then– Neither will be deleted– OK to delete and return true

Page 60: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 60

Removing an Absent Entry

a b d e

remove c

return false

Page 61: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 61

Correctness

• If– Entry b and Entry d both locked– Entry b still accessible– Entry d still successor to b

• Then– Neither will be deleted– No thread can add c after b– OK to return false

Page 62: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 62

Validationprivate booleanvalidate(Entry predEntry,

Entry currEntry) {Entry entry = head;while (entry.key <= predEntry.key) {if (entry == predEntry)return predEntry.next == currEntry;

entry = entry.next;}return false;

}

Page 63: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 63

Validationprivate booleanvalidate(Entry predEntry,

Entry currEntry) {Entry entry = head;while (entry.key <= predEntry.key) {if (entry == predEntry)return predEntry.next == currEntry;

entry = entry.next;}return false;

}

Predecessor & current entries

Page 64: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 64

Validationprivate booleanvalidate(Entry predEntry,

Entry currEntry) {Entry entry = head;while (entry.key <= predEntry.key) {if (entry == predEntry)return predEntry.next == currEntry;

entry = entry.next;}return false;

}Start at the

beginning

Page 65: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 65

Validationprivate booleanvalidate(Entry predEntry,

Entry currEntry) {Entry entry = head;while (entry.key <= predEntry.key) {if (entry == predEntry)return predEntry.next == currEntry;

entry = entry.next;}return false;

}Search range of keys

Page 66: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 66

Validationprivate booleanvalidate(Entry predEntry,

Entry currEntry) {Entry entry = head;while (entry.key <= predEntry.key) {if (entry == predEntry)return predEntry.next == currEntry;entry = entry.next;

}return false;

}Predecessor reachable

Page 67: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 67

Validationprivate booleanvalidate(Entry predEntry,

Entry currEntry) {Entry entry = head;while (entry.key <= predEntry.key) {if (entry == predEntry)return predEntry.next == currEntry;

entry = entry.next;}return false;

}Is current entry next?

Page 68: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 68

Validationprivate booleanvalidate(Entry predEntry,

Entry currEntry) {Entry entry = head;while (entry.key <= predEntry.key) {if (entry == predEntry)return predEntry.next == currEntry;

entry = entry.next;}return false;

}

Otherwise move on

Page 69: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 69

Validationprivate booleanvalidate(Entry predEntry,

Entry currEntry) {Entry entry = head;while (entry.key <= predEntry.key) {if (entry == predEntry)return predEntry.next == currEntry;

entry = entry.next;}return false;

}

Predecessor not reachable

Page 70: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 70

Remove: searchingpublic boolean remove(Object object) {int key = object.hashCode();retry: while (true) {Entry predEntry = this.head;Entry currEntry = predEntry.next;while (currEntry.key <= key) {if (object == currEntry.object)break;

predEntry = currEntry;currEntry = currEntry.next;

} …

Page 71: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 71

Remove: searchingpublic boolean remove(Object object) {int key = object.hashCode();retry: while (true) {Entry prevEntry = this.head;Entry currEntry = prevEntry.next;while (currEntry.key <= key) {if (object == currEntry.object)break;

prevEntry = currEntry;currEntry = currEntry.next;

} … Search key

Page 72: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 72

Remove: searchingpublic boolean remove(Object object) {int key = object.hashCode();retry: while (true) {Entry prevEntry = this.head;Entry currEntry = prevEntry.next;while (currEntry.key <= key) {if (object == currEntry.object)break;

prevEntry = currEntry;currEntry = currEntry.next;

} … Retry on synchronization conflict

Page 73: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 73

Remove: searchingpublic boolean remove(Object object) {int key = object.hashCode();retry: while (true) {Entry predEntry = this.head;Entry currEntry = predEntry.next;while (currEntry.key <= key) {if (object == currEntry.object)break;

prevEntry = currEntry;currEntry = currEntry.next;

} …Examine predecessor and current entries

Page 74: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 74

Remove: searchingpublic boolean remove(Object object) {int key = object.hashCode();retry: while (true) {Entry prevEntry = this.head;Entry currEntry = prevEntry.next;while (currEntry.key <= key) {if (object == currEntry.object)break;

prevEntry = currEntry;currEntry = currEntry.next;

} … Search by key

Page 75: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 75

Remove: searchingpublic boolean remove(Object object) {int key = object.hashCode();retry: while (true) {Entry prevEntry = this.head;Entry currEntry = prevEntry.next;while (currEntry.key <= key) {if (object == currEntry.object)break;

prevEntry = currEntry;currEntry = currEntry.next;

} … Stop if we find object

Page 76: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 76

Remove: searchingpublic boolean remove(Object object) {int key = object.hashCode();retry: while (true) {Entry prevEntry = this.head;Entry currEntry = prevEntry.next;while (currEntry.key <= key) {if (object == currEntry.object)break;

predEntry = currEntry;currEntry = currEntry.next;

} …

Move along

Page 77: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 77

On Exit from Loop

• If object is present– currEntry holds object– predEntry just before currEntry

• If object is absent– currEntry has first higher key– predEntry just before currEntry

• Assuming no synchronization problems

Page 78: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 78

Remove Methodtry {

predEntry.lock(); currEntry.lock();if (validate(predEntry,currEntry) {if (currEntry.object == object) {predEntry.next = currEntry.next;return true;} else {return false;}}} finally {predEntry.unlock();currEntry.unlock();

}}}

Page 79: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 79

Remove Methodtry {

predEntry.lock(); currEntry.lock();if (validate(predEntry,currEntry) {if (currEntry.object == object) {predEntry.next = currEntry.next;return true;} else {return false;}}} finally {predEntry.unlock();currEntry.unlock();

}}}

Always unlock

Page 80: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 80

Remove Methodtry {

predEntry.lock(); currEntry.lock();if (validate(predEntry,currEntry) {if (currEntry.object == object) {predEntry.next = currEntry.next;return true;} else {return false;}}} finally {predEntry.unlock();currEntry.unlock();

}}}

Lock both entries

Page 81: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 81

Remove Methodtry {

predEntry.lock(); currEntry.lock();if (validate(predEntry,currEntry) {if (currEntry.object == object) {predEntry.next = currEntry.next;return true;} else {return false;}}} finally {predEntry.unlock();currEntry.unlock();

}}}

Check for synchronization conflicts

Page 82: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 82

Remove Methodtry {

predEntry.lock(); currEntry.lock();if (validate(predEntry,currEntry) {if (currEntry.object == object) {predEntry.next = currEntry.next;return true;} else {return false;}}} finally {predEntry.unlock();currEntry.unlock();

}}}

Object found, remove entry

Page 83: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 83

Remove Methodtry {

predEntry.lock(); currEntry.lock();if (validate(predEntry,currEntry) {if (currEntry.object == object) {predEntry.next = currEntry.next;return true;} else {return false;}}} finally {predEntry.unlock();currEntry.unlock();

}}}

Object not found

Page 84: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 84

So Far, So Good

• Much less lock acquisition/release– Performance– Concurrency

• Problems– Need to traverse list twice– contains() method acquires locks

• Most common method call

Page 85: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 85

Marked Lists

• Remove Method– Scans list (as before)– Locks predecessor & current (as before)– Marks current entry as removed (new!)– Redirects predecessor’s next (as before)

Page 86: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 86

Marked Lists

• All Methods– Scan list – Do not scan past marked entry– Instead, start over from list head

Page 87: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 87

Business as Usual

a b c d

Page 88: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 88

Interference

a b c d

Remove c

Page 89: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 89

Interference

a b c d

Uh-ohRemove

cmark

Page 90: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 90

Interference

a b c d

markUh-oh

Page 91: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 91

Marking a Node

• AtomicMarkableReference class– Java.util.concurrent.atomic package

address F

mark bit

Reference (31 bits)

Page 92: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 92

Extracting Information

Public Object get(boolean[]);

Page 93: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 93

Extracting Information

Public Object get(boolean[]);

Returns reference

Stores mark at index 0

Page 94: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 94

Extracting Information

public boolean isMarked();

Value of mark

Page 95: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 95

Changing State

Public boolean compareAndSet( Object expectedRef,Object updateRef,boolean expectedMark,boolean updateMark);

Page 96: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 96

Changing State

Public boolean compareAndSet(Object expectedRef,Object updateRef,boolean expectedMark,boolean updateMark);

If this is the current reference …

And this is the current mark …

Page 97: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 97

Changing State

Public boolean compareAndSet( Object expectedRef,Object updateRef,boolean expectedMark,boolean updateMark);

…then change to this new reference …

… and this new mark

Page 98: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 98

Changing State

public boolean attemptMark( Object expectedRef,boolean updateMark);

Page 99: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 99

Changing State

public boolean attemptMark(Object expectedRef,boolean updateMark);

If this is the current reference …

Page 100: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 100

Changing State

public boolean attemptMark( Object expectedRef,boolean updateMark);

.. then change to this new mark.

Page 101: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 101

Aside

• We will see that it is often useful to tag pointers with– Boolean values– Integer values

• Sometimes to mark, and sometimes to ensure pointers are unique

Page 102: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 102

List Validate Methodprivate booleanvalidate(Entry predEntry,

Entry currEntry) {return(!predEntry.next.isMarked()) && (!currEntry.next.isMarked()) && (predEntry.next.getReference()== currEntry);

}

Page 103: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 103

List Validate Methodprivate booleanvalidate(Entry predEntry,

Entry currEntry) {return(!predEntry.next.isMarked()) && (!currEntry.next.isMarked()) && (predEntry.next.getReference()== currEntry);

}

Predecessor not removed

Page 104: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 104

List Validate Methodprivate booleanvalidate(Entry predEntry,

Entry currEntry) {return (!predEntry.next.isMarked()) &&(!currEntry.next.isMarked()) && (predEntry.next.getReference()== currEntry);

}

Current not removed

Page 105: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 105

List Validate Methodprivate booleanvalidate(Entry predEntry,

Entry currEntry) {return (!predEntry.next.isMarked()) && (!currEntry.next.isMarked()) &&(predEntry.next.getReference()== currEntry);

}

Next field unchanged

Page 106: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 106

Remove: searchingpublic boolean remove(Object object) {…while (currEntry.key <= key) {

Entry nextEntry = (Entry)currEntry.next.get(mark);

if (mark[0])continue retry;

if (object == currEntry.object)break;

predEntry = currEntry;currEntry = currEntry.next;

} …

Page 107: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 107

Remove: searchingpublic boolean remove(Object object) {…while (currEntry.key <= key) {

Entry nextEntry = (Entry)currEntry.next.get(mark);

if (mark[0])continue retry;

if (object == currEntry.object)break;

predEntry = currEntry;currEntry = currEntry.next;

} …

Atomically read reference & mark

Page 108: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 108

Remove: searchingpublic boolean remove(Object object) {…while (currEntry.key <= key) {

Entry nextEntry = (Entry)currEntry.next.get(mark);

if (mark[0])continue retry;

if (object == currEntry.object)break;

predEntry = currEntry;currEntry = currEntry.next;

} …

Panic if entry removed

Page 109: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 109

Evaluation

• Good:– Contains method doesn’t need to lock– Uncontended calls don’t re-traverse

• Bad– Contended calls do re-traverse– Traffic jam if one thread delays

Page 110: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 110

Traffic Jam

• Any concurrent data structure based on mutual exclusion has a weakness

• If one thread– Enters critical section– And “eats the big muffin” (stops running)

• Cache miss, page fault, descheduled …• Software error, …

– Everyone else using that lock is stuck!

Page 111: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 111

Lock-Free Data Structures

• No matter what …– Some thread will complete method call– Even if others halt at malicious times

• Implies that– You can’t use locks (why?)– Um, that’s why they call it lock-free

Page 112: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 112

Lock-Free ≠Wait-Free

• Wait-free synchronization– Every method call eventually finishes– What everyone really wants

• Lock-free synchronization– Some method call eventually finishes– What we are usually willing to pay for

• Starvation rare in practice …

Page 113: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 113

Lock-Free Lists

• Next logical step• Eliminate locking entirely• Use only compareAndSet()• Invented by Maged Michael, 2003

Page 114: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 114

Adding an Entry

a b c

b

CAS

Page 115: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 115

Removing an Entry

a b cCAS

Page 116: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 116

Removing an Entry

a b c d

remove b

remove c

CAS CAS

Page 117: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 117

Look Familiar?

a b c d

remove b

remove c

Page 118: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 118

Problem

• Method updates entry’s next field• After entry has been removed

Page 119: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 119

Solution

• Use AtomicMarkableReference• Remove in two steps

– Set mark bit in next field– Redirect predecessor’s pointer

• CAS– Fails if mark bit set (entry removed)

Page 120: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 120

Removing an Entry

a b c d

remove c

CAS

Page 121: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 121

Removing an Entry

a b d

remove b

remove c

cCASCAS

failed

Page 122: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 122

Removing an Entry

a b d

remove b

remove c

c

Page 123: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 123

Removing an Entry

a d

remove b

remove c

Page 124: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 124

Traversing the List

• Q: what do you do when you find a “logically” deleted entry in your path?

• A: finish the job.– CAS the predecessor’s next field– Proceed (repeat as needed)

Page 125: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 125

Lock-Free Traversal

a b c dCAS

Uh-oh

Page 126: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 126

The Find Method

pred,curr,next = find(object);

Page 127: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 127

The Find Method

pred,curr,succ = find(object);

At some instant,

pred curr succ

object or …

Page 128: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 128

The Find Method

pred,curr,succ = find(object);

At some instant,

predcurr= null

succ

object not in list

Page 129: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 129

Removepublic boolean remove(Object object) {while (true) {pred,curr,succ = find(object);if (curr == null)return false;

if (!curr.next.attemptMark(succ,true))

continue; pred.next.compareAndSet(curr, succ,

false,false);return true;}}

Page 130: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 130

Removepublic boolean remove(Object object) {while (true) {pred,curr,succ = find(object);if (curr == null)return false;

if (!curr.next.attemptMark(succ,true))

continue; pred.next.compareAndSet(curr, succ,

false,false);return true;}} Keep trying

Page 131: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 131

Removepublic boolean remove(Object object) {while (true) {pred,curr,succ = find(object);if (curr == null)return false;

if (!curr.next.attemptMark(succ,true))

continue; pred.next.compareAndSet(curr, succ,

false,false);return true;}} Find alleged neighbors

Page 132: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 132

Removepublic boolean remove(Object object) {while (true) {pred,curr,succ = find(object);if (curr == null)return false;

if (!curr.next.attemptMark(succ,true))

continue; pred.next.compareAndSet(curr, succ,

false,false);return true;}} She’s not there …

Page 133: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 133

Removepublic boolean remove(Object object) {while (true) {pred,curr,succ = find(object);if (curr == null)return false;

if (!curr.next.attemptMark(succ,true))

continue;pred.next.compareAndSet(curr, succ,

false,false);return true;}}

Try to mark entry as deleted

Page 134: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 134

Removepublic boolean remove(Object object) {while (true) {pred,curr,succ = find(object);if (curr == null)return false;

if (!curr.next.attemptMark(succ,true))

continue; pred.next.compareAndSet(curr, succ,

false,false);return true;}}

If it doesn’t work, just retry

Page 135: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 135

Removepublic boolean remove(Object object) {while (true) {pred,curr,succ = find(object);if (curr == null)return false;

if (!curr.next.attemptMark(succ,true))

continue; pred.next.compareAndSet(curr, succ,

false,false);return true;}}

If it works, our job is (essentially) done

Page 136: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 136

Removepublic boolean remove(Object object) {while (true) {pred,curr,succ = find(object);if (curr == null)return false;

if (!curr.next.attemptMark(succ,true))

continue; pred.next.compareAndSet(curr, succ,

false,false);return true;}}

Try to advance reference(if we don’t succeed, someone else did).

a

Page 137: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 137

Addpublic boolean add(Object object) {while (true) {pred,curr,succ= find(object);if (curr != null)return false;

Entry entry = new Entry(object);entry.next = new AMR(succ,false);if (pred.next.CAS(succ, entry,

false, false))return true;

}}

Page 138: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 138

Addpublic boolean add(Object object) {while (true) {pred,curr,succ= find(object);if (curr != null)return false;

Entry entry = new Entry(object);entry.next = new AMR(succ,false);if (pred.next.CAS(succ, entry,

false, false))return true;

}}

Object already there.

Page 139: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 139

Addpublic boolean add(Object object) {while (true) {pred,curr,succ= find(object);if (curr != null)return false;

Entry entry = new Entry(object);entry.next = new AMR(succ,false);if (pred.next.CAS(succ, entry,

false, false))return true;

}}create new entry

Page 140: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 140

Addpublic boolean add(Object object) {while (true) {pred,curr,succ= find(object);if (curr != null)return false;

Entry entry = new Entry(object);entry.next = new AMR(succ,false);if (pred.next.CAS(succ, entry,

false, false))return true;

}}

Install new entry

Page 141: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 141

Containspublic boolean contains(Object obj){while (true) {prev,curr,succ = find(object);return (curr != null);

}}

Page 142: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 142

Containspublic boolean contains(Object obj){while (true) {prev,curr,succ = find(object);return (curr != null);

}}

Did we find anything?

Page 143: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 143

Findprivate Entry,Entry,Entry

find(Object object) {Entry pred, curr, succ;boolean[] pmark = new boolean[1];boolean[] cmark = new boolean[1];int key = object.hashCode();tryAgain: while (true) {

…}}}

Page 144: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 144

Findprivate Entry,Entry,Entry

find(Object object) {Entry pred, curr, succ;boolean[] pmark = new boolean[1];boolean[] cmark = new boolean[1];int key = object.hashCode();tryAgain: while (true) {

…}}}

The entries we seek

Page 145: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 145

Findprivate Entry,Entry,Entry

find(Object object) {Entry pred, curr, succ;boolean[] pmark = new boolean[1];boolean[] cmark = new boolean[1];int key = object.hashCode();tryAgain: while (true) {

…}}}

Deleted bits for predand curr

Page 146: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 146

Findprivate Entry,Entry,Entry

find(Object object) {Entry pred, curr, succ;boolean[] pmark = new boolean[1];boolean[] cmark = new boolean[1];int key = object.hashCode();tryAgain: while (true) {

…}}}

If list changes while traversed, start over

Page 147: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 147

Findprivate Entry,Entry,Entry

find(Object object) {Entry pred, curr, succ;boolean[] pmark = new boolean[1];boolean[] cmark = new boolean[1];int key = object.hashCode();tryAgain: while (true) {

…}}}

Lock-Free because we start over only if someone else makes progress

Page 148: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 148

FindtryAgain: while (true) {

pred = this.head.getReference();curr = pred.next.get(pmark); while (true) {…

}}} Start with first two entries

Page 149: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 149

FindtryAgain: while (true) {

pred = this.head.getReference();curr = pred.next.get(pmark);while (true) {…

}}}

Move down the list

Page 150: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 150

Find…

while (true) {if (curr == null)return pred, null, succ;succ = curr.next.get(cmark); int ckey = curr.key;if (isChanged(pred.next))continue tryAgain;

}}}

Fell off the end of the list

Page 151: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 151

Find…

while (true) {if (curr == null)return pred, null, succ;succ = curr.next.get(cmark); int ckey = curr.key;if (isChanged(pred.next))continue tryAgain;

}}}

Get ref to successor and current deleted bit

Page 152: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 152

Find…

while (true) {if (curr == null)return pred, null, succ;succ = curr.next.get(cmark); int ckey = curr.key;if (isChanged(pred.next))continue tryAgain;

}}}

Panic if predecessor’s next field changed

Page 153: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 153

Findwhile (true) {…

if (!cmark[0]) {if (curr.object == object)return pred, curr, succ;

else if (ckey <= key) {pred = curr;

} elsereturn prev, null, curr;

} else {…

}}}

If current node is not deleted

Page 154: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 154

Findwhile (true) {…

if (!cmark[0]) {if (curr.object == object)return pred, curr, succ;

else if (ckey <= key) {pred = curr;

} elsereturn prev, null, curr;

} else {…

}}}

Object found

Page 155: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 155

Findwhile (true) {…

if (!cmark[0]) {if (curr.object == object)return pred, curr, succ;

else if (ckey <= key) {pred = curr;

} elsereturn prev, null, curr;

} else {…

}}}Keep looking

Page 156: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 156

Findwhile (true) {…

if (!cmark[0]) {if (curr.object == object)return pred, curr, succ;

else if (ckey <= key) {pred = curr;

} elsereturn prev, null, curr;

} else {…

}}}

Not there, give up

Page 157: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 157

Find…while (true) {…

if (!cmark[0]) {…

} else {if (pred.next.compareAndSet(curr, succ, false, false))continue;

elsecontinue tryAgain;

}

Current entry is logically deleted

Page 158: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 158

Find…while (true) {…

if (!cmark[0]) {…

} else {if (pred.next.compareAndSet(curr, succ, false, false))continue;

elsecontinue tryAgain;

}

Try to redirect predecessor’s next reference

Page 159: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 159

Find…while (true) {…

if (!cmark[0]) {…

} else {if (pred.next.compareAndSet(curr, succ, false, false))continue;

elsecontinue tryAgain;

}

On success, keep going, on failure, start over

Page 160: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 160

Summary

• Coarse-grained locking• Fine-grained locking• Optimistic syncrhronization• Lock-free synchronization

Page 161: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 161

Scratch

a

Page 162: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 162

Scratch

a

Page 163: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 163

Scratch

Page 164: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 164

Scratch

Page 165: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 165

Scratch

Page 166: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 166

Scratch

Page 167: Linked Lists: Locking, Lock- Free, and Beyond · Lock and Load • To move to successor entry for e –Lock e –Lock e.next –Unlock e • While traversing – e cannot be removed

© 2003 Herlihy & Shavit 167

Removing an Entry

a b cCAS