[ltt-dev] [RFC] Lock-free RCU stack for userspace RCU library

Paul E. McKenney paulmck at linux.vnet.ibm.com
Mon Jul 12 20:05:23 EDT 2010


On Mon, Jul 12, 2010 at 11:50:44AM -0400, Mathieu Desnoyers wrote:
> Hi,
> 
> I just did the lock-free stack, which end up being much simpler than the queue
> because there is no need for dummy head pointer. Comments are welcome.
> 
> Even though I did not do formal verification of the queue and stack, I feel
> sufficiently confident to push them in urcu mainline. I'll wait for feedback
> before cutting a release though. I also created test_urcu_lfq and test_urcu_lfs
> which will also be in the tree. They perform heavy enqueue/dequeue and push/pop
> to stress-test the algorithms. They check if the number of operations (e.g. push
> vs pop) balance.

This one looks OK.  You definitely need some comments stating that
pop() needs to refrain from touching the rcu_lfs_node until after an
RCU grace period elapses, though.  ;-)

							Thanx, Paul

> Thanks,
> 
> Mathieu
> 
> 
> /*
>  * rculfstack.h
>  *
>  * Userspace RCU library - Lock-Free RCU Stack
>  *
>  * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
>  *
>  * This library is free software; you can redistribute it and/or
>  * modify it under the terms of the GNU Lesser General Public
>  * License as published by the Free Software Foundation; either
>  * version 2.1 of the License, or (at your option) any later version.
>  *
>  * This library is distributed in the hope that it will be useful,
>  * but WITHOUT ANY WARRANTY; without even the implied warranty of
>  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>  * Lesser General Public License for more details.
>  *
>  * You should have received a copy of the GNU Lesser General Public
>  * License along with this library; if not, write to the Free Software
>  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>  */
> 
> struct rcu_lfs_node {
> 	struct rcu_lfs_node *next;
> };
> 
> struct rcu_lfs_stack {
> 	struct rcu_lfs_node *head;
> };
> 
> void rcu_lfs_node_init(struct rcu_lfs_node *node)
> {
> }
> 
> void rcu_lfs_init(struct rcu_lfs_stack *s)
> {
> 	s->head = NULL;
> }
> 
> void rcu_lfs_push(struct rcu_lfs_stack *s, struct rcu_lfs_node *node)
> {
> 	rcu_read_lock();
> 	for (;;) {
> 		struct rcu_lfs_node *head = rcu_dereference(s->head);
> 
> 		node->next = head;
> 		/*
> 		 * uatomic_cmpxchg() implicit memory barrier orders earlier
> 		 * stores to node before publication.
> 		 */
> 		if (uatomic_cmpxchg(&s->head, head, node) == head) {
> 			rcu_read_unlock();
> 			return;
> 		} else {
> 			/* Failure to prepend. Retry. */
> 			continue;
> 		}
> 	}
> }
> 
> struct rcu_lfs_node *
> rcu_lfs_pop(struct rcu_lfs_stack *s)
> {
> 	rcu_read_lock();
> 	for (;;) {
> 		struct rcu_lfs_node *head = rcu_dereference(s->head);
> 
> 		if (head) {
> 			struct rcu_lfs_node *next = rcu_dereference(head->next);
> 
> 			if (uatomic_cmpxchg(&s->head, head, next) == head) {
> 				rcu_read_unlock();
> 				return head;
> 			} else {
> 				/* Concurrent modification. Retry. */
> 				continue;
> 			}
> 		} else {
> 			/* Empty stack */
> 			rcu_read_unlock();
> 			return NULL;
> 		}
> 	}
> }
> 
> 
> -- 
> Mathieu Desnoyers
> Operating System Efficiency R&D Consultant
> EfficiOS Inc.
> http://www.efficios.com




More information about the lttng-dev mailing list