Contact Info

Instructional Support

Languages, Libraries, and Tools

PDF Versions

Ordering Information


Modern Multithreading Errata

This errata contains corrections for known errors and clarifications of a few additional points. If you find an additional error, please send email to Prof. Carver.

    Page 9, Beginning of section 1.5: The parameters for function
         pthread_create should be between (...) not {...}.

    Page 11, Listing 1.4: The fourth line from the bottom:
         int status = pthread_attr_init(...); should be deleted.

    Page 14: On line 10 of Section 1.6.1, "Cass" should be "class".

    Page 20: The comment for variable detached is broken
       across two lines. Also, threadAttribute
       does not need to be a member of the class,
       it can be local to method start().

    Page 27: The formula for the number of interleavings is:
       (m1 + m2 + ... + mn)!
       (m1! * m2! * ... * mn!)

    Page 43: On line 3 of 1.6, Thread_i should be Threadi:

    Page 44: Exercise 1.10 should refer to Section 1.7.2.

    Page 60: Middle of the page:
    The discussion about the critical section code mentions
    waiting[j] is set to 0; the code actually sets waiting[j]
    to false.

    Page 60: Bottom of the page:
    Note that linux provides a select() function that lets a thread
    sleep in multiples of micro-seconds.
       #include <stdio.h>
       #include <sys/select.h>
       void _sleep(int ms) {
          struct timeval timeout;
          timeout.tv_sec = ms/1000;
          timeout.tv_usec= (ms-timeout.tv_sec*1000)*1000;
          if (select (0, NULL, NULL, NULL, & timeout)< 0)

    Page 61: Middle of the page:
    The call to InterlockedExchange on page 60 occurs on line
    (4) not (3).
    The line marked (5) on page 61 should actually be the line
    with the call to InterlockedExchange(), not the comment.

    Page 60-61:Code Segments:
    Variable key is assumed to be a local variable of the threads.
    Variable key is not a shared variable; variable lock is shared.

    Page 61:Last Line:
    "Exercise 2.13" should be "Exercise 2.11"

    Page 69, Listing 2.1:
    Method startWrite in trace mode should check for
    active writers too:
       while (activeReaders>0 || writing) delay;
       writing = true;
    In method endWrite, set writing = false;
    At the beginning of startWrite, the check should be for
    (mode == trace) not (mode = trace).

    Page 82, 2.11.b:
    "use" should be "uses".

    Page 93, Strong semaphores:
    Note: Strong semaphores are not necessarily FCFS.
    So the queue in Implementation 2, Listing 3.2 is not
    necessarily FCFS.

    Page 96: Middle of the page:
    The VP implementation is in Section 3.7 not Section 3.6.

    Page 109, Listing 3.13:
    The comment in Read should be:
       // block writers while reads are occurring.

    Page 127, Listing 3.22:
    In method P(), the return code check should be
       if (!(rc==WAIT_OBJECT_0))

    Page 168, exercise 3.6 (a):
    The condition in the first if-statement should be
       (activeReaderCount == 1)
    The condition in the second if-statement should be
       (activeReaderCount == 0)

    Page 169, exercise 3.6 (b):
    mutex_r.V() should be mutex_r.unlock()

    Page 171, exercise 3.12:
    In class Barrier, private binarySemaphore mutex(1); should be
      private binarySemaphore mutex = new binarySemaphore(1);
    In class Barrier, private binarySemaphore go(0); should be
      private binarySemaphore go = new binarySemaphore(0);

    Page 171, exercise 3.13:
    On line 3, the exclamation point in H != n is upside down.

    Page 200, Listing 4.16:
    Method withdraw() should not be declared "synchronized."

    Page 205, middle of the page, 2nd bullet should be:
    T1 resumes execution, executes the statement --permits, ...

    Page 246, exercise 4.5 (b):
    This question should be about the SU toolbox, not the
    SC toolbox.

    Page 250, exercise 4.10:
    The word "turn" on line 2 should be part of the comment
    on the preceding line.

    Page 255, exercise 4.22:
    Method alternate() should have calls to enterMonitor() and
    exitMonitor() at the beginning and end, respectively.

    Page 298, first paragraph
    The asynchPort classes in Chapter 5 do not provide causal
    synchronization. They provide FIFO synchronization.

    Page 337, bottom paragraph
    This paragraph refers to Fig. 6.14, not Fig. 6.13. As
    such, VT(w) = [1,3,2] since message w <--> p occurs in Fig. 6.14.

    Page 376, Exercise 6.1
    On line 3, Ej should be ej

    Page 380, exercise 6.10:
    Change b,z) to (b,z)

    Page 401, Object-Centric Scheme:
    Add an edge from node 5 to node 4.

    Page 435, Middle of page, add the word "for":
    "The timestamp scheme for synchronous message passing ..."

    Page 437, Object-Centric Scheme:
    When a receivng event occurs, increment O.v, as in
    (a) O.v = O.v + 1; (b) O.v = max(O.v,s.ts) (c) r.ts = O.v

Questions and comments to: