Index: uspace/lib/libc/generic/fibril_sync.c
===================================================================
--- uspace/lib/libc/generic/fibril_sync.c	(revision 95ba2b84acffdac11b75bbad97e71f5b2be3c218)
+++ uspace/lib/libc/generic/fibril_sync.c	(revision 92d34f0bb50f9375034e4a22900906fe7a043f91)
@@ -91,25 +91,79 @@
 void fibril_rwlock_initialize(fibril_rwlock_t *frw)
 {
-	fibril_mutex_initialize(&frw->fm);
+	frw->writers = 0;
+	frw->readers = 0;
+	list_initialize(&frw->waiters);
 }
 
 void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
 {
-	fibril_mutex_lock(&frw->fm);
+	futex_down(&async_futex);
+	if (frw->writers) {
+		fibril_t *f = (fibril_t *) fibril_get_id();
+		f->flags &= ~FIBRIL_WRITER;
+		list_append(&f->link, &frw->waiters);
+		fibril_switch(FIBRIL_TO_MANAGER);
+	} else {
+		frw->readers++;
+		futex_up(&async_futex);
+	}
 }
 
 void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
 {
-	fibril_mutex_lock(&frw->fm);
+	futex_down(&async_futex);
+	if (frw->writers || frw->readers) {
+		fibril_t *f = (fibril_t *) fibril_get_id();
+		f->flags |= FIBRIL_WRITER;
+		list_append(&f->link, &frw->waiters);
+		fibril_switch(FIBRIL_TO_MANAGER);
+	} else {
+		frw->writers++;
+		futex_up(&async_futex);
+	}
+}
+
+static void _fibril_rwlock_common_unlock(fibril_rwlock_t *frw)
+{
+	futex_down(&async_futex);
+	assert(frw->readers || (frw->writers == 1));
+	if (frw->readers) {
+		if (--frw->readers)
+			goto out;
+	} else {
+		frw->writers--;
+	}
+	
+	assert(!frw->readers && !frw->writers);
+	
+	while (!list_empty(&frw->waiters)) {
+		link_t *tmp = frw->waiters.next;
+		fibril_t *f = list_get_instance(tmp, fibril_t, link);
+		
+		if (f->flags & FIBRIL_WRITER) {
+			if (frw->readers)
+				break;
+			list_remove(&f->link);
+			fibril_add_ready((fid_t) f);
+			frw->writers++;
+			break;
+		} else {
+			list_remove(&f->link);
+			fibril_add_ready((fid_t) f);
+			frw->readers++;
+		}
+	}
+out:
+	futex_up(&async_futex);
 }
 
 void fibril_rwlock_read_unlock(fibril_rwlock_t *frw)
 {
-	fibril_mutex_unlock(&frw->fm);
+	_fibril_rwlock_common_unlock(frw);
 }
 
 void fibril_rwlock_write_unlock(fibril_rwlock_t *frw)
 {
-	fibril_mutex_unlock(&frw->fm);
+	_fibril_rwlock_common_unlock(frw);
 }
 
Index: uspace/lib/libc/include/fibril.h
===================================================================
--- uspace/lib/libc/include/fibril.h	(revision 95ba2b84acffdac11b75bbad97e71f5b2be3c218)
+++ uspace/lib/libc/include/fibril.h	(revision 92d34f0bb50f9375034e4a22900906fe7a043f91)
@@ -47,5 +47,6 @@
 #endif /* context_set */
 
-#define FIBRIL_SERIALIZED  1
+#define FIBRIL_SERIALIZED	1
+#define FIBRIL_WRITER 		2
 
 typedef enum {
Index: uspace/lib/libc/include/fibril_sync.h
===================================================================
--- uspace/lib/libc/include/fibril_sync.h	(revision 95ba2b84acffdac11b75bbad97e71f5b2be3c218)
+++ uspace/lib/libc/include/fibril_sync.h	(revision 92d34f0bb50f9375034e4a22900906fe7a043f91)
@@ -56,15 +56,16 @@
 
 typedef struct {
-	fibril_mutex_t fm;
+	unsigned writers;
+	unsigned readers;
+	link_t waiters;
 } fibril_rwlock_t;
 
 #define FIBRIL_RWLOCK_INITIALIZE(name) \
 	fibril_rwlock_t name = { \
-		.fm = { \
-			.counter = 1, \
-			.waiters = { \
-				.prev = &name.fm.waiters, \
-				.next = &name.fm.waiters, \
-			} \
+		.readers = 0, \
+		.writers = 0, \
+		.waiters = { \
+			.prev = &name.waiters, \
+			.next = &name.waiters, \
 		} \
 	}
