Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision b3f8fb771f871e7f2bb35ce9339717639e8f86d6)
+++ kernel/generic/src/synch/waitq.c	(revision 8ecb3067403118be4ab8be6d777ffa06ca2299bf)
@@ -117,4 +117,56 @@
 }
 
+/** Interrupt sleeping thread.
+ *
+ * This routine attempts to interrupt a thread from its sleep in a waitqueue.
+ * If the thread is not found sleeping, no action is taken.
+ *
+ * @param t Thread to be interrupted.
+ */
+void waitq_interrupt_sleep(thread_t *t)
+{
+	waitq_t *wq;
+	bool do_wakeup = false;
+	ipl_t ipl;
+
+	ipl = interrupts_disable();
+	spinlock_lock(&threads_lock);
+	if (!thread_exists(t))
+		goto out;
+
+grab_locks:
+	spinlock_lock(&t->lock);
+	if ((wq = t->sleep_queue)) {		/* assignment */
+		if (!(t->sleep_interruptible)) {
+			/*
+			 * The sleep cannot be interrupted.
+			 */
+			spinlock_unlock(&t->lock);
+			goto out;
+		}
+			
+		if (!spinlock_trylock(&wq->lock)) {
+			spinlock_unlock(&t->lock);
+			goto grab_locks;	/* avoid deadlock */
+		}
+
+		if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
+			t->timeout_pending = false;
+
+		list_remove(&t->wq_link);
+		t->saved_context = t->sleep_interruption_context;
+		do_wakeup = true;
+		t->sleep_queue = NULL;
+		spinlock_unlock(&wq->lock);
+	}
+	spinlock_unlock(&t->lock);
+
+	if (do_wakeup)
+		thread_ready(t);
+
+out:
+	spinlock_unlock(&threads_lock);
+	interrupts_restore(ipl);
+}
 
 /** Sleep until either wakeup, timeout or interruption occurs
