[ltt-dev] [PATCH 05/10] call_rcu: drop mutex

Paolo Bonzini pbonzini at redhat.com
Wed Jun 8 04:59:13 EDT 2011


The mutex is being used only to protect OR accesses to the flags.
Just use atomic operations for that.

Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
 urcu-call-rcu-impl.h |   23 +++++++----------------
 1 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h
index 69edd49..7e6acdd 100644
--- a/urcu-call-rcu-impl.h
+++ b/urcu-call-rcu-impl.h
@@ -46,7 +46,6 @@
 struct call_rcu_data {
 	struct cds_wfq_queue cbs;
 	unsigned long flags;
-	pthread_mutex_t mtx;
 	int futex;
 	unsigned long qlen;
 	pthread_t tid;
@@ -235,9 +234,9 @@ static void *call_rcu_thread(void *arg)
 			} while (cbs != NULL);
 			uatomic_sub(&crdp->qlen, cbcount);
 		}
-		if (crdp->flags & URCU_CALL_RCU_STOP)
+		if (uatomic_read(&crdp->flags) & URCU_CALL_RCU_STOP)
 			break;
-		if (crdp->flags & URCU_CALL_RCU_RT)
+		if (uatomic_read(&crdp->flags) & URCU_CALL_RCU_RT)
 			poll(NULL, 0, 10);
 		else {
 			if (&crdp->cbs.head == _CMM_LOAD_SHARED(crdp->cbs.tail))
@@ -245,9 +244,7 @@ static void *call_rcu_thread(void *arg)
 			poll(NULL, 0, 10);
 		}
 	}
-	call_rcu_lock(&crdp->mtx);
-	crdp->flags |= URCU_CALL_RCU_STOPPED;
-	call_rcu_unlock(&crdp->mtx);
+	uatomic_or(&crdp->flags, URCU_CALL_RCU_STOPPED);
 	return NULL;
 }
 
@@ -271,10 +268,6 @@ static void call_rcu_data_init(struct call_rcu_data **crdpp,
 	memset(crdp, '\0', sizeof(*crdp));
 	cds_wfq_init(&crdp->cbs);
 	crdp->qlen = 0;
-	if (pthread_mutex_init(&crdp->mtx, NULL) != 0) {
-		perror("pthread_mutex_init");
-		exit(-1);
-	}
 	crdp->futex = 0;
 	crdp->flags = flags;
 	cds_list_add(&crdp->list, &call_rcu_data_list);
@@ -557,12 +550,10 @@ void call_rcu_data_free(struct call_rcu_data *crdp)
 	if (crdp == NULL || crdp == default_call_rcu_data) {
 		return;
 	}
-	if ((crdp->flags & URCU_CALL_RCU_STOPPED) == 0) {
-		call_rcu_lock(&crdp->mtx);
-		crdp->flags |= URCU_CALL_RCU_STOP;
-		call_rcu_unlock(&crdp->mtx);
+	if ((uatomic_read(&crdp->flags) & URCU_CALL_RCU_STOPPED) == 0) {
+		uatomic_or(&crdp->flags, URCU_CALL_RCU_STOP);
 		wake_call_rcu_thread(crdp);
-		while ((crdp->flags & URCU_CALL_RCU_STOPPED) == 0)
+		while ((uatomic_read(&crdp->flags) & URCU_CALL_RCU_STOPPED) == 0)
 			poll(NULL, 0, 1);
 	}
 	if (&crdp->cbs.head != _CMM_LOAD_SHARED(crdp->cbs.tail)) {
@@ -646,7 +637,7 @@ void call_rcu_after_fork_child(void)
 		if (crdp == default_call_rcu_data)
 			crdp = cds_list_entry(crdp->list.prev,
 					      struct call_rcu_data, list);
-		crdp->flags = URCU_CALL_RCU_STOPPED;
+		uatomic_set(&crdp->flags, URCU_CALL_RCU_STOPPED);
 		call_rcu_data_free(crdp);
 	}
 }
-- 
1.7.4.4






More information about the lttng-dev mailing list