Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ kernel/Makefile	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -227,5 +227,5 @@
 	generic/src/synch/smc.c \
 	generic/src/synch/waitq.c \
-	generic/src/synch/futex.c \
+	generic/src/synch/syswaitq.c \
 	generic/src/smp/ipi.c \
 	generic/src/smp/smp.c \
Index: kernel/generic/include/cap/cap.h
===================================================================
--- kernel/generic/include/cap/cap.h	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ kernel/generic/include/cap/cap.h	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -55,4 +55,5 @@
 	KOBJECT_TYPE_IRQ,
 	KOBJECT_TYPE_PHONE,
+	KOBJECT_TYPE_WAITQ,
 	KOBJECT_TYPE_MAX
 } kobject_type_t;
@@ -63,4 +64,5 @@
 struct irq;
 struct phone;
+struct waitq;
 
 typedef struct kobject_ops {
@@ -88,4 +90,5 @@
 		struct irq *irq;
 		struct phone *phone;
+		struct waitq *waitq;
 	};
 } kobject_t;
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ kernel/generic/include/proc/task.h	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -42,5 +42,4 @@
 #include <synch/spinlock.h>
 #include <synch/mutex.h>
-#include <synch/futex.h>
 #include <adt/list.h>
 #include <adt/odict.h>
@@ -128,9 +127,4 @@
 	task_arch_t arch;
 
-	/** Serializes access to futex_list.*/
-	SPINLOCK_DECLARE(futex_list_lock);
-	/** List of all futexes accesses by this task. */
-	list_t futex_list;
-
 	/** Accumulated accounting. */
 	uint64_t ucycles;
Index: kernel/generic/include/synch/futex.h
===================================================================
--- kernel/generic/include/synch/futex.h	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup kernel_sync
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_FUTEX_H_
-#define KERN_FUTEX_H_
-
-#include <typedefs.h>
-#include <synch/waitq.h>
-#include <adt/hash_table.h>
-
-/** Kernel-side futex structure. */
-typedef struct {
-	/** Physical address of the status variable. */
-	uintptr_t paddr;
-	/** Wait queue for threads waiting for futex availability. */
-	waitq_t wq;
-	/** Futex hash table link. */
-	ht_link_t ht_link;
-	/** Number of tasks that reference this futex. */
-	size_t refcount;
-} futex_t;
-
-extern void futex_init(void);
-extern sys_errno_t sys_futex_sleep(uintptr_t, uintptr_t);
-extern sys_errno_t sys_futex_wakeup(uintptr_t);
-
-extern void futex_task_cleanup(void);
-extern void futex_task_init(struct task *);
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/synch/syswaitq.h
===================================================================
--- kernel/generic/include/synch/syswaitq.h	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
+++ kernel/generic/include/synch/syswaitq.h	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup kernel_sync
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_SYS_WAITQ_H_
+#define KERN_SYS_WAITQ_H_
+
+#include <typedefs.h>
+#include <abi/cap.h>
+
+extern void sys_waitq_init(void);
+
+extern void sys_waitq_task_cleanup(void);
+
+extern sys_errno_t sys_waitq_create(cap_waitq_handle_t *);
+extern sys_errno_t sys_waitq_sleep(cap_waitq_handle_t, uint32_t, unsigned int);
+extern sys_errno_t sys_waitq_wakeup(cap_waitq_handle_t);
+extern sys_errno_t sys_waitq_destroy(cap_waitq_handle_t);
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/synch/waitq.h
===================================================================
--- kernel/generic/include/synch/waitq.h	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ kernel/generic/include/synch/waitq.h	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -49,5 +49,5 @@
  *
  */
-typedef struct {
+typedef struct waitq {
 	/** Lock protecting wait queue structure.
 	 *
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ kernel/generic/src/main/main.c	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -77,5 +77,5 @@
 #include <mm/reserve.h>
 #include <synch/waitq.h>
-#include <synch/futex.h>
+#include <synch/syswaitq.h>
 #include <arch/arch.h>
 #include <arch.h>
@@ -278,5 +278,5 @@
 	task_init();
 	thread_init();
-	futex_init();
+	sys_waitq_init();
 
 	sysinfo_set_item_data("boot_args", NULL, bargs, str_size(bargs) + 1);
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ kernel/generic/src/proc/task.c	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -43,5 +43,4 @@
 #include <mm/slab.h>
 #include <atomic.h>
-#include <synch/futex.h>
 #include <synch/spinlock.h>
 #include <synch/waitq.h>
@@ -251,6 +250,4 @@
 	}
 
-	futex_task_init(task);
-
 	irq_spinlock_lock(&tasks_lock, true);
 
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ kernel/generic/src/proc/thread.c	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -48,4 +48,5 @@
 #include <synch/spinlock.h>
 #include <synch/waitq.h>
+#include <synch/syswaitq.h>
 #include <cpu.h>
 #include <str.h>
@@ -519,5 +520,5 @@
 			 */
 			ipc_cleanup();
-			futex_task_cleanup();
+			sys_waitq_task_cleanup();
 			LOG("Cleanup of task %" PRIu64 " completed.", TASK->taskid);
 		}
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ 	(revision )
@@ -1,362 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * Copyright (c) 2012 Adam Hraska
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup kernel_sync
- * @{
- */
-
-/**
- * @file
- * @brief	Kernel backend for futexes.
- *
- * Kernel futex objects are stored in a global hash table futex_ht
- * where the physical address of the futex variable (futex_t.paddr)
- * is used as the lookup key. As a result multiple address spaces
- * may share the same futex variable.
- *
- * A kernel futex object is created the first time a task accesses
- * the futex (having a futex variable at a physical address not
- * encountered before). Futex object's lifetime is governed by
- * a reference count that represents the number of all the different
- * tasks that reference the futex variable. A futex object is freed
- * when the last task having accessed the futex exits.
- *
- * Each task keeps track of the futex objects it accessed in a list
- * of pointers (futex_ptr_t, task->futex_list) to the different futex
- * objects.
- */
-
-#include <assert.h>
-#include <synch/futex.h>
-#include <synch/mutex.h>
-#include <synch/spinlock.h>
-#include <mm/frame.h>
-#include <mm/page.h>
-#include <stdlib.h>
-#include <proc/thread.h>
-#include <proc/task.h>
-#include <genarch/mm/page_pt.h>
-#include <genarch/mm/page_ht.h>
-#include <adt/hash.h>
-#include <adt/hash_table.h>
-#include <adt/list.h>
-#include <arch.h>
-#include <align.h>
-#include <panic.h>
-#include <errno.h>
-
-/** Task specific pointer to a global kernel futex object. */
-typedef struct futex_ptr {
-	/** Link for the list of all futex pointers used by a task. */
-	link_t task_link;
-	/** Kernel futex object. */
-	futex_t *futex;
-} futex_ptr_t;
-
-static void futex_initialize(futex_t *futex, uintptr_t paddr);
-static void futex_add_ref(futex_t *futex);
-static void futex_release_ref(futex_t *futex);
-static void futex_release_ref_locked(futex_t *futex);
-
-static futex_t *get_futex(uintptr_t uaddr);
-static bool find_futex_paddr(uintptr_t uaddr, uintptr_t *phys_addr);
-
-static size_t futex_ht_hash(const ht_link_t *item);
-static size_t futex_ht_key_hash(void *key);
-static bool futex_ht_key_equal(void *key, const ht_link_t *item);
-static void futex_ht_remove_callback(ht_link_t *item);
-
-/** Mutex protecting the global futex hash table.
- *
- * Acquire task specific TASK->futex_list_lock before this mutex.
- */
-SPINLOCK_STATIC_INITIALIZE_NAME(futex_ht_lock, "futex-ht-lock");
-
-/** Global kernel futex hash table. Lock futex_ht_lock before accessing.
- *
- * Physical address of the futex variable is the lookup key.
- */
-static hash_table_t futex_ht;
-
-/** Global kernel futex hash table operations. */
-static hash_table_ops_t futex_ht_ops = {
-	.hash = futex_ht_hash,
-	.key_hash = futex_ht_key_hash,
-	.key_equal = futex_ht_key_equal,
-	.remove_callback = futex_ht_remove_callback
-};
-
-/** Initialize futex subsystem. */
-void futex_init(void)
-{
-	hash_table_create(&futex_ht, 0, 0, &futex_ht_ops);
-}
-
-/** Initializes the futex structures for the new task. */
-void futex_task_init(struct task *task)
-{
-	list_initialize(&task->futex_list);
-	spinlock_initialize(&task->futex_list_lock, "futex-list-lock");
-}
-
-/** Remove references from futexes known to the current task. */
-void futex_task_cleanup(void)
-{
-	/* All threads of this task have terminated. This is the last thread. */
-	spinlock_lock(&TASK->futex_list_lock);
-
-	list_foreach_safe(TASK->futex_list, cur_link, next_link) {
-		futex_ptr_t *futex_ptr = member_to_inst(cur_link, futex_ptr_t,
-		    task_link);
-
-		futex_release_ref_locked(futex_ptr->futex);
-		free(futex_ptr);
-	}
-
-	spinlock_unlock(&TASK->futex_list_lock);
-}
-
-/** Initialize the kernel futex structure.
- *
- * @param futex	Kernel futex structure.
- * @param paddr Physical address of the futex variable.
- */
-static void futex_initialize(futex_t *futex, uintptr_t paddr)
-{
-	waitq_initialize(&futex->wq);
-	futex->paddr = paddr;
-	futex->refcount = 1;
-}
-
-/** Increments the counter of tasks referencing the futex. */
-static void futex_add_ref(futex_t *futex)
-{
-	assert(spinlock_locked(&futex_ht_lock));
-	assert(futex->refcount > 0);
-	++futex->refcount;
-}
-
-/** Decrements the counter of tasks referencing the futex. May free the futex.*/
-static void futex_release_ref(futex_t *futex)
-{
-	assert(spinlock_locked(&futex_ht_lock));
-	assert(futex->refcount > 0);
-
-	--futex->refcount;
-
-	if (futex->refcount == 0)
-		hash_table_remove(&futex_ht, &futex->paddr);
-}
-
-/** Decrements the counter of tasks referencing the futex. May free the futex.*/
-static void futex_release_ref_locked(futex_t *futex)
-{
-	spinlock_lock(&futex_ht_lock);
-	futex_release_ref(futex);
-	spinlock_unlock(&futex_ht_lock);
-}
-
-/** Returns a futex for the virtual address @a uaddr (or creates one). */
-static futex_t *get_futex(uintptr_t uaddr)
-{
-	uintptr_t paddr;
-
-	if (!find_futex_paddr(uaddr, &paddr))
-		return NULL;
-
-	futex_t *futex = malloc(sizeof(futex_t));
-	if (!futex)
-		return NULL;
-
-	futex_ptr_t *futex_ptr = malloc(sizeof(futex_ptr_t));
-	if (!futex_ptr) {
-		free(futex);
-		return NULL;
-	}
-
-	/*
-	 * Find the futex object in the global futex table (or insert it
-	 * if it is not present).
-	 */
-	spinlock_lock(&TASK->futex_list_lock);
-	spinlock_lock(&futex_ht_lock);
-
-	ht_link_t *fut_link = hash_table_find(&futex_ht, &paddr);
-
-	if (fut_link) {
-		free(futex);
-		futex = member_to_inst(fut_link, futex_t, ht_link);
-
-		/*
-		 * See if the futex is already known to the TASK
-		 */
-		bool found = false;
-		list_foreach(TASK->futex_list, task_link, futex_ptr_t, fp) {
-			if (fp->futex->paddr == paddr) {
-				found = true;
-				break;
-			}
-		}
-		/*
-		 * If not, put it on the TASK->futex_list and bump its reference
-		 * count
-		 */
-		if (!found) {
-			list_append(&futex_ptr->task_link, &TASK->futex_list);
-			futex_add_ref(futex);
-		} else
-			free(futex_ptr);
-	} else {
-		futex_initialize(futex, paddr);
-		hash_table_insert(&futex_ht, &futex->ht_link);
-
-		/*
-		 * This is a new futex, so it is not on the TASK->futex_list yet
-		 */
-		futex_ptr->futex = futex;
-		list_append(&futex_ptr->task_link, &TASK->futex_list);
-	}
-
-	spinlock_unlock(&futex_ht_lock);
-	spinlock_unlock(&TASK->futex_list_lock);
-
-	return futex;
-}
-
-/** Finds the physical address of the futex variable. */
-static bool find_futex_paddr(uintptr_t uaddr, uintptr_t *paddr)
-{
-	page_table_lock(AS, false);
-	spinlock_lock(&futex_ht_lock);
-
-	bool success = false;
-
-	pte_t t;
-	bool found;
-
-	found = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE), true, &t);
-	if (found && PTE_VALID(&t) && PTE_PRESENT(&t)) {
-		success = true;
-		*paddr = PTE_GET_FRAME(&t) +
-		    (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
-	}
-
-	spinlock_unlock(&futex_ht_lock);
-	page_table_unlock(AS, false);
-
-	return success;
-}
-
-/** Sleep in futex wait queue with a timeout.
- *
- *  If the sleep times out or is interrupted, the next wakeup is ignored.
- *  The userspace portion of the call must handle this condition.
- *
- * @param uaddr	 	Userspace address of the futex counter.
- * @param timeout	Maximum number of useconds to sleep. 0 means no limit.
- *
- * @return		If there is no physical mapping for uaddr ENOENT is
- *			returned. Otherwise returns the return value of
- *                      waitq_sleep_timeout().
- */
-sys_errno_t sys_futex_sleep(uintptr_t uaddr, uintptr_t timeout)
-{
-	futex_t *futex = get_futex(uaddr);
-
-	if (!futex)
-		return (sys_errno_t) ENOENT;
-
-#ifdef CONFIG_UDEBUG
-	udebug_stoppable_begin();
-#endif
-
-	errno_t rc = waitq_sleep_timeout(&futex->wq, timeout,
-	    SYNCH_FLAGS_INTERRUPTIBLE | SYNCH_FLAGS_FUTEX, NULL);
-
-#ifdef CONFIG_UDEBUG
-	udebug_stoppable_end();
-#endif
-
-	return (sys_errno_t) rc;
-}
-
-/** Wakeup one thread waiting in futex wait queue.
- *
- * @param uaddr		Userspace address of the futex counter.
- *
- * @return		ENOENT if there is no physical mapping for uaddr.
- */
-sys_errno_t sys_futex_wakeup(uintptr_t uaddr)
-{
-	futex_t *futex = get_futex(uaddr);
-
-	if (futex) {
-		waitq_wakeup(&futex->wq, WAKEUP_FIRST);
-		return EOK;
-	} else {
-		return (sys_errno_t) ENOENT;
-	}
-}
-
-/** Return the hash of the key stored in the item */
-size_t futex_ht_hash(const ht_link_t *item)
-{
-	futex_t *futex = hash_table_get_inst(item, futex_t, ht_link);
-	return hash_mix(futex->paddr);
-}
-
-/** Return the hash of the key */
-size_t futex_ht_key_hash(void *key)
-{
-	uintptr_t *paddr = (uintptr_t *) key;
-	return hash_mix(*paddr);
-}
-
-/** Return true if the key is equal to the item's lookup key. */
-bool futex_ht_key_equal(void *key, const ht_link_t *item)
-{
-	uintptr_t *paddr = (uintptr_t *) key;
-	futex_t *futex = hash_table_get_inst(item, futex_t, ht_link);
-	return *paddr == futex->paddr;
-}
-
-/** Callback for removal items from futex hash table.
- *
- * @param item		Item removed from the hash table.
- */
-void futex_ht_remove_callback(ht_link_t *item)
-{
-	futex_t *futex;
-
-	futex = hash_table_get_inst(item, futex_t, ht_link);
-	free(futex);
-}
-
-/** @}
- */
Index: kernel/generic/src/synch/syswaitq.c
===================================================================
--- kernel/generic/src/synch/syswaitq.c	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
+++ kernel/generic/src/synch/syswaitq.c	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2018 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup kernel_sync
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Wrapper for using wait queue as a kobject.
+ */
+
+#include <synch/syswaitq.h>
+#include <synch/waitq.h>
+#include <abi/cap.h>
+#include <cap/cap.h>
+#include <mm/slab.h>
+#include <proc/task.h>
+#include <syscall/copy.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+
+static slab_cache_t *waitq_cache;
+
+static void waitq_destroy(void *arg)
+{
+	waitq_t *wq = (waitq_t *) arg;
+	slab_free(waitq_cache, wq);
+}
+
+static kobject_ops_t waitq_kobject_ops = {
+	.destroy = waitq_destroy
+};
+
+static bool waitq_cap_cleanup_cb(cap_t *cap, void *arg)
+{
+	kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
+	    KOBJECT_TYPE_WAITQ);
+	kobject_put(kobj);
+	cap_free(cap->task, cap->handle);
+	return true;
+}
+
+/** Initialize the user waitq subsystem */
+void sys_waitq_init(void)
+{
+	waitq_cache = slab_cache_create("waitq_t", sizeof(waitq_t), 0, NULL,
+	    NULL, 0);
+}
+
+/** Clean-up all waitq capabilities held by the exiting task */
+void sys_waitq_task_cleanup(void)
+{
+	caps_apply_to_kobject_type(TASK, KOBJECT_TYPE_WAITQ,
+	    waitq_cap_cleanup_cb, NULL);
+}
+
+/** Create a waitq for the current task
+ *
+ * @param[out] whandle  Userspace address of the destination buffer that will
+ *                      receive the allocated waitq capability.
+ *
+ * @return              Error code.
+ */
+sys_errno_t sys_waitq_create(cap_waitq_handle_t *whandle)
+{
+	waitq_t *wq = slab_alloc(waitq_cache, FRAME_ATOMIC);
+	if (!wq)
+		return (sys_errno_t) ENOMEM;
+	waitq_initialize(wq);
+
+	kobject_t *kobj = (kobject_t *) malloc(sizeof(kobject_t));
+	if (!kobj) {
+		slab_free(waitq_cache, wq);
+		return (sys_errno_t) ENOMEM;
+	}
+	kobject_initialize(kobj, KOBJECT_TYPE_WAITQ, wq, &waitq_kobject_ops);
+
+	cap_handle_t handle;
+	errno_t rc = cap_alloc(TASK, &handle);
+	if (rc != EOK) {
+		slab_free(waitq_cache, wq);
+		free(kobj);
+		return (sys_errno_t) rc;
+	}
+
+	rc = copy_to_uspace(whandle, &handle, sizeof(handle));
+	if (rc != EOK) {
+		cap_free(TASK, handle);
+		free(kobj);
+		slab_free(waitq_cache, wq);
+		return (sys_errno_t) rc;
+	}
+
+	cap_publish(TASK, handle, kobj);
+
+	return (sys_errno_t) EOK;
+}
+
+/** Destroy a waitq
+ *
+ * @param whandle  Waitq capability handle of the waitq to be destroyed.
+ *
+ * @return         Error code.
+ */
+sys_errno_t sys_waitq_destroy(cap_waitq_handle_t whandle)
+{
+	kobject_t *kobj = cap_unpublish(TASK, whandle, KOBJECT_TYPE_WAITQ);
+	if (!kobj)
+		return (sys_errno_t) ENOENT;
+	kobject_put(kobj);
+	cap_free(TASK, whandle);
+	return EOK;
+}
+
+/** Sleep in the waitq
+ *
+ * @param whandle  Waitq capability handle of the waitq in which to sleep.
+ * @param timeout  Timeout in microseconds.
+ * @param flags    Flags from SYNCH_FLAGS_* family. SYNCH_FLAGS_INTERRUPTIBLE is
+ *                 always implied.
+ *
+ * @return         Error code.
+ */
+sys_errno_t sys_waitq_sleep(cap_waitq_handle_t whandle, uint32_t timeout,
+    unsigned int flags)
+{
+	kobject_t *kobj = kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
+	if (!kobj)
+		return (sys_errno_t) ENOENT;
+
+#ifdef CONFIG_UDEBUG
+	udebug_stoppable_begin();
+#endif
+
+	errno_t rc = waitq_sleep_timeout(kobj->waitq, timeout,
+	    SYNCH_FLAGS_INTERRUPTIBLE | flags, NULL);
+
+#ifdef CONFIG_UDEBUG
+	udebug_stoppable_end();
+#endif
+
+	kobject_put(kobj);
+
+	return (sys_errno_t) rc;
+}
+
+/** Wakeup a thread sleeping in the waitq
+ *
+ * @param whandle  Waitq capability handle of the waitq to invoke wakeup on.
+ *
+ * @return         Error code.
+ */
+sys_errno_t sys_waitq_wakeup(cap_waitq_handle_t whandle)
+{
+	kobject_t *kobj = kobject_get(TASK, whandle, KOBJECT_TYPE_WAITQ);
+	if (!kobj)
+		return (sys_errno_t) ENOENT;
+
+	waitq_wakeup(kobj->waitq, WAKEUP_FIRST);
+
+	kobject_put(kobj);
+	return (sys_errno_t) EOK;
+}
+
+/** @}
+ */
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 3ce781f475c32746c4d1a7a2a7090be49e8552a4)
+++ kernel/generic/src/syscall/syscall.c	(revision aaa3c4571e7747f21c303ea4c746fe2ef17a5ae8)
@@ -46,6 +46,6 @@
 #include <interrupt.h>
 #include <ipc/sysipc.h>
-#include <synch/futex.h>
 #include <synch/smc.h>
+#include <synch/syswaitq.h>
 #include <ddi/ddi.h>
 #include <ipc/event.h>
@@ -136,6 +136,8 @@
 
 	/* Synchronization related syscalls. */
-	[SYS_FUTEX_SLEEP] = (syshandler_t) sys_futex_sleep,
-	[SYS_FUTEX_WAKEUP] = (syshandler_t) sys_futex_wakeup,
+	[SYS_WAITQ_CREATE] = (syshandler_t) sys_waitq_create,
+	[SYS_WAITQ_SLEEP] = (syshandler_t) sys_waitq_sleep,
+	[SYS_WAITQ_WAKEUP] = (syshandler_t) sys_waitq_wakeup,
+	[SYS_WAITQ_DESTROY] = (syshandler_t) sys_waitq_destroy,
 	[SYS_SMC_COHERENCE] = (syshandler_t) sys_smc_coherence,
 
