[cpp-threads] Review comments on N2176 WRT dependency ordering

Peter Dimov pdimov at mmltd.net
Tue Apr 17 12:38:29 BST 2007


Paul E. McKenney wrote:
> On Mon, Apr 16, 2007 at 06:12:14PM +0300, Peter Dimov wrote:

>> N2195 proposes the following minimalistic approach:
>>
>> template< class T > inline T * atomic_load_address( T * const * p );
>> template< class T > inline T * atomic_load_address( T * const
>> volatile * p );
>
> I do like the template approach!
>
>> Returns: *p.
>>
>> Constraint: _Acquire only with respect to **p.
>
> OK -- but what about p->some_field?  Or does **p indicate any
> dereference of p?  I had been assuming the more restrictive mode.

**p denotes the entire object that *p refers to, including all of its 
fields.

In the dependency discussion paper, you write that a single level of 
indirection is not enough for the Linux kernel, but I don't see how you 
could make a multi-level primitive work on an Alpha. In:

r1 = x;
// rmb
r2 = r1->a;
// rmb
r3 = r2->b;

I believe that you need two rmb fences.

r1 = atomic_load_address( &x );
r2 = atomic_load_address( &r1->a );
r3 = r2->b;

can insert the two fences for you, but if the second atomic_load_address is 
an ordinary operation (somewhere in a translation unit far, far away), 
there's no way to insert a rmb after it.

>> Index-based dependencies are not supported.
>
> Why not?

Are they important enough? We can add a minimalistic index-based primitive 
along the lines of:

template<class T, class U> inline U* atomic_load_index( T const * pi, U * 
base );

Requires: T shall be integral.
Returns: base + *pi.
Constraint: _Acquire only with respect to base[ *pi ].

but it doesn't cover the complex cases where you want to index more than one 
array.




More information about the cpp-threads mailing list