# Errata for

Document Sample

					                                         Errata for

The Art of Multiprocessor Programming
Version of 3 January 2011

In many places, inserted text is highlighted in red.

There are 5 new eps files to replace existing figures. Replace Figure 14.3 with
lazyskiplist-add.eps. Replace Figure 6.5 with lock-free-universal.eps. Replace Figure
10.12 with LockFreeQueue.eps. Replace Figure 15.3 with SimpleTree.eps. Replace
Figure 6.7 with wait-free-universal.eps.

Also, please completely remove Figure 16.8 on page 380 and remove the sentence “Fig.
16.8 shows such a sub-DAG.” In the 5th line from the bottom on page 379.

p. xvi        add item after Bibliography (note page number)
Suggested Ways to Teach                                                                     494

Preface
p. xvii Pearlman -> Perlman
p. xx “all of which are useful in structuring concurrent applications.”

Chapter 1
P3        Include few words => include a few words
P. 3      references the end -> references at the end
P3: “The hope is that the reader will understand the issues in a way that will later allow
him or her to apply the lessons learned to specific multiprocessor systems.”
P3: line 25: the end -> at the end
p. 3      In Section 1.1 in place of "there are many primes between 1 and 109, but hardly
any between 9x109 and 1010" should say "there are more primes between 1 and
109 than between 9x109 and 1010"
p. 4      In Fig. 1.1, line 4 should say
for (int j = (i * block) + 1; j <= (i + 1)* block;
j++) {
p. 5      Fig.1.3 add 2 more spaces at the start of line 6
p. 11     Second paragraph of Mutual Exclusion bullet: “Initially the can is either up or
down. Let us say it was down. Then only the pets can go in, and mutual
exclusion holds.”
p. 18     Replace question 6 with:
Use Amdahl’s law to answer the following questions:
 Suppose the sequential part of a program accounts for 40% of the
program's execution time on a single processor. Find a limit for the
overall speedup that can be achieved by running the program on a
multiprocessor machine.
 Now suppose the sequential part accounts for 30% of the program's
computation time. Let sn be the program's speedup on n processes,
assuming the rest of the program is perfectly parallelizable. Your boss
tells you to double this speedup: the revised program should have
speedup s'n > sn/2. You advertize for a programmer to replace the
sequential part with an improved version that runs k times faster. What
value of k should you require?
 Suppose the sequential part can be sped up three-fold, and when we do
so, the modified program takes half the time of the original on n
processors. What fraction of the overall execution time did the sequential
part account for? Express your answer as a function of n.
P 22      Change “… threads typically” to “…. Threads typically”

Chapter 2
p. 23   Figure 2.3 should be amended as shown:
public long getAndIncrement() {
lock.lock();
try {
long temp = value;
value = temp + 1;
return temp;
} finally {
lock.unlock();
}
}
P 24    “some thread make” => “some thread makes”
p. 25   Pragma 2.3.1: “We explain the reasons in Chapter 3 and Appendix B.”
P24: change in line 3-4 to: “Let us assume, for simplicity, that each thread repeatedly
acquires and releases the lock, with other work taking place in the meantime.”
P25: after "Pragma 2.3.1" replace “read A(v == x)” by “read A(x == v)”.
p. 26   In Fig. 2.5, remove the word "volatile" from line 2.

p. 35   Change

“Suppose A’s token is on Node 0, and B’s token on Node 1 (so A has the later
timestamp). For A, the label() method is trivial: it already has the latest
timestamp, so it does nothing. For B, the label() method “leapfrogs” A’s node by
jumping from 0 to 2.”

to

“Suppose A’s token is on Node 0, and B’s token on Node 1 (so B has the later
timestamp). For B, the label() method is trivial: it already has the latest
timestamp, so it does nothing. For A, the label() method “leapfrogs” B’s node by
jumping from 0 to 2.”
p. 27    In Fig. 2.6, remove the word "volatile" in lines 3 and 4
p. 27    “if one thread runs completely before the other” -> “if one thread never tries to
get the lock”
p. 29    Fig 2.7 line 13 “level 1” => “level i”
p.43     Fig 2.17 add the following line between 6 & 7
… // initialize myIndex
p. 44    Exercise 19. Instead of 3n should be O(3n) and instead of n2n should say O(n2n).
p. 48    Fig 3.3 delete line 6
P 48     Line 4 of Fig 3.3: add space “(T[])new” => “(T[]) new”

Chapter 3
p. 54.   First paragraph: “We use the following shorthand: <p.enq(x) A> -> <p.deq(x)
B> means that any sequential execution must order A's enqueue of x at p before
B's dequeue of x at p, and so on.”

P 55     Empty Exception should be EmptyException
P.57     Top of page, “shorthand notion" should be "shorthand notation".
P 60     “the cost ... are” => “the cost ... is”
P. 61    "This method must be synchronized to ensure that only one instance is created,
even if several threads observe instance to be null create new instances."
Delete "create new instances".
p. 67    "... head is the index of the next slot from which to remove an item, and tail is
the index of the next slot in which to place an item."

Chapter 4
p.77     In the table of Figure 4.5 in the second line MRMW Boolean Regular should be
MRSW Boolean Regular.
p.84     In Fig.4.12, add a new line between 22 and 23 Line
if (i == me) continue;
In addition, Line 32 should be
a_table [ 0 ][ i ] = value;
p. 88    Should be “when B’s snapshot was taken before A started its Scan() call”.
p. 91    In Fig 4.21 Line 20 should be “return newCopy[j].snap;
p. 85    figure 4.13
"Thread 0 reads a_table[0][1] with value t+1."
Should be a_table[0][0]
P 87     linearizable to) -> linearizable) to
p. 88    2nd last line
"before A started its update() call" should be "... scan() call".
p. 90    In Fig 4.19 Line 11 should be “stamp = label;”
p. 94    In Exercise 40 “ Does Peterson’s two thread mutual exclusion algorithm work if
the shared atomic flag registers are replaced by regular registers”.
p. 95.   In Figure 4.23, the comment “N is the total number of threads”
is incorrect. N is actually the length of the register.
P95: “If multiple processors call write(), is this register atomic?” Replace
“atomic” with “safe.”
P95: “If multiple processors call write(), is this register atomic?” Replace
“atomic” with “safe.”

Chapter 5
P 100    “The reader will notice that since the decide() method of a given consensus
object is executed only once by each thread, and that there are a finite
number of threads, by definition, a lock-free implementation would also be
wait-free and vice versa.”
P101: remove the sentence: “A's moves are showed in black, and B's in gray.”
P104: Caption of figure 5.3: “In the second execution scenario, A moves first, driving
the protocol to a 0-valent state s’’. “ replace by: “In the second execution scenario, A
moves first, then B executes one operation, driving the protocol to a 0-valent state s’’.”
P 106    can provide -> can we provide
p. 108   for a threads A -> for a thread A
P110: “Exercise 72 asks one to justify this claim.”

p 111    figure 5.11, 3: “Assign23 assign2 = new Assign23(NULL)” should
be “Assign23 assign23 = new Assign23(NULL)”

p 111 figure 5.11, 5: [indentation should match line 6]
P114: Figure 5.14 line 5 need to add indentation before “propose(value)”.
p 115 figure 5.14, 5: [indentation]
P 117    provides a get() -> provide a get()
P117: replace “provides” by “provide” and “a get() method is only a convenience, and
as proved in a homework assignment.” By “a get() method is only a convenience, and
so it follows that:”
P119: In the text “We consider the compareAndSet() operation mentioned earlier, a
synchronization operation supported by several contemporary architectures. (For example, it
is called CMPXCHG on the Intel PentiumTM). This method is also known in the literature
as compare-and-swap. compareAndSet() takes two arguments: an expected value and an
update value.”
Remove “mentioned earlier” and replace “As noted earlier, compareAndset() takes…” by
“A compareAndSet() takes…”
P119: and P120 exercise 59 should read: “The SetAgree class, like the Consensus class,
provides a decide() method whose call returns a value that was the input of some
thread’s decide() call. However, unlike the Consensus class, the values returned by
decide() calls are not required to agree. Instead, these calls may return no more than k
distinct values. (When k is 1, SetAgree is the same as consensus.) What is the consensus
number of the SetAgree class when k >1?”
p 121.   In Exercise 65, Replace “provides the same propose() and decide() method as
consensus” by “provides the same decide() method as consensus”.

Chapter 6
P 127  figure 6.2
"Invocation" should be "Invoc".
p. 128 figure 6.4 line 21 "current" should be "Node current".
P129: Figure 6.5 file named lock-free-universal.pdf seems that somehow the fonts for
the words “next”, “decideNext”, “seq” and “invoc()” are in boldface even though they
should be the same as for the word “sentinel.”
P132: (PRINTERS TYPO, appears OK in galley proof file Ch06-P370591 but
not in printed book) “The value of before.seq 1 mod n+” should be “The value of
before.seq + 1 mod n”
P132 and P133: Changes in red “Now imagine that Thread 3 immediately
announces its node. Then Thread 7 helps to append Thread 3’s node, but again pauses
immediately after setting Thread 3’s node’s sequence number to 3, but before adding it
to head[]. Now Thread 3 wakes up. It will not enter the main loop because its node’s
sequence number is non zero…”
P 131    figure 6.6 line 23 "current" should be "Node current".
p 131    In Figure 6.6 line 12
Node help = announce[(before.seq + 1) % n];
p 131    In Figure 6.6 line 17
Node after = before.decideNext.decide(prefer);
P132: Figure 6.7 caption: similar changes as in text, thread numbers in red
“Notice that Thread 5’s own entry in the head[] array is not yet set to its
announced node. Next, Thread 3 announces its node and
Thread 7 helps to append Thread 3’s node, setting Thread 3’s node’s sequence
number
to 3. Now Thread 3 wakes up. It will not enter the main loop because its node’s
sequence number is non zero….”

p 134  In Figure 6.8 line 12
Node help = announce[(before.seq + 1) % n];
p. 134 figure 6.8 line 23 "current" should be "Node current".
p 134 In Figure 6.8 line 17
Node after = before.decideNext.decide(prefer);
p 137    “Exercise 77. Propose a way to fix the universal construction of Figure 6.8 to
work for objects with nondeterministic sequential specifications.”
Exercise 82 first line: "made to the lock-free protocol" should be "made to the
wait-free protocol"

P 135 announced). thread C => announced). Thread C
p. 132 The value of before.seq 1 mod n+" => "The value of (before.seq + 1) mod n”

Chapter 7
p.146    first line of section: "simple TTASLock" should be "TASLock"
p. 148   In Figure7.5 Line 7 should be:
maxDelay = max;
P149      line -8: the the -> the
p. 153   Fig. 7.9 omit line 6
P153: Fig. 7.9 line 2 should be “2 AtomicReference<Qnode> tail;
p. 149   the the critical section => the critical section
P. 151   Replace “shows the CLHLock class's fields, constructor, and QNode class” with “shows
the CLHLock class's fields and constructor”
P 151    its its own => its own
p. 155   Fig. 7.12 replace “queue” in line 5 with “tail”
p. 155   Fig 7.13, change line 33 to
// wait until successor fills in the next field
p. 157    First paragraph of Section 7.6, the reference to Pragma 8.2.3 should be to Pragma 8.2.2.
p. 157    “field is null, the associated thread has either not acquired the lock or has released it”
should be “field is null, the associated thread has either not acquired the lock or has not
released it yet”

p. 161    Enqueues that node in the queue (Line 12) => Enqueues that node in the queue (Line 8)
p. 162    In Fig. 7.21, Line 6 is redundant and can be omitted.
p. 163    In Fig. 7.23, remove Line 4.
p. 165    “the thread-local myPred field” =>“the thread-local myNode field”
p. 165    “node from myPred” =>“node from myNode”
p .174    Exercise 86 should be: (may require rewrap through page 176, please advise)
First barrier implementation: We have a counter protected by a test-and-test-and-
set lock. Each thread locks the counter, increments it, releases the lock, and spins,
rereading the counter until it reaches n

Second barrier implementation: We have an n-element array b, all 0. Thread zero
sets b[0] to 1. Every thread i, for 0 < i <= n-1, spins until b[i-1] is 1, sets b[i] to 1,
and waits until b[i+1] becomes 2, at which point it proceeds to leave the barrier.
Thread b[n-1], upon detecting that b[n-1] is 1, sets b[n-1] to 2 and leaves the
barrier.

Compare (in ten lines) the behavior of these two implementations on a bus-based
cache-coherent architecture. Explain which approach you expect will perform
better under low load and high load.
p. 175    In Exercise 86, “Second barrier implementation: We have an n-element boolean array b,
all false. Thread zero sets b[0] to true. Every thread i, for 0 < i <= n, spins until b[i-1]
is true, sets b[i] to true, and waits until b[n-1] is true”
p. 175    In Exercise 89, Remove “Notice that” and begin with “In the HCLHLock lock…”.
p. 175    Fig 7.33 replace Line 3 with
AtomicReference<Qnode> tail = new Qnode();
p. 176    Exercise 91: “whether any thread is holding a lock (but does not actually acquire the
lock)”

Chapter 8
p. 181 In the caption for Fig. 8.4, change

However, thread D manages to acquire the critical section lock first,
and so both A and B spin until C leaves the critical section.

to
However, thread D manages to acquire the critical section lock first,
and so both A and B spin until D leaves the critical section.

p 182     The constructor for LockedQueue should be:
public LockedQueue(int capacity) {
items = (T[])new Object[capacity];
}
p.185   In Figure 8.9, line 48 should be:
while (readers > 0 || writer) {

P185: instead of “both synchronize on the mutex and condition fields” should be
“both synchronize on the lock and condition fields”

p.186. Figure 8.11 should be:
private class ReadLock implements Lock {
public void lock() {
lock.lock();
try {
while (writer) {
condition.await();
}
} finally {
lock.unlock();
}
}
public void unlock() {
lock.lock();
try {
condition.signalAll();
} finally {
lock.unlock();
}
}
}
Figure 8.12 should be
private class WriteLock implements Lock {
public void lock() {
lock.lock();
try {
while (writer) {
condition.await();
}
writer = true;
condition.await();
}
} finally {
lock.unlock();
}
}
public void unlock() {
writer = false;
condition.signalAll();
}
}
P 188    Fig 8.13 replace lines 11-23 with
public void lock() {
int me = ThreadID.get();
lock.lock();
try {
if (owner == me) {
holdCount++;
return;
}
while (holdCount != 0) {
condition.await();
}
owner = me;
holdCount = 1;
} finally {
lock.unlock();
}
}
P 189    Line 2-3: initialize => initialize

P196:    Heading 9.2, Line 3: “Node<T> class has three fields. The item…”
change to:
“Node<T> class has three fields. \footnote{To be consistent with the Java
memory model these fields and their modifications later in the text will need to
be volatile, though we ignore this issue here for the sake of brevity.} The item…”
[If a footnote will fit, please renumber remaining footnotes. If easier to add a
side-note to avoid rewrap and renumbering, please set that in a box in the left
margin]
P 197    any any ordered set => any ordered set

Chapter 9
p 204    last line: "harder than in the course-grained" should be "coarse".
P 207    Fig. 9.13, lines 52,53 change

Entry pred = this.head; // sentinel node;
Entry curr = pred.next;

to

Node pred = this.head; // sentinel node;
Node curr = pred.next;
}
p. 209   nodes has been -> node has been
P211     First graph Change
(Figs. 9.16 and 9.17) to (Figs 9.17 and 9.18)
(Fig. 9.18) to (Fig. 9.16)
"as Fig. 9.19 shows" to ""as Fig. 9.20 shows"
P212     Change "the contains method (Fig. 9.20)" to the contains method (Fig. 9.19)"
p. 213. [Can the following be done with rewrap up to page 221-222?]
Heading 9.8, starting line 7:
Replace:
Fig. 9.22 shows a Thread A attempting to add node a between nodes
predA and currA. It sets a’s next field to currA, and then calls
compareAndSet() to set predA’s next field to a. If B wants to remove
currB from the list, it might call CompareAndSet() to set predB’s next
field to currB’s successor. It is not hard to see that if these two threads
try to remove these adjacent nodes concurrently, the list would end up
with b not being removed. A similar situation for a pair of concurrent
add() and remove() methods is depicted in the upper part of Fig. 9.22.
with:
In Fig. 9.22, part (a) shows a Thread A attempting to remove node node
a while Thread B is adding a node b. Suppose A applies
compareAndSet() to head.next, while B applies compareAndSet() to
a.next. The net effect is that a is correctly deleted but b is not added to
the list. In part (b) of the figure, Thread A attempts to remove a, the first
node in the list, while B is about to remove b, where a points to b.
Suppose A applies compareAndSet() to head.next, while B applies
compareAndSet() to a.next. The net effect is to remove a, but not b.

If B wants to remove currB from the list, it might call compareAndSet()
to set predB’s next field to currB’s successor. It is not hard to see that if
these two threads try to remove these adjacent nodes concurrently, the
list would end up with b not being removed. A similar situation for a pair
of concurrent add() and remove() methods is depicted in the upper part
of Fig. 9.22.
p.201.   Last paragraph: “except for the initial head sentinel node, acquire the lock for a
node only while holding the lock for its predecessor”
p. 204   [near bottom of page]
Replace
"The same distinctions apply to remove(a) calls. A successful call (a present)
is linearized when the predecessor node is locked (Lines 36 or 42). A
successful call (a absent) is linearized when the node containing the next
higher key is locked (Lines 36 or 42). An unsuccessful call (a present) is
linearized when the node containing a is locked."

With:

"The same distinctions apply to remove(a) calls. A successful call (a present)
is linearized when the predecessor node is locked (Lines 36 or 42). An
unsuccessful call (a absent) is linearized when the node containing the next
higher key is locked (Lines 36 or 42)." [delete last sentence in this paragraph]
p210: Figure 9.18 the indentation starting in line 9 is off, pred.lock should be
appropriately aligned with the w of the while in line 6 and next lines aligned
accordingly.
p211: Remove the paragraph starting with “Logical removals require a small…” and
ending with “even if its predecessor is logically or physically deleted.”
p214: Figure 9.22: The LazyList class -> Figure 9.22: The LockFreeList class
p218: 40 curr = curr.next -> 40 curr = curr.next.getReference()
is the almost the same
again as when -> again when
p219: The Lock-free

P 206    Fig. 9.11 change line 6 from
while (curr.key <= key) {
to
while (curr.key < key) {
p.204    Figure 9.9 caption: Because A must lock both head and a, and B must lock
both a and b, they are guaranteed to conflict on a, forcing one call to wait for the
other.''
p.217    In Line 16 "calls attemptMark() to mark currA as logically removed (Line 27)"
should be "uses a compareAndSet() to attempt to mark currA as logically
removed (Line 27)".
p.217    In Line 20 "If the attemptMark() call fails, remove() starts over." should be
replaced by "If the compareAndSet() call fails, remove() starts over."
p. 218   In Figure 9.26, Line 27, replace "27 snip = curr.next.attemptMark(succ,true);"
by "27 snip = curr.next.compareAndSet(succ, succ, false, true);"
p218, Fig 9.27, line 36: false{} -> false
p. 221   In Exercise 118 “Explain why the following cannot happen…”
p. 217   "It then calls compareAndSet() (Line 10)" => "It then calls compareAndSet()
(Line 11)"
p.216    paragraph 1 line 4. "The Window class's find() method” => "The find() method”
p. 225   Fig 10.2 replace line 5 with
p. 226   Fig 10.3, replace line 24 with
tail.next = tail; tail = e;
Fig. 10.4, line 48 replace “size.getAndincrement()” with
“size.getAndDecerement();”
p. 227   Line 3, Replace “notify waiting enqueuers” with “notify waiting dequeuers”
P. 227   Fig 10.5 replace 66 with
public volatile Node next;

Chapter 10
p. 224 Paragraph 4: “Pools provide different fairness guarantees. They can be first-in-
first-out (a queue), last-in-first-out (a stack),”
p. 226 Figure 10.4 should be
public T deq() {
T result;
boolean mustWakeEnqueuers = false;
deqLock.lock();
try {
while (size.get() == 0)
notEmptyCondition.await();
if (size.getAndDecrement() == capacity) {
mustWakeEnqueuers = true;
}
} finally {
deqLock.unlock();
}
if (mustWakeEnqueuers) {
enqLock.lock();
try {
notFullCondition.signalAll();
} finally {
enqLock.unlock();
}
}
return result;
}
Fig. 10.3, line 24 should be replaced by:
tail.next = e;
tail = tail.next;
P.226    Fig. 10.3 Replace “tail.next = tail = e ;” with “tail = e; tail.next = e;”
p. 227   “The deq() method proceeds as follows. It reads the size field to check whether
the queue is empty. If so, the dequeuer must wait until an item is enqueued.”
p. 228   Paragraph 2: “The dequeuer then decrements size and releases deqLock.”
p229: 2nd line: decremented by deq() -> incremented by enq()
3rd line: incremented by enq() -> decremented by deq().
Change the line that says: “When the field reaches capacity, the threadlocks
deqLock and adds deqSize to EnqSize.” To say: “When the field reaches
capacity, the thread …
adds deqSize to EnqSize, and resets deqSideSize to 0.
p230, Fig 10.10: if possible add a line 25 with another closing bracket “}” but if
it’s a problem with layout not crucial
p. 232   In Figure 10.12 “CAS tail” on the right side should be “CAS head.”
p232:    "help"other
p. 233   Last line of 1st graph: “linearized at Line 33” => “linearized at Line 32”
p. 234   In Fig. 10.14, “Threads B and C: enq a, c, and d.”
p. 236   In Fig. 10.15 replace “AtomicReference<T> class” with
“AtomicStampedReference<T> class”
p. 236   figure 10.16
delete Line 5.
p237: the enqueuer then sets -> the enqueuer sets

Chapter 11
p. 246 In paragraph 1, “at which point push()” should be “at which
point pop()”
p. 246 In Figure 11.1 part (b) the dashed line emanating from top
should be solid and the solid line directed from top to A should
be dashed (dashed lines symbolize past states).
p247: “the throwing of the exception” -> “in Line 3”

p249: line 2, top of page, "If if fails" should be "If it fails"
p250: figure 11.6 between lines 30 and 31 need to insert a “}”
(create new line 31 consisting of "}" set two characters to the left
of the start of line 30). Then increase current lines 31-43
numbering by 1 each)
p255: EliminationArray [118] -> EliminationArray [120]

p. 251 “The waiting thread will consume the item and reset the state to
EMPTY. Resetting to EMPTY can be done using a simple write”
p. 255 The LockFreeStack is credited to Treiber [145]. The
EliminationBackoffStack is due to Danny Hendler, Nir Shavit,
and Lena Yerushalmi.
p254: line 21: calls). -> calls.

Chapter 12
p. 259     “Interestingly, for some data structures based on distributed coordination, high
throughput does not necessarily mean low latency.”
p. 264     5 lines from the top, “Fig. 12.6” should be “in Part (a) of Fig. 12.3”
p. 261     Add the following first element to the list at the bottom of the page:
IDLE: This node is not in use.
P 262      Replace “we create a width w=2p array of CNode objects.” with “we create a
size w \geq p/2 array of CNode objects.”
p. 264     “In Line 20, the thread waits until the locked field is false”
p.264      "For example, Fig 12.6 shows a precombining phase example."
should be "Fig 12.3".
p. 272     figure 12.11
"token number 3 enters on wire 2, goes down to wire 1, and ends up on wire 3"
should be “token number 3 enters on wire 2, goes down to wire 3, and ends up
on wire 2”

p. 273     In caption of Figure 12.12 Caption first sentence should read “as depicted in
Fig. 12.11”. In next sentence “The gray Merger[4] network has as inputs the
even wires coming out of the top Bitonic[4] network, and the odd ones
from the lower Bitonic[4] network.”

P274       change
layer[] is an array of width balancers implementing the final network layer.
The Layer[] array is initialized so that layer[i] and layer[width-i-1] refer to the
same balancer.

to

layer[] is an array of width/2 balancers implementing the final network layer.
[omit second sentence]
p. 275   Delete sentence
“The merger[] array is initialized to a Merger network of full width.”
p. 275   In Fig. 12.15, the traverse method is missing a line at the end:
return (2 * output) + layer[output].traverse();

p.275    figure 12.14
"Boolean" should be "boolean".
"traverse(t)" should be "traverse()".
p. 276   In Fig. 12.16, replace Line 17 with:
return merger.traverse((input >= (size / 2) ?
(size / 2) : 0) + output);
}

p282: “assume inductively that a quiescent Tree[k]”
P. 292   8 lines from the bottom of the page, “Beng-Hong Lim et al.” should be
“Maurice Herlihy, Beng-Hong Lim, and Nir Shavit”

Chapter 13

p.302     Change Lines 27 and 28 from

setSize = result ? setSize + 1 : setSize ;

to
int myBucket = Math.abs(x.hashCode() % table.length);
if (! table[myBucket].contains(x)) {
result = true ;
size++ ;
}

p312: four lines from bottom “if it it exists”
p317: and 25, and -> and 23, and

P 313     Fig 3.14 line 2 should be
static final int HI_MASK = 0x80000000;
p. 313    Figure 13.15 line 22 should be omitted;
p. 314    Fig. 13.16 delete lines 41-42
p. 315    Change “InitialBucket()” to “InitializeBucket()” in the following:

Fig.13.19 shows the InitialBucket() method,

InitialBucket() is applied recursively to the parent

The InitialBucket() method may need to recursively initialize
P 317     Fig 13.22 caption: taken by the values 23 and 25 => taken by the values 3
and 23
p. 317    Fig. 13.21 should be
public boolean add(T x) {
if (contains(x)) {
return false;
}
for (int i = 0; i < LIMIT; i++) {
if ((x = swap(0, hash0(x), x)) == null) {
return true;
} else if ((x = swap(1, hash1(x), x)) == null) {
return true;
}
}
resize();
}
The caption to Fig. 13.22 should say:
A sequence of displacements started when an item with key 14 finds
both locations Table[0][h0 (14)] and Table[1][h1(14)] taken by the
values} 3 and 25, …

p. 319    In caption for Figure 13.24: “… and Table[1][2] below threshold…”
p. 324    “One difference is that the locks[] array has two dimensions.”

Chapter 14
p. 331. Last paragraph: “as in the LazyList class…”
p. 332 Figure 14.3 (b) is wrong. Correct figure is included.
p. 335 “… must become unmarked and fully linked before it can become marked
(see Fig. 14.7).”
p. 337. In Figure 14.7, Line 102 should be
if (ismarked ||
p. 340 In caption of Figure 14.9: “Part (b) shows the result of redirecting the dashed
p. 343 In Figure 14.11, Line 53 is redundant and can be omitted.
p. 344    In Figure 14.12, Line 87, replace
“ nodeToRemove.next[level].attemptMark(succ, true);”
with
“nodeToRemove.next[level].compareAndSet(succ, succ,
false, true);”
p. 345    Lines 4 and 5 should end with "applying a compareAndSet()" instead
of "applying attemptMark()"
p. 345    Each mention of victim should be nodeToRemove.
p. 347    Figure 14.14, Line 145 should read:
curr = curr.next[ level ]. getReference();
p.353     In Figure 15.3, deleteMin() should be removeMin() in 3 places. *
figure 15.3 section (d): Third box from left, delete "a" (see SimpleTree.eps)
p. 359. In Figure 15.9 between lines 32 and line 33 add line
… // other methods omitted

Chapter 15
p. 361 Fig 15.11, lines 77,78, replace

heap[bottom].lock();
heap[ROOT].lock();
with
heap[ROOT].lock();
heap[bottom].lock();
Fig 15.11, add the following line between 88 and 89
heap[ROOT].tag = Status.AVAILABLE;
Fig 15.11, line 108

replace
if (heap[child].score < heap[parent].score {
with
if (heap[child].score < heap[parent].score
&& heap[child].tag != Status.EMPTY) {

p.353     “If the bins are linearizable, so is SimpleLinear” should say “If the bins are
quiescently consistent, so is SimpleLinear.”
p.353     In Figure 15.3, “deleteMin()” should be “removeMin()” in 3 places.
p.362     Fig 15.12 (c). Node with the value 10 occurs twice, while node 7 is absent.
p.364     The bottom 10 should be 7 instead (the state before the two swaps).
In Fig 15.13, drop the curly brackets in Lines 19 and 24, so the lines will read
If (!curr.marked.get()) {
if(curr.marked.compareAndSet(false,true))
return curr;
}
else {
curr=curr.next[0].getReference();
}

p364: new code for the findAndMarkMin procedure in lines 14-27

public Node<T> findAndMarkMin() {
Node<T> curr = null;
while (curr != tail) {
if (!curr.marked.get()) {
if (curr.marked.compareAndSet(false, true)) {
return curr;
} else {
curr = curr.next[0].getReference();
}
}
}
return null; // no unmarked nodes
}

Chapter 16
p369: a_{ki}\cdot b_{jk} -> a_{ik}\cdot b_{kj}
p. 370 In Fig 16.1, line 5. ymA should be myA
p. 372 Last paragraph, “Line 19” should be “Line 20 of Fig. 16.4”.
p.374 Replace
53    for (int i = 0; i < 2; i++)
54          for (int j = 0; j < 2; j++) {
55                future[i][j][0] =
56                      exec.submit(new MulTask(aa[i][0], bb[0][i], ll[i][j]));
57                future[i][j][1] =
58                      exec.submit(new MulTask(aa[1][i], bb[i][1], rr[i][j]));
59          }
With
53    for (int i = 0; i < 2; i++)
54          for (int j = 0; j < 2; j++) {
55                future[i][j][0] =
56                      exec.submit(new MulTask(aa[i][0], bb[0][j], ll[i][j]));
57                future[i][j][1] =
58                      exec.submit(new MulTask(aa[i][1], bb[1][j], rr[i][j]));
59          }

p375, Fig 16.6, l8: arg > 2 -> arg >= 2
p376, Fig 16.7 and p380, Fig 16.8: two of the fib(1) boxes should be named
fib(0)
p. 382 In Fig 16.9, remove line 3
p. 383 In Fig. 16.10, The isEmpty() method should be:
boolean isEmpty() {
int localTop = top.getReference();
int localBottom = bottom;
return localBottom <= localTop;
}

p384: removed a task that is already complete -> stolen a task that has already
been completed, and removed a task that will never be completed
p385, Fig 16.12: should the array not extend to place 0?
[Please add one gray box on top of the stack, left of 0, in both (a) and (b)]
p386: line 9-10: and the task has been claimed -> and the task has been
claimed by the caller
p386, line 12: the the caller
p386, line 14: only rarely when -> only rarely, when (insert comma where
indicated)

p. 384 In Figure 16.11 between lines 27 and 28 add a new line with “bottom = 0;”
p. 386 Paragraph 4 should reference corrected Fig. 16.10 (above).
“On the other hand if bottom is greater than top”
p. 387 2nd paragraph
"The CircularTaskArray() class" should be "The CircularArray class".
P388      Fig 16.14 line 5 Change
AtomicReference<Integer> top;;
to
AtomicInteger top;

Line 8 change
top = new AtomicReference<Integer>(0);
to
top = new AtomicInteger(0);

Fig 16.14 delete line 20

P389     Fig 16.15 delete line 5, in line 5 of first paragraph topfield should be top field.
p391: that that other threads
p. 393 Exercise 186: “optimized version with T’1 = 1024 seconds, and T’ = 8 seconds.
Why is it optimized? When you run it on your 32-processor machine, the
running time is 40 seconds, as predicted by our formula.”
p395: “two work queues: first, lock the smaller queue, then lock the larger
queue, and…”

Chapter 17
p. 398   Last paragraph: “This barrier class may look like it works, but it does not.”
p. 399   First paragraph: “Unfortunately, the attempt to make the barrier reusable causes
it to break”
Line 13 of figure 17.3 should be
while (count.get() != 0){};
p399: balancer's sense field -> barrier's sense field
p401: $n=r^d$ threads -> $n=r^{d+1}$ threads
p402: in the last two barriers -> in the last barrier
p. 400   Delete Figure 17.5, and change reference to 17.5 in Pragma to 17.4
P406     “The barrier encompasses an AtomicInteger initialized to n, the number of
threads.” => “The barrier encompasses an AtomicInteger initialized to 0.”
“Each thread that becomes active increments the counter (Line 8) and each
thread that becomes inactive decrements it (Line 10).”

P407     Fig 17.13 change lines 7-11 to
if (active) {
count.getAndIncrement();
} else {
count.getAndDecrement();
}

P 411    Exercise 203 should refer to Fig. 17.18

Chapter 18
p. 422   Figs 18.6 and 18.7 are switched with respect to the text.
P 422    “enq(x) call that enqueues that item to another queue q0”
should be
“enq(x) call that enqueues that item to another queue q1”
p422: in last two paragraphs, “Fig 18.6 shows…” should be “Fig. 18.7 shows…”
and then “Fig. 18.7 shows” should be “Fig. 18.6 shows…”.
p422: “another queue q0” should be “another queue q1”.
p423, Fig 18.7, line 3: q1.deq(x) should be q1.enq(x)
p424: walking though
p424: search first though

p. 423   figure 18.7 line 3
"q1.deq(x)" should be "q1.enq(x)".
p. 428   “The doIt() method (line 5 of Figure 18.12) takes…”

p. 428   “Z later reads x, and sees value 2, which is inconsistent with the value it read for
y.”
p. 429   In Fig. 18.16, Line 3 should be
protected T internalInit;
p. 430   In Figure 18.17, Line 21 should be
target.next = next;
p. 433   In Fig. 18.19, line 8 should be
if (other != previous)
p433: synchronization., These (change comma to period)
p435: symmetrically.). (delete extra period inside parens)
p436: "seqential object" should be "sequential object" (twice, in Fig 18.21 near
top)
p436, figure caption, line 2: the a second object

p. 434   “Setters are implemented in a symmetric way, calling the setter in the second
step.”
“This class has a single AtomicObject<SSkipNode> field. The constructor
takes
as argument values to initialize the AtomicObject<SSkipNode> field.”
p447: placed in the cache -> placed in the cache line

Appendix A
p. 455    In Fig. A1, Caption should read “This method initializes a number of Java
threads, starts them, and waits for them to finish.”
P 457     Footnote: Pragma 8.2.3 => Pragma 8.3
p.462     Figure A.5, line 17, comment should be “queue is full”.
p.463     Figure A.6, line 36, comment should be “queue is empty”.
p.466     Last sentence of section should be: “Unlike the Java implementation, is uses two
different condition variables to wait for the buffer to become either not full or
not empty.”
p469: We studied many ways -> We will study many ways

Appendix B
p.473 In Fig. B.4, the right and left-hand sides are reversed.

p.473 change "small memories that are situated closer to the processors and are
therefore much faster than memory" to "small memories that are situated closer
to the processors and are therefore much faster than main memory"
p475: first bullet: cache,. and (replace period with comma)
p.478 “… is not necessarily the order in which they occur in the program.”
p480: discussed in detail in Chapter 16 -> discussed in detail in Chapter 10
p.480 3rd graf from bottom: “Chapter 16” should be “Chapter 10”
p.481 “John Hennessey and David Patterson”'
p481: Hennessey -> Hennessy
p484, in [14]: shared-money -> shared-memory
p489, in [103]: authors and title are duplicated
p492, in [142]: Special Issue (10) -> 10(2)
p496: sense-serving -> sense-reversing
P499: Index, add entry: Exchanger class 249-251 (between "Events" and
"Exclusive state")

Back matter
Page 494, immediately following the bibliography, please add the text from the attached
file, "Suggested teaching amendment" on page 494, which is currently blank. Please lay
out to fit on one page only.

Acknowledgements
Page xvii: Please add the following new paragraph at the end:
Thanks to all who have sent us errata to improve this book, including: Rajeev Alur,
Matthew Allen, Liran Barsisa, Igor Berman, Konstantin Boudnik, Bjoern Brandenburg ,
Martin Buchholz, Mario Calha, Michael Champigny, Neill Clift , Eran Cohen, Daniel B.
Curtis, Gil Danziger, Venkat Dhinakaran, David Dice, David Fort, Robert P. Goddard,
Brian Goetz, Bart Golsteijn , K. Gopinath, Jason T. Greene, Dan Grossman, Tim
Halloran, Muhammad Amber Hassaan, Matt Hayes, Francis Hools , Ben Horowitz, Barak
Itkin, Paulo Janotti, Kyungho Jeon, Ahmed Khademzadeh, Irena Karlinsky, Habib Khan,
Omar Khan, Namhyung Kim, Guy Korland , Sergey Kotov, Doug Lea, Yossi Lev, Adam
MacBeth, Adam Morrison, Adam Weinstock, Mike Maloney, Tim McIver, Sergejs
Melderis, Bartosz Milewski, Mark Moir, Adam Morrison, Victor Luchangco, Jose Pedro
Oliveira, Dale Parson, Jonathan Perry, Amir Pnueli, Pat Quillen, Binoy Ravindran , Roei
Raviv, Sudarshan Raghunathan, Jean-Paul Rigault, Michael Rueppel, Mohamed M. Saad,
Assaf Schuster, Marc Shapiro, Nathar Shah, Huang-Ti Shih, Joseph P. Skudlarek, James
Stout, Mark Summerfield, Deqing Sun, Seth Syberg, Fuad Tabba, Binil Thomas, John A
Trono, Thomas Weibel, Adam Weinstock, Jaeheon Yi, Zhenyuan Zhao, Ruiwen Zuo,
Chong Xing


DOCUMENT INFO
Categories:
Tags:
Stats:
 views: 15 posted: 12/5/2011 language: English pages: 20