Index: kernel/generic/include/synch/waitq.h
===================================================================
--- kernel/generic/include/synch/waitq.h	(revision ea6370458b7ba595ee9a33c78e3c1fe58ce1ac76)
+++ kernel/generic/include/synch/waitq.h	(revision f169b7b92a2c20ad90fe7889d2defb67151199f5)
@@ -41,6 +41,8 @@
 #include <adt/list.h>
 
-#define WAKEUP_FIRST	0
-#define WAKEUP_ALL	1
+typedef enum {
+	WAKEUP_FIRST = 0,
+	WAKEUP_ALL
+} wakeup_mode_t;
 
 /** Wait queue structure. */
@@ -71,6 +73,6 @@
 extern int waitq_sleep_timeout_unsafe(waitq_t *wq, uint32_t usec, int flags);
 extern void waitq_sleep_finish(waitq_t *wq, int rc, ipl_t ipl);
-extern void waitq_wakeup(waitq_t *wq, bool all);
-extern void _waitq_wakeup_unsafe(waitq_t *wq, bool all);
+extern void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode);
+extern void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode);
 extern void waitq_interrupt_sleep(struct thread *t);
 
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision ea6370458b7ba595ee9a33c78e3c1fe58ce1ac76)
+++ kernel/generic/src/ipc/ipc.c	(revision f169b7b92a2c20ad90fe7889d2defb67151199f5)
@@ -164,5 +164,5 @@
 	list_append(&call->link, &callerbox->answers);
 	spinlock_unlock(&callerbox->lock);
-	waitq_wakeup(&callerbox->wq, 0);
+	waitq_wakeup(&callerbox->wq, WAKEUP_FIRST);
 }
 
@@ -206,5 +206,5 @@
 	list_append(&call->link, &box->calls);
 	spinlock_unlock(&box->lock);
-	waitq_wakeup(&box->wq, 0);
+	waitq_wakeup(&box->wq, WAKEUP_FIRST);
 }
 
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision ea6370458b7ba595ee9a33c78e3c1fe58ce1ac76)
+++ kernel/generic/src/proc/scheduler.c	(revision f169b7b92a2c20ad90fe7889d2defb67151199f5)
@@ -412,5 +412,6 @@
 					goto repeat;
 				}
-				_waitq_wakeup_unsafe(&THREAD->join_wq, false);
+				_waitq_wakeup_unsafe(&THREAD->join_wq,
+				    WAKEUP_FIRST);
 				spinlock_unlock(&THREAD->join_wq.lock);
 				
Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision ea6370458b7ba595ee9a33c78e3c1fe58ce1ac76)
+++ kernel/generic/src/synch/waitq.c	(revision f169b7b92a2c20ad90fe7889d2defb67151199f5)
@@ -384,9 +384,8 @@
  * timeout.
  *
- * @param wq Pointer to wait queue.
- * @param all If this is non-zero, all sleeping threads will be woken up and
- * 	missed count will be zeroed.
- */
-void waitq_wakeup(waitq_t *wq, bool all)
+ * @param wq	Pointer to wait queue.
+ * @param mode	Wakeup mode.
+ */
+void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode)
 {
 	ipl_t ipl;
@@ -395,8 +394,8 @@
 	spinlock_lock(&wq->lock);
 
-	_waitq_wakeup_unsafe(wq, all);
-
-	spinlock_unlock(&wq->lock);	
-	interrupts_restore(ipl);	
+	_waitq_wakeup_unsafe(wq, mode);
+
+	spinlock_unlock(&wq->lock);
+	interrupts_restore(ipl);
 }
 
@@ -406,20 +405,25 @@
  * assumes wq->lock is already locked and interrupts are already disabled.
  *
- * @param wq Pointer to wait queue.
- * @param all If this is non-zero, all sleeping threads will be woken up and
- * 	missed count will be zeroed.
- */
-void _waitq_wakeup_unsafe(waitq_t *wq, bool all)
+ * @param wq	Pointer to wait queue.
+ * @param mode	If mode is WAKEUP_FIRST, then the longest waiting thread,
+ *		if any, is woken up. If mode is WAKEUP_ALL, then all
+ *		waiting threads, if any, are woken up. If there are no
+ *		waiting threads to be woken up, the missed wakeup is
+ *		recorded in the wait queue.
+ */
+void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode)
 {
 	thread_t *t;
+	count_t count = 0;
 
 loop:	
 	if (list_empty(&wq->head)) {
 		wq->missed_wakeups++;
-		if (all)
-			wq->missed_wakeups = 0;
+		if (count && mode == WAKEUP_ALL)
+			wq->missed_wakeups--;
 		return;
 	}
 
+	count++;
 	t = list_get_instance(wq->head.next, thread_t, wq_link);
 	
@@ -450,5 +454,5 @@
 	thread_ready(t);
 
-	if (all)
+	if (mode == WAKEUP_ALL)
 		goto loop;
 }
