[cpp-threads] Failed compare-and-swap

Paul E. McKenney paulmck at linux.vnet.ibm.com
Thu Aug 2 20:50:23 BST 2007


On Thu, Aug 02, 2007 at 11:33:15AM -0700, Lawrence Crowl wrote:
> Are there any objections to the following compare-and-swap?
> Basically, it adds another parameter specifying the memory
> synchronization for the load-only-write-did-not-happen case.
> 
> On 7/31/07, Lawrence Crowl <Lawrence at crowl.org> wrote:
> > Just to be clear on the evolving specification:
> >
> >    extern "C"
> >    bool atomic_compare_swap_explicit(
> >       volatile atomic_int* the_atomic,
> >       int* the_old_value,
> >       int the_new_value,
> >       memory_order failure_order,
> >       memory_order success_order );
> >
> >    bool atomic_int::compare_swap(
> >       int& the_old_value,
> >       int the_new_value,
> >       memory_order failure_order = memory_order_seq_cst,
> >       memory_order success_order = memory_order_seq_cst );

How about a "memory_order_unspecified", so that the failure_order
would by default follow the success_order?  The C++ definition would then
be as follows:

   bool atomic_int::compare_swap(
      int& the_old_value,
      int the_new_value,
      memory_order success_order = memory_order_seq_cst,
      memory_order failure_order = memory_order_unspecified );

If failure_order is memory_order_unspecified, compare_swap() takes
the value from success_order for the failure_order value.

For example:

	x.compare_swap(&old, new);

		Sequentially consistent compare_swap() operation.

	x.compare_swap(&old, new, memory_order_relaxed);

		Totally relaxed compare_swap() operation.

	x.compare_swap(&old, new, memory_order_seq_cst, memory_order_relaxed);

		Sequential consistency on success, relaxed on failure.
		This is appropriate when failure results in unconditional
		retry, and where failure is likely to occur.  (If failure
		is unlikely, then there is little penalty for sequential
		consistency on failure.)

> > The failure_order parameter applies when the write does not happen,
> > and may use the "read" subset of memory_order (relaxed, acquire,
> > seq_cst).

By default, the failure_order would follow the ordering specified for
the success_order.

> > The success_order parameter applies when the write does happen (and
> > hence the read also happened and may use any of the memory_order
> > values.
> >
> > (I chose the parameter order because one is more likely to weaken
> > failure_order than the success_order.)

But it is also reasonably likely that the user would weaken success_order
and want the same weakening of the failure order, right?  Also, I am
concerned about the following:

	x.compare_swap(&old, new, memory_order_relaxed);

This would -not- be a relaxed operation under your proposal, but would
instead be sequentially consistent on success and relaxed only on failure.
I believe that a natural reading of the above would lead the reader to
believe that the operation was relaxed on both success and failure.

Also, I believe that it is more natural for the success case to come
first in the argument list.

> > In the event of failure, there is still value dependence on the load.

Interesting -- where do I find the definition of "value dependence"?

							Thanx, Paul



More information about the cpp-threads mailing list