************
EventPair
************

This is a standard "ping-pong" problem exactly like Tweedledum and Tweedledee.
For the mutex/CV solution, a single condition variable is sufficient.
The ping-pong loop code (e.g., Handoff) is as follows:

	mx->Acquire();
	cv->Signal(mx);
	cv->Wait(mx);
	mx->Release();

This is one case in which you do not need to "loop before you leap": it is
the exception that proves the rule.  In this case, there is only one thread
waiting and one thread issuing the signal, and no condition that must be
true (other than that the signal occurred).

For the semaphore solution, two semaphores are needed to prevent one
party from consuming its own signal (V).  No mutex is needed.  The
semaphore code looks like this:

	othersem->V();
	mysem->P();

For EventPair, the Wait() primitive exists just to prime the "ping" so
there's a thread blocked to "pong".  This code is easy (just P() or
cv->Wait()).  Also, for EventPair there needs to be some way to keep
track of which semaphore is the "current" semaphore in handoff, and
switch to the other semaphore after each handoff.  For TweedleDum and
TweedleDee, just put the code fragments above in a loop, one loop for
Dee and one loop for Dum (make sure each loop Ps on its own semaphore
and Vs on the other guy's.  In the Mx/CV solution, the Mx acquire may
be outside the loop.

Note: for TweedleDum/TweedleDee, the problem with the sleep solution
is "the missed wakeup problem", where one thread issues its wakeup
before the other is asleep.  Understand how the Mx/CV and semaphore
solutions avoid this problem.

***************
Barrier
***************

	Condition* slavecv, mastercv;
	Mutex* mx;
	int count

	Create(int n) {
		new slavecv, mastercv, and mx;
		count = n;
	}

	Wait() {
		mx->Acquire();
		while (count)
			cv->Wait(mx);
		mx->Release();
	}

	Arrive() {
		mx->Acquire();
		count--;
		if (count == 0)
			mastercv->Signal();
		slavecv->Wait();
		mx->Release();
	}

	Release() {
		slavecv->Broadcast();
		count = n;
	}