Discussion questions: threads

Please work out these problems before your next discussion section. The GSIs will go over these problems during the discussion section.

1. Threads and races

Consider the following pseudo-code for a program that executes two threads, each of which executes the thread code give below:

//Global variables
const int n = 20;
int tally = 0;

//Thread start function
void total() {
    for (int count = 0; count < n; ++count) {
	tally = tally + 1;
    }
}

void main() {
    /*
     * First, we create a thread, thread1; it starts executing from the
     * function "total", defined above.
     */
    Thread thread1 = Thread(total);

    /*
     * The call to the Thread constructor returns immediately and we create another thread.
     * thread2 starts executing from the function "total", defined above.
     */
    Thread thread2 = Thread(total);
}

Assume that the following operators are atomic: comparision operators, assignment, and addition. Determine the proper lower bound and the upper bound on the final value of the shared variable tally. Also, briefly explain how you arrived at your conclusion.

2. Is a thread within a process protected from other threads within the same process?

3. Is a thread within a process protected from threads of a different process?

4. How do two threads in the same process share information? Can such a sharing be done directly between two threads in different processes?

5. Consider the following pseudo-code that attempts to provide mutual exclusion for a critical section using atomic load and store operations.

/* Global variables */
active[0] = false;
active[1] = false;
turn = 0;

Thread 0

while (1) {
    active[0] = true;

    while (turn != 0){
	while (active[1]) {
	}
	turn = 0;
    }
    <critical section>
    active[0] = false;

    <do other stuff>
}

Thread 1

while (1) {
    active[1] = true;

    while (turn != 1) {
	while (active[0]) {
	}
	turn = 1;
    }

    <critical section>
    active[1] = false;

    <do other stuff>
}

Is this a correct solution? If yes, prove it; else give a counter-example (by showing a possible interleaving of threads that allow the two threads to simultaneously access their critical sections).

6. Basic Monitors / Condition Variables

Write a function pingpong that creates two threads, ping (which prints "ping\n") and pong (which prints "pong\n"). Using only a mutex, condition variables, and counters, ensure that ping and pong together output:

  ping
  pong
  ping
  pong
  ...

Such that each "ping" is followed by a "pong" and each "pong" is followed by a "ping". This should stop after ten messages (five pings and five pongs). pingpong should not return until all pings and pongs have finished printing.