From 7618919ae496bda84a2efa4f2ad0abe569892a9e Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 17 Aug 2011 17:54:33 -0400 Subject: [PATCH] CDS API: removal of rcu_read lock/unlock dep, removal of call_rcu argument from init * API change * for all liburcu-cds* flavors. Signed-off-by: Mathieu Desnoyers --- rculfqueue.c | 6 ++---- tests/test_urcu_lfq.c | 9 +-------- tests/test_urcu_lfs.c | 2 -- urcu/rculfqueue.h | 10 +++------- urcu/rculfstack.h | 2 +- urcu/static/rculfqueue.h | 25 ++++++++++++++++--------- urcu/static/rculfstack.h | 6 +++++- 7 files changed, 28 insertions(+), 32 deletions(-) diff --git a/rculfqueue.c b/rculfqueue.c index 09b8587..c579e75 100644 --- a/rculfqueue.c +++ b/rculfqueue.c @@ -44,11 +44,9 @@ void cds_lfq_node_init_rcu(struct cds_lfq_node_rcu *node) _cds_lfq_node_init_rcu(node); } -void cds_lfq_init_rcu(struct cds_lfq_queue_rcu *q, - void queue_call_rcu(struct rcu_head *head, - void (*func)(struct rcu_head *head))) +void cds_lfq_init_rcu(struct cds_lfq_queue_rcu *q) { - _cds_lfq_init_rcu(q, queue_call_rcu); + _cds_lfq_init_rcu(q); } int cds_lfq_destroy_rcu(struct cds_lfq_queue_rcu *q) diff --git a/tests/test_urcu_lfq.c b/tests/test_urcu_lfq.c index b61a7d4..82a90b0 100644 --- a/tests/test_urcu_lfq.c +++ b/tests/test_urcu_lfq.c @@ -180,9 +180,7 @@ void *thr_enqueuer(void *_count) if (!node) goto fail; cds_lfq_node_init_rcu(node); - rcu_read_lock(); cds_lfq_enqueue_rcu(&q, node); - rcu_read_unlock(); nr_successful_enqueues++; if (unlikely(wdelay)) @@ -230,10 +228,7 @@ void *thr_dequeuer(void *_count) for (;;) { struct cds_lfq_node_rcu *node; - rcu_read_lock(); node = cds_lfq_dequeue_rcu(&q); - rcu_read_unlock(); - if (node) { defer_rcu(free, node); nr_successful_dequeues++; @@ -262,9 +257,7 @@ void test_end(struct cds_lfq_queue_rcu *q, unsigned long long *nr_dequeues) struct cds_lfq_node_rcu *node; do { - rcu_read_lock(); node = cds_lfq_dequeue_rcu(q); - rcu_read_unlock(); if (node) { free(node); /* no more concurrent access */ (*nr_dequeues)++; @@ -363,7 +356,7 @@ int main(int argc, char **argv) tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); count_enqueuer = malloc(2 * sizeof(*count_enqueuer) * nr_enqueuers); count_dequeuer = malloc(2 * sizeof(*count_dequeuer) * nr_dequeuers); - cds_lfq_init_rcu(&q, call_rcu); + cds_lfq_init_rcu(&q); next_aff = 0; diff --git a/tests/test_urcu_lfs.c b/tests/test_urcu_lfs.c index 252454d..a7f9af3 100644 --- a/tests/test_urcu_lfs.c +++ b/tests/test_urcu_lfs.c @@ -229,9 +229,7 @@ void *thr_dequeuer(void *_count) for (;;) { struct cds_lfs_node_rcu *node; - rcu_read_lock(); node = cds_lfs_pop_rcu(&s); - rcu_read_unlock(); if (node) { defer_rcu(free, node); nr_successful_dequeues++; diff --git a/urcu/rculfqueue.h b/urcu/rculfqueue.h index e1d64f1..1582694 100644 --- a/urcu/rculfqueue.h +++ b/urcu/rculfqueue.h @@ -39,8 +39,6 @@ struct cds_lfq_node_rcu { struct cds_lfq_queue_rcu { struct cds_lfq_node_rcu *head, *tail; - void (*queue_call_rcu)(struct rcu_head *head, - void (*func)(struct rcu_head *head)); }; #ifdef _LGPL_SOURCE @@ -80,9 +78,7 @@ struct cds_lfq_queue_rcu { #else /* !_LGPL_SOURCE */ extern void cds_lfq_node_init_rcu(struct cds_lfq_node_rcu *node); -extern void cds_lfq_init_rcu(struct cds_lfq_queue_rcu *q, - void queue_call_rcu(struct rcu_head *head, - void (*func)(struct rcu_head *head))); +extern void cds_lfq_init_rcu(struct cds_lfq_queue_rcu *q); /* * The queue should be emptied before calling destroy. * @@ -91,13 +87,13 @@ extern void cds_lfq_init_rcu(struct cds_lfq_queue_rcu *q, extern int cds_lfq_destroy_rcu(struct cds_lfq_queue_rcu *q); /* - * Should be called under rcu read lock critical section. + * Acts as a RCU reader. */ extern void cds_lfq_enqueue_rcu(struct cds_lfq_queue_rcu *q, struct cds_lfq_node_rcu *node); /* - * Should be called under rcu read lock critical section. + * Acts as a RCU reader. * * The caller must wait for a grace period to pass before freeing the returned * node or modifying the cds_lfq_node_rcu structure. diff --git a/urcu/rculfstack.h b/urcu/rculfstack.h index ad83dbe..f673952 100644 --- a/urcu/rculfstack.h +++ b/urcu/rculfstack.h @@ -71,7 +71,7 @@ extern void cds_lfs_init_rcu(struct cds_lfs_stack_rcu *s); extern void cds_lfs_push_rcu(struct cds_lfs_stack_rcu *s, struct cds_lfs_node_rcu *node); /* - * Should be called under rcu read lock critical section. + * Acts as a RCU reader. * * The caller must wait for a grace period to pass before freeing the returned * node or modifying the cds_lfs_node_rcu structure. diff --git a/urcu/static/rculfqueue.h b/urcu/static/rculfqueue.h index fea6110..99335c4 100644 --- a/urcu/static/rculfqueue.h +++ b/urcu/static/rculfqueue.h @@ -88,7 +88,7 @@ void rcu_free_dummy(struct cds_lfq_node_rcu *node) assert(node->dummy); dummy = caa_container_of(node, struct cds_lfq_node_rcu_dummy, parent); - dummy->q->queue_call_rcu(&dummy->head, free_dummy_cb); + call_rcu(&dummy->head, free_dummy_cb); } static inline @@ -109,13 +109,10 @@ void _cds_lfq_node_init_rcu(struct cds_lfq_node_rcu *node) } static inline -void _cds_lfq_init_rcu(struct cds_lfq_queue_rcu *q, - void queue_call_rcu(struct rcu_head *head, - void (*func)(struct rcu_head *head))) +void _cds_lfq_init_rcu(struct cds_lfq_queue_rcu *q) { q->tail = make_dummy(q, NULL); q->head = q->tail; - q->queue_call_rcu = queue_call_rcu; } /* @@ -136,7 +133,7 @@ int _cds_lfq_destroy_rcu(struct cds_lfq_queue_rcu *q) } /* - * Should be called under rcu read lock critical section. + * Acts as a RCU reader. */ static inline void _cds_lfq_enqueue_rcu(struct cds_lfq_queue_rcu *q, @@ -150,6 +147,7 @@ void _cds_lfq_enqueue_rcu(struct cds_lfq_queue_rcu *q, for (;;) { struct cds_lfq_node_rcu *tail, *next; + rcu_read_lock(); tail = rcu_dereference(q->tail); next = uatomic_cmpxchg(&tail->next, NULL, node); if (next == NULL) { @@ -159,6 +157,7 @@ void _cds_lfq_enqueue_rcu(struct cds_lfq_queue_rcu *q, * enqueue might beat us to it, that's fine). */ (void) uatomic_cmpxchg(&q->tail, tail, node); + rcu_read_unlock(); return; } else { /* @@ -166,6 +165,7 @@ void _cds_lfq_enqueue_rcu(struct cds_lfq_queue_rcu *q, * Help moving tail further and retry. */ (void) uatomic_cmpxchg(&q->tail, tail, next); + rcu_read_unlock(); continue; } } @@ -182,7 +182,7 @@ void enqueue_dummy(struct cds_lfq_queue_rcu *q) } /* - * Should be called under rcu read lock critical section. + * Acts as a RCU reader. * * The caller must wait for a grace period to pass before freeing the returned * node or modifying the cds_lfq_node_rcu structure. @@ -194,10 +194,13 @@ struct cds_lfq_node_rcu *_cds_lfq_dequeue_rcu(struct cds_lfq_queue_rcu *q) for (;;) { struct cds_lfq_node_rcu *head, *next; + rcu_read_lock(); head = rcu_dereference(q->head); next = rcu_dereference(head->next); - if (head->dummy && next == NULL) + if (head->dummy && next == NULL) { + rcu_read_unlock(); return NULL; /* empty */ + } /* * We never, ever allow dequeue to get to a state where * the queue is empty (we need at least one node in the @@ -209,13 +212,17 @@ struct cds_lfq_node_rcu *_cds_lfq_dequeue_rcu(struct cds_lfq_queue_rcu *q) enqueue_dummy(q); next = rcu_dereference(head->next); } - if (uatomic_cmpxchg(&q->head, head, next) != head) + if (uatomic_cmpxchg(&q->head, head, next) != head) { + rcu_read_unlock(); continue; /* Concurrently pushed. */ + } if (head->dummy) { /* Free dummy after grace period. */ rcu_free_dummy(head); + rcu_read_unlock(); continue; /* try again */ } + rcu_read_unlock(); return head; } } diff --git a/urcu/static/rculfstack.h b/urcu/static/rculfstack.h index ba26231..ed6b0d4 100644 --- a/urcu/static/rculfstack.h +++ b/urcu/static/rculfstack.h @@ -63,7 +63,7 @@ void _cds_lfs_push_rcu(struct cds_lfs_stack_rcu *s, struct cds_lfs_node_rcu *nod } /* - * Should be called under rcu read-side lock. + * Acts as a RCU reader. * * The caller must wait for a grace period to pass before freeing the returned * node or modifying the cds_lfs_node_rcu structure. @@ -76,18 +76,22 @@ _cds_lfs_pop_rcu(struct cds_lfs_stack_rcu *s) for (;;) { struct cds_lfs_node_rcu *head; + rcu_read_lock(); head = rcu_dereference(s->head); if (head) { struct cds_lfs_node_rcu *next = rcu_dereference(head->next); if (uatomic_cmpxchg(&s->head, head, next) == head) { + rcu_read_unlock(); return head; } else { /* Concurrent modification. Retry. */ + rcu_read_unlock(); continue; } } else { /* Empty stack */ + rcu_read_unlock(); return NULL; } } -- 2.34.1