Index: uspace/app/rcutest/rcutest.c
===================================================================
--- uspace/app/rcutest/rcutest.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/app/rcutest/rcutest.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -35,4 +35,5 @@
  */
 
+#include <atomic.h>
 #include <stdio.h>
 #include <stdlib.h>
Index: uspace/app/wavplay/main.c
===================================================================
--- uspace/app/wavplay/main.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/app/wavplay/main.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -35,4 +35,5 @@
 
 #include <assert.h>
+#include <atomic.h>
 #include <errno.h>
 #include <fibril_synch.h>
Index: uspace/lib/c/generic/assert.c
===================================================================
--- uspace/lib/c/generic/assert.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/c/generic/assert.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -35,10 +35,9 @@
 #include <io/kio.h>
 #include <stdlib.h>
-#include <atomic.h>
 #include <stacktrace.h>
 #include <stdint.h>
 #include <task.h>
 
-static atomic_t failed_asserts = { 0 };
+__thread int failed_asserts = 0;
 
 void __helenos_assert_quick_abort(const char *cond, const char *file, unsigned int line)
@@ -69,5 +68,6 @@
 	 * Check if this is a nested or parallel assert.
 	 */
-	if (atomic_postinc(&failed_asserts))
+	failed_asserts++;
+	if (failed_asserts > 0)
 		abort();
 
Index: uspace/lib/c/generic/async/client.c
===================================================================
--- uspace/lib/c/generic/async/client.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/c/generic/async/client.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -185,5 +185,5 @@
 	list_initialize(&session_ns.exch_list);
 	fibril_mutex_initialize(&session_ns.mutex);
-	atomic_set(&session_ns.refcnt, 0);
+	session_ns.exchanges = 0;
 }
 
@@ -605,5 +605,5 @@
 	}
 
-	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	async_sess_t *sess = calloc(1, sizeof(async_sess_t));
 	if (sess == NULL) {
 		errno = ENOMEM;
@@ -627,9 +627,6 @@
 
 	fibril_mutex_initialize(&sess->remote_state_mtx);
-	sess->remote_state_data = NULL;
-
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
-	atomic_set(&sess->refcnt, 0);
 
 	return sess;
@@ -676,5 +673,5 @@
 	}
 
-	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	async_sess_t *sess = calloc(1, sizeof(async_sess_t));
 	if (sess == NULL) {
 		errno = ENOMEM;
@@ -698,9 +695,6 @@
 
 	fibril_mutex_initialize(&sess->remote_state_mtx);
-	sess->remote_state_data = NULL;
-
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
-	atomic_set(&sess->refcnt, 0);
 
 	return sess;
@@ -712,5 +706,5 @@
 async_sess_t *async_connect_kbox(task_id_t id)
 {
-	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	async_sess_t *sess = calloc(1, sizeof(async_sess_t));
 	if (sess == NULL) {
 		errno = ENOMEM;
@@ -729,14 +723,8 @@
 	sess->mgmt = EXCHANGE_ATOMIC;
 	sess->phone = phone;
-	sess->arg1 = 0;
-	sess->arg2 = 0;
-	sess->arg3 = 0;
 
 	fibril_mutex_initialize(&sess->remote_state_mtx);
-	sess->remote_state_data = NULL;
-
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
-	atomic_set(&sess->refcnt, 0);
 
 	return sess;
@@ -761,8 +749,7 @@
 	assert(sess);
 
-	if (atomic_get(&sess->refcnt) > 0)
-		return EBUSY;
-
 	fibril_mutex_lock(&async_sess_mutex);
+
+	assert(sess->exchanges == 0);
 
 	errno_t rc = async_hangup_internal(sess->phone);
@@ -874,12 +861,11 @@
 	}
 
+	if (exch != NULL)
+		sess->exchanges++;
+
 	fibril_mutex_unlock(&async_sess_mutex);
 
-	if (exch != NULL) {
-		atomic_inc(&sess->refcnt);
-
-		if (mgmt == EXCHANGE_SERIALIZE)
-			fibril_mutex_lock(&sess->mutex);
-	}
+	if (exch != NULL && mgmt == EXCHANGE_SERIALIZE)
+		fibril_mutex_lock(&sess->mutex);
 
 	return exch;
@@ -903,10 +889,10 @@
 		mgmt = sess->iface & IFACE_EXCHANGE_MASK;
 
-	atomic_dec(&sess->refcnt);
-
 	if (mgmt == EXCHANGE_SERIALIZE)
 		fibril_mutex_unlock(&sess->mutex);
 
 	fibril_mutex_lock(&async_sess_mutex);
+
+	sess->exchanges--;
 
 	list_append(&exch->sess_link, &sess->exch_list);
Index: uspace/lib/c/generic/async/server.c
===================================================================
--- uspace/lib/c/generic/async/server.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/c/generic/async/server.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -129,5 +129,5 @@
 
 	task_id_t in_task_id;
-	atomic_t refcnt;
+	int refcnt;
 	void *data;
 } client_t;
@@ -327,5 +327,5 @@
 	if (link) {
 		client = hash_table_get_inst(link, client_t, link);
-		atomic_inc(&client->refcnt);
+		client->refcnt++;
 	} else if (create) {
 		// TODO: move the malloc out of critical section
@@ -336,5 +336,5 @@
 			client->data = async_client_data_create();
 
-			atomic_set(&client->refcnt, 1);
+			client->refcnt = 1;
 			hash_table_insert(&client_hash_table, &client->link);
 		}
@@ -351,5 +351,5 @@
 	fibril_rmutex_lock(&client_mutex);
 
-	if (atomic_predec(&client->refcnt) == 0) {
+	if (--client->refcnt == 0) {
 		hash_table_remove(&client_hash_table, &client->in_task_id);
 		destroy = true;
@@ -1574,5 +1574,5 @@
 	}
 
-	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	async_sess_t *sess = calloc(1, sizeof(async_sess_t));
 	if (sess == NULL) {
 		async_answer_0(&call, ENOMEM);
@@ -1583,14 +1583,8 @@
 	sess->mgmt = mgmt;
 	sess->phone = phandle;
-	sess->arg1 = 0;
-	sess->arg2 = 0;
-	sess->arg3 = 0;
 
 	fibril_mutex_initialize(&sess->remote_state_mtx);
-	sess->remote_state_data = NULL;
-
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
-	atomic_set(&sess->refcnt, 0);
 
 	/* Acknowledge the connected phone */
@@ -1622,5 +1616,5 @@
 		return NULL;
 
-	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
+	async_sess_t *sess = calloc(1, sizeof(async_sess_t));
 	if (sess == NULL)
 		return NULL;
@@ -1629,14 +1623,8 @@
 	sess->mgmt = mgmt;
 	sess->phone = phandle;
-	sess->arg1 = 0;
-	sess->arg2 = 0;
-	sess->arg3 = 0;
 
 	fibril_mutex_initialize(&sess->remote_state_mtx);
-	sess->remote_state_data = NULL;
-
 	list_initialize(&sess->exch_list);
 	fibril_mutex_initialize(&sess->mutex);
-	atomic_set(&sess->refcnt, 0);
 
 	return sess;
Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/c/generic/ddi.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -34,5 +34,4 @@
 
 #include <assert.h>
-#include <atomic.h>
 #include <stdio.h>
 #include <errno.h>
Index: uspace/lib/c/generic/private/async.h
===================================================================
--- uspace/lib/c/generic/private/async.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/c/generic/private/async.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -70,5 +70,5 @@
 
 	/** Number of opened exchanges */
-	atomic_t refcnt;
+	int exchanges;
 
 	/** Mutex for stateful connections */
Index: uspace/lib/c/generic/private/fibril.h
===================================================================
--- uspace/lib/c/generic/private/fibril.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/c/generic/private/fibril.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -34,5 +34,4 @@
 #include <tls.h>
 #include <abi/proc/uarg.h>
-#include <atomic.h>
 #include <fibril.h>
 
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/c/include/async.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -43,5 +43,4 @@
 #include <fibril.h>
 #include <sys/time.h>
-#include <atomic.h>
 #include <stdbool.h>
 #include <abi/proc/task.h>
Index: uspace/lib/c/include/refcount.h
===================================================================
--- uspace/lib/c/include/refcount.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
+++ uspace/lib/c/include/refcount.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018 CZ.NIC, z.s.p.o.
+ * 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.
+ */
+
+/*
+ * Authors:
+ *	Jiří Zárevúcky (jzr) <zarevucky.jiri@gmail.com>
+ */
+
+/*
+ * Using atomics for reference counting efficiently is a little tricky,
+ * so we define a unified API for this.
+ */
+
+#ifndef LIBC_REFCOUNT_H_
+#define LIBC_REFCOUNT_H_
+
+// TODO: #include <stdatomic.h>
+
+#include <assert.h>
+#include <atomic.h>
+#include <stdbool.h>
+
+/* Wrapped in a structure to prevent direct manipulation. */
+typedef struct atomic_refcount {
+	//volatile atomic_int __cnt;
+	atomic_t __cnt;
+} atomic_refcount_t;
+
+static inline void refcount_init(atomic_refcount_t *rc)
+{
+	//atomic_store_explicit(&rc->__cnt, 0, memory_order_relaxed);
+	atomic_set(&rc->__cnt, 0);
+}
+
+/**
+ * Increment a reference count.
+ *
+ * Calling this without already owning a reference is undefined behavior.
+ * E.g. acquiring a reference through a shared mutable pointer requires that
+ * the caller first locks the pointer itself (thereby acquiring the reference
+ * inherent to the shared variable), and only then may call refcount_up().
+ */
+static inline void refcount_up(atomic_refcount_t *rc)
+{
+	// XXX: We can use relaxed operation because acquiring a reference
+	//      implies no ordering relationships. A reference-counted object
+	//      still needs to be synchronized independently of the refcount.
+
+	//int old = atomic_fetch_add_explicit(&rc->__cnt, 1,
+	//    memory_order_relaxed);
+
+	atomic_signed_t old = atomic_postinc(&rc->__cnt);
+
+	/* old < 0 indicates that the function is used incorrectly. */
+	assert(old >= 0);
+}
+
+/**
+ * Decrement a reference count. Caller must own the reference.
+ *
+ * If the function returns `false`, the caller no longer owns the reference and
+ * must not access the reference counted object.
+ *
+ * If the function returns `true`, the caller is now the sole owner of the
+ * reference counted object, and must deallocate it.
+ */
+static inline bool refcount_down(atomic_refcount_t *rc)
+{
+	// XXX: The decrementers don't need to synchronize with each other,
+	//      but they do need to synchronize with the one doing deallocation.
+	//int old = atomic_fetch_sub_explicit(&rc->__cnt, 1,
+	//    memory_order_release);
+
+	atomic_signed_t old = atomic_postdec(&rc->__cnt);
+
+	assert(old >= 0);
+
+	if (old == 0) {
+		// XXX: We are holding the last reference, so we must now
+		//      synchronize with all the other decrementers.
+		//int val = atomic_load_explicit(&rc->__cnt,
+		//    memory_order_acquire);
+		//assert(val == -1);
+		return true;
+	}
+
+	return false;
+}
+
+#endif
+
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/drv/generic/driver.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -578,5 +578,5 @@
 static void dev_add_ref(ddf_dev_t *dev)
 {
-	atomic_inc(&dev->refcnt);
+	refcount_up(&dev->refcnt);
 }
 
@@ -587,5 +587,5 @@
 static void dev_del_ref(ddf_dev_t *dev)
 {
-	if (atomic_predec(&dev->refcnt) == 0)
+	if (refcount_down(&dev->refcnt))
 		delete_device(dev);
 }
@@ -600,5 +600,5 @@
 {
 	dev_add_ref(fun->dev);
-	atomic_inc(&fun->refcnt);
+	refcount_up(&fun->refcnt);
 }
 
@@ -611,5 +611,5 @@
 	ddf_dev_t *dev = fun->dev;
 
-	if (atomic_predec(&fun->refcnt) == 0)
+	if (refcount_down(&fun->refcnt))
 		delete_function(fun);
 
Index: uspace/lib/drv/generic/private/driver.h
===================================================================
--- uspace/lib/drv/generic/private/driver.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/drv/generic/private/driver.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -38,4 +38,5 @@
 
 #include <async.h>
+#include <refcount.h>
 #include <ipc/devman.h>
 #include <ipc/dev_iface.h>
@@ -51,5 +52,5 @@
 
 	/** Reference count */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 
 	/** Session with the parent device driver */
@@ -75,5 +76,5 @@
 
 	/** Reference count */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 
 	/** Device which this function belogs to */
Index: uspace/lib/usbhost/include/usb/host/endpoint.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -42,6 +42,6 @@
 
 #include <adt/list.h>
-#include <atomic.h>
 #include <fibril_synch.h>
+#include <refcount.h>
 #include <stdbool.h>
 #include <sys/time.h>
@@ -78,5 +78,5 @@
 	device_t *device;
 	/** Reference count. */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 
 	/** An inherited guard */
Index: uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -38,6 +38,6 @@
 #define LIBUSBHOST_HOST_USB_TRANSFER_BATCH_H
 
-#include <atomic.h>
 #include <errno.h>
+#include <refcount.h>
 #include <stddef.h>
 #include <stdint.h>
Index: uspace/lib/usbhost/src/endpoint.c
===================================================================
--- uspace/lib/usbhost/src/endpoint.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/lib/usbhost/src/endpoint.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -36,5 +36,4 @@
 
 #include <assert.h>
-#include <atomic.h>
 #include <mem.h>
 #include <stdlib.h>
@@ -60,5 +59,5 @@
 	ep->device = dev;
 
-	atomic_set(&ep->refcnt, 0);
+	refcount_init(&ep->refcnt);
 	fibril_condvar_initialize(&ep->avail);
 
@@ -91,5 +90,5 @@
 void endpoint_add_ref(endpoint_t *ep)
 {
-	atomic_inc(&ep->refcnt);
+	refcount_up(&ep->refcnt);
 }
 
@@ -115,7 +114,6 @@
 void endpoint_del_ref(endpoint_t *ep)
 {
-	if (atomic_predec(&ep->refcnt) == 0) {
+	if (refcount_down(&ep->refcnt))
 		endpoint_destroy(ep);
-	}
 }
 
Index: uspace/srv/audio/hound/audio_data.c
===================================================================
--- uspace/srv/audio/hound/audio_data.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/audio/hound/audio_data.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -59,5 +59,5 @@
 		adata->size = size - overflow;
 		adata->format = format;
-		atomic_set(&adata->refcount, 1);
+		refcount_init(&adata->refcount);
 	}
 	return adata;
@@ -71,6 +71,5 @@
 {
 	assert(adata);
-	assert(atomic_get(&adata->refcount) > 0);
-	atomic_inc(&adata->refcount);
+	refcount_up(&adata->refcount);
 }
 
@@ -82,7 +81,5 @@
 {
 	assert(adata);
-	assert(atomic_get(&adata->refcount) > 0);
-	atomic_count_t refc = atomic_predec(&adata->refcount);
-	if (refc == 0) {
+	if (refcount_down(&adata->refcount)) {
 		free(adata->data);
 		free(adata);
Index: uspace/srv/audio/hound/audio_data.h
===================================================================
--- uspace/srv/audio/hound/audio_data.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/audio/hound/audio_data.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -38,5 +38,5 @@
 
 #include <adt/list.h>
-#include <atomic.h>
+#include <refcount.h>
 #include <errno.h>
 #include <fibril_synch.h>
@@ -52,5 +52,5 @@
 	pcm_format_t format;
 	/** Reference counter */
-	atomic_t refcount;
+	atomic_refcount_t refcount;
 } audio_data_t;
 
Index: uspace/srv/bd/vbd/disk.c
===================================================================
--- uspace/srv/bd/vbd/disk.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/bd/vbd/disk.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -244,5 +244,5 @@
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG2, "vbds_part_add_ref");
-	atomic_inc(&part->refcnt);
+	refcount_up(&part->refcnt);
 }
 
@@ -250,5 +250,5 @@
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG2, "vbds_part_del_ref");
-	if (atomic_predec(&part->refcnt) == 0) {
+	if (refcount_down(&part->refcnt)) {
 		log_msg(LOG_DEFAULT, LVL_DEBUG2, " - free part");
 		free(part);
@@ -328,5 +328,5 @@
 	part->block0 = lpinfo.block0;
 	part->nblocks = lpinfo.nblocks;
-	atomic_set(&part->refcnt, 1);
+	refcount_init(&part->refcnt);
 
 	bd_srvs_init(&part->bds);
Index: uspace/srv/bd/vbd/types/vbd.h
===================================================================
--- uspace/srv/bd/vbd/types/vbd.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/bd/vbd/types/vbd.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -39,8 +39,8 @@
 
 #include <adt/list.h>
-#include <atomic.h>
 #include <bd_srv.h>
 #include <label/label.h>
 #include <loc.h>
+#include <refcount.h>
 #include <stdbool.h>
 #include <stddef.h>
@@ -83,5 +83,5 @@
 	aoff64_t nblocks;
 	/** Reference count */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 } vbds_part_t;
 
Index: uspace/srv/devman/dev.c
===================================================================
--- uspace/srv/devman/dev.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/devman/dev.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -48,5 +48,5 @@
 		return NULL;
 
-	atomic_set(&dev->refcnt, 0);
+	refcount_init(&dev->refcnt);
 	list_initialize(&dev->functions);
 	link_initialize(&dev->driver_devices);
@@ -74,5 +74,5 @@
 void dev_add_ref(dev_node_t *dev)
 {
-	atomic_inc(&dev->refcnt);
+	refcount_up(&dev->refcnt);
 }
 
@@ -85,5 +85,5 @@
 void dev_del_ref(dev_node_t *dev)
 {
-	if (atomic_predec(&dev->refcnt) == 0)
+	if (refcount_down(&dev->refcnt))
 		delete_dev_node(dev);
 }
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/devman/devman.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -41,5 +41,5 @@
 #include <ipc/loc.h>
 #include <fibril_synch.h>
-#include <atomic.h>
+#include <refcount.h>
 #include <async.h>
 
@@ -115,5 +115,5 @@
 struct dev_node {
 	/** Reference count */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 
 	/** The global unique identifier of the device. */
@@ -155,5 +155,5 @@
 struct fun_node {
 	/** Reference count */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 	/** State */
 	fun_state_t state;
Index: uspace/srv/devman/driver.c
===================================================================
--- uspace/srv/devman/driver.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/devman/driver.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -406,6 +406,4 @@
 		}
 
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "pass_devices_to_driver: dev->refcnt=%d\n",
-		    (int)atomic_get(&dev->refcnt));
 		dev_add_ref(dev);
 
Index: uspace/srv/devman/fun.c
===================================================================
--- uspace/srv/devman/fun.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/devman/fun.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -60,5 +60,5 @@
 
 	fun->state = FUN_INIT;
-	atomic_set(&fun->refcnt, 0);
+	refcount_init(&fun->refcnt);
 	fibril_mutex_initialize(&fun->busy_lock);
 	link_initialize(&fun->dev_functions);
@@ -89,5 +89,5 @@
 void fun_add_ref(fun_node_t *fun)
 {
-	atomic_inc(&fun->refcnt);
+	refcount_up(&fun->refcnt);
 }
 
@@ -100,5 +100,5 @@
 void fun_del_ref(fun_node_t *fun)
 {
-	if (atomic_predec(&fun->refcnt) == 0)
+	if (refcount_down(&fun->refcnt))
 		delete_fun_node(fun);
 }
Index: uspace/srv/fs/exfat/exfat.h
===================================================================
--- uspace/srv/fs/exfat/exfat.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/fs/exfat/exfat.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -38,5 +38,4 @@
 #include <fibril_synch.h>
 #include <libfs.h>
-#include <atomic.h>
 #include <stdint.h>
 #include <stdbool.h>
Index: uspace/srv/fs/fat/fat.h
===================================================================
--- uspace/srv/fs/fat/fat.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/fs/fat/fat.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -38,5 +38,4 @@
 #include <fibril_synch.h>
 #include <libfs.h>
-#include <atomic.h>
 #include <stdint.h>
 #include <stdbool.h>
Index: uspace/srv/fs/tmpfs/tmpfs.h
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/fs/tmpfs/tmpfs.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -35,5 +35,4 @@
 
 #include <libfs.h>
-#include <atomic.h>
 #include <stddef.h>
 #include <stdbool.h>
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -43,5 +43,4 @@
 #include <async.h>
 #include <errno.h>
-#include <atomic.h>
 #include <stdlib.h>
 #include <str.h>
Index: uspace/srv/fs/udf/udf.h
===================================================================
--- uspace/srv/fs/udf/udf.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/fs/udf/udf.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -37,5 +37,4 @@
 #include <fibril_synch.h>
 #include <libfs.h>
-#include <atomic.h>
 #include <stddef.h>
 #include <stdint.h>
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/hid/compositor/compositor.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -33,4 +33,5 @@
  */
 
+#include <assert.h>
 #include <stddef.h>
 #include <stdint.h>
@@ -46,5 +47,5 @@
 #include <stdlib.h>
 
-#include <atomic.h>
+#include <refcount.h>
 #include <fibril_synch.h>
 #include <adt/prodcons.h>
@@ -93,5 +94,5 @@
 typedef struct {
 	link_t link;
-	atomic_t ref_cnt;
+	atomic_refcount_t ref_cnt;
 	window_flags_t flags;
 	service_id_t in_dsid;
@@ -223,5 +224,5 @@
 
 	link_initialize(&win->link);
-	atomic_set(&win->ref_cnt, 0);
+	refcount_init(&win->ref_cnt);
 	prodcons_initialize(&win->queue);
 	transform_identity(&win->transform);
@@ -240,16 +241,17 @@
 static void window_destroy(window_t *win)
 {
-	if ((win) && (atomic_get(&win->ref_cnt) == 0)) {
-		while (!list_empty(&win->queue.list)) {
-			window_event_t *event = (window_event_t *) list_first(&win->queue.list);
-			list_remove(&event->link);
-			free(event);
-		}
-
-		if (win->surface)
-			surface_destroy(win->surface);
-
-		free(win);
-	}
+	if (!win || !refcount_down(&win->ref_cnt))
+		return;
+
+	while (!list_empty(&win->queue.list)) {
+		window_event_t *event = (window_event_t *) list_first(&win->queue.list);
+		list_remove(&event->link);
+		free(event);
+	}
+
+	if (win->surface)
+		surface_destroy(win->surface);
+
+	free(win);
 }
 
@@ -988,8 +990,11 @@
 		}
 	}
+
+	if (win)
+		refcount_up(&win->ref_cnt);
+
 	fibril_mutex_unlock(&window_list_mtx);
 
 	if (win) {
-		atomic_inc(&win->ref_cnt);
 		async_answer_0(icall, EOK);
 	} else {
@@ -1005,5 +1010,4 @@
 			if (!IPC_GET_IMETHOD(call)) {
 				async_answer_0(&call, EOK);
-				atomic_dec(&win->ref_cnt);
 				window_destroy(win);
 				return;
@@ -1024,5 +1028,4 @@
 			if (!IPC_GET_IMETHOD(call)) {
 				comp_window_close(win, &call);
-				atomic_dec(&win->ref_cnt);
 				window_destroy(win);
 				return;
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/hid/console/console.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -34,4 +34,5 @@
 
 #include <async.h>
+#include <atomic.h>
 #include <stdio.h>
 #include <adt/prodcons.h>
Index: uspace/srv/net/tcp/conn.c
===================================================================
--- uspace/srv/net/tcp/conn.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/net/tcp/conn.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -128,5 +128,6 @@
 
 	/* One for the user, one for not being in closed state */
-	atomic_set(&conn->refcnt, 2);
+	refcount_init(&conn->refcnt);
+	refcount_up(&conn->refcnt);
 
 	/* Allocate receive buffer */
@@ -238,7 +239,8 @@
 void tcp_conn_addref(tcp_conn_t *conn)
 {
-	log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_addref(%p) before=%zu",
-	    conn->name, conn, atomic_get(&conn->refcnt));
-	atomic_inc(&conn->refcnt);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_addref(%p)",
+	    conn->name, conn);
+
+	refcount_up(&conn->refcnt);
 }
 
@@ -251,8 +253,8 @@
 void tcp_conn_delref(tcp_conn_t *conn)
 {
-	log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_delref(%p) before=%zu",
-	    conn->name, conn, atomic_get(&conn->refcnt));
-
-	if (atomic_predec(&conn->refcnt) == 0)
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_delref(%p)",
+	    conn->name, conn);
+
+	if (refcount_down(&conn->refcnt))
 		tcp_conn_free(conn);
 }
Index: uspace/srv/net/tcp/tcp_type.h
===================================================================
--- uspace/srv/net/tcp/tcp_type.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/net/tcp/tcp_type.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -41,4 +41,5 @@
 #include <fibril.h>
 #include <fibril_synch.h>
+#include <refcount.h>
 #include <stddef.h>
 #include <stdint.h>
@@ -248,5 +249,5 @@
 	fibril_mutex_t lock;
 	/** Reference count */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 
 	/** Connection state */
Index: uspace/srv/net/udp/assoc.c
===================================================================
--- uspace/srv/net/udp/assoc.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/net/udp/assoc.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -91,5 +91,5 @@
 
 	/* One for the user */
-	atomic_set(&assoc->refcnt, 1);
+	refcount_init(&assoc->refcnt);
 
 	/* Initialize receive queue */
@@ -145,5 +145,5 @@
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: upd_assoc_addref(%p)", assoc->name, assoc);
-	atomic_inc(&assoc->refcnt);
+	refcount_up(&assoc->refcnt);
 }
 
@@ -158,5 +158,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: udp_assoc_delref(%p)", assoc->name, assoc);
 
-	if (atomic_predec(&assoc->refcnt) == 0)
+	if (refcount_down(&assoc->refcnt))
 		udp_assoc_free(assoc);
 }
Index: uspace/srv/net/udp/udp_type.h
===================================================================
--- uspace/srv/net/udp/udp_type.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/net/udp/udp_type.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -41,4 +41,5 @@
 #include <inet/endpoint.h>
 #include <ipc/loc.h>
+#include <refcount.h>
 #include <stdbool.h>
 #include <stddef.h>
@@ -114,5 +115,5 @@
 	fibril_mutex_t lock;
 	/** Reference count */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 
 	/** Receive queue */
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/vfs/vfs.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -49,5 +49,4 @@
 #include <str.h>
 #include <as.h>
-#include <atomic.h>
 #include <macros.h>
 #include "vfs.h"
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/volsrv/part.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -179,5 +179,5 @@
 	}
 
-	atomic_set(&part->refcnt, 1);
+	refcount_init(&part->refcnt);
 	link_initialize(&part->lparts);
 	part->parts = NULL;
@@ -524,5 +524,5 @@
 		if (part->svc_id == sid) {
 			/* Add reference */
-			atomic_inc(&part->refcnt);
+			refcount_up(&part->refcnt);
 			*rpart = part;
 			return EOK;
@@ -547,5 +547,5 @@
 void vol_part_del_ref(vol_part_t *part)
 {
-	if (atomic_predec(&part->refcnt) == 0)
+	if (refcount_down(&part->refcnt))
 		vol_part_delete(part);
 }
Index: uspace/srv/volsrv/types/part.h
===================================================================
--- uspace/srv/volsrv/types/part.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/volsrv/types/part.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -39,5 +39,5 @@
 
 #include <adt/list.h>
-#include <atomic.h>
+#include <refcount.h>
 #include <fibril_synch.h>
 #include <stdbool.h>
@@ -51,5 +51,5 @@
 	link_t lparts;
 	/** Reference count */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 	/** Service ID */
 	service_id_t svc_id;
Index: uspace/srv/volsrv/types/volume.h
===================================================================
--- uspace/srv/volsrv/types/volume.h	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/volsrv/types/volume.h	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -39,5 +39,5 @@
 
 #include <adt/list.h>
-#include <atomic.h>
+#include <refcount.h>
 #include <fibril_synch.h>
 #include <sif.h>
@@ -50,5 +50,5 @@
 	link_t lvolumes;
 	/** Reference count */
-	atomic_t refcnt;
+	atomic_refcount_t refcnt;
 	/** Volume label */
 	char *label;
Index: uspace/srv/volsrv/volume.c
===================================================================
--- uspace/srv/volsrv/volume.c	(revision 21a0d8a1c491bebee19acc5f968c67b94c31f0b6)
+++ uspace/srv/volsrv/volume.c	(revision 498ced18a4f90fe1c9eee028e354d61b39de484d)
@@ -83,5 +83,5 @@
 	}
 
-	atomic_set(&volume->refcnt, 1);
+	refcount_init(&volume->refcnt);
 	link_initialize(&volume->lvolumes);
 	volume->volumes = NULL;
@@ -245,5 +245,5 @@
 		    str_size(label) > 0) {
 			/* Add reference */
-			atomic_inc(&volume->refcnt);
+			refcount_up(&volume->refcnt);
 			*rvolume = volume;
 			return EOK;
@@ -309,5 +309,5 @@
 void vol_volume_del_ref(vol_volume_t *volume)
 {
-	if (atomic_predec(&volume->refcnt) == 0) {
+	if (refcount_down(&volume->refcnt)) {
 		/* No more references. Check if volume is persistent. */
 		if (!vol_volume_is_persist(volume)) {
