Index: uspace/app/rcutest/rcutest.c
===================================================================
--- uspace/app/rcutest/rcutest.c	(revision 29b81388f01a3adc660d263ca0e29a9bc35f2f0a)
+++ uspace/app/rcutest/rcutest.c	(revision a879d73cc0f7f958b997643d14d34dd72ecbe10e)
@@ -74,5 +74,5 @@
 static bool basic_sanity_check(void);
 static bool dont_wait_for_new_reader(void);
-
+static bool wait_for_exiting_reader(void);
 
 static test_desc_t test_desc[] = {
@@ -104,5 +104,5 @@
 		.func = basic_sanity_check,
 		.name = "basic-sanity",
-		.desc = "Locks/unlocks and syncs in a single fibril, no contention.",
+		.desc = "Locks/unlocks and syncs in 1 fibril, no contention.",
 	},
 	{
@@ -118,5 +118,12 @@
 		.func = dont_wait_for_new_reader,
 		.name = "ignore-new-r",
-		.desc = "Syncs with preexisting reader but ignores new reader.",
+		.desc = "Syncs with preexisting reader; ignores new reader.",
+	},
+	{
+		.aggregate = false,
+		.type = T_SANITY,
+		.func = wait_for_exiting_reader,
+		.name = "dereg-unlocks",
+		.desc = "Lets deregister_fibril unlock the reader section.",
 	},
 	{
@@ -269,4 +276,5 @@
 	bool synching;
 	bool synched;
+	size_t failed;
 } one_reader_info_t;
 
@@ -278,5 +286,7 @@
 	printf("lock{");
 	rcu_read_lock();
+	rcu_read_lock();
 	arg->entered_cs = true;
+	rcu_read_unlock();
 
 	printf("r-sleep{");
@@ -286,4 +296,9 @@
 	printf("}");
 	
+	if (arg->synched) {
+		arg->failed = 1;
+		printf("Error: rcu_sync exited prematurely.\n");
+	}
+	
 	arg->exited_cs = true;
 	rcu_read_unlock();
@@ -318,5 +333,5 @@
 	memory_barrier();
 	
-	if (!info.exited_cs) {
+	if (!info.exited_cs || info.failed) {
 		printf("Error: rcu_sync() returned before the reader exited its CS.\n");
 		/* 
@@ -334,5 +349,5 @@
 /*--------------------------------------------------------------------*/
 
-#define WAIT_STEP_US  1000 * USECS_PER_MS
+#define WAIT_STEP_US  500 * USECS_PER_MS
 
 typedef struct two_reader_info {
@@ -496,4 +511,80 @@
 
 #undef WAIT_STEP_US
+
+/*--------------------------------------------------------------------*/
+#define WAIT_STEP_US  500 * USECS_PER_MS
+
+typedef struct exit_reader_info {
+	bool entered_cs;
+	bool exited_cs;
+	bool synching;
+	bool synched;
+} exit_reader_info_t;
+
+
+static int exiting_locked_reader(exit_reader_info_t *arg)
+{
+	rcu_register_fibril();
+	
+	printf("old-lock{");
+	rcu_read_lock();
+	rcu_read_lock();
+	rcu_read_lock();
+	arg->entered_cs = true;
+	
+	printf("wait-for-sync{");
+	/* Wait for rcu_sync() to start waiting for us. */
+	while (!arg->synching) {
+		async_usleep(WAIT_STEP_US);
+	}
+	printf(" }");
+	
+	rcu_read_unlock();
+	printf(" }");
+
+	arg->exited_cs = true;
+	/* Store exited_cs before unlocking reader section in deregister. */
+	memory_barrier();
+	
+	/* Deregister forcefully unlocks the reader section. */
+	rcu_deregister_fibril();
+	return 0;
+}
+
+
+static bool wait_for_exiting_reader(void)
+{
+	exit_reader_info_t info = { 0 };
+	
+	if (!create_fibril((fibril_func_t) exiting_locked_reader, &info))
+		return false;
+	
+	/* Waits for the preexisting_reader to enter its CS.*/
+	while (!info.entered_cs) {
+		async_usleep(WAIT_STEP_US);
+	}
+	
+	assert(!info.exited_cs);
+	
+	printf("sync[");
+	info.synching = true;
+	rcu_synchronize();
+	info.synched = true;
+	printf(" ]\n");
+	
+	/* Load info.exited_cs */
+	memory_barrier();
+	
+	if (!info.exited_cs) {
+		printf("Error: rcu_deregister_fibril did not unlock the CS.\n");
+		return false;
+	}	
+	
+	return true;
+}
+
+#undef WAIT_STEP_US
+
+
 /*--------------------------------------------------------------------*/
 /*--------------------------------------------------------------------*/
