|
Boost : |
From: Bill Wade (bill.wade_at_[hidden])
Date: 2000-08-31 16:25:39
> From: William Kempf [mailto:sirwillard_at_[hidden]]
> You aren't suggesting that exchange is not useful, however,
> are you? It's really the only portable way to read/write an atomic_t
> value. (I'm not distinguishing exchange() from get()/set() because
> they are equivalent functionality with different interface
> signatures.)
L-value exchange (i.e. swap) is very useful and usually not available in a
fast atomic-over-both-arguments form.
R-value exchange (Atomic get-old-value-and-set-new-value) is useful, but is
a different operation from get(), and I still don't see how to use it to
implement get().
In procedural terms:
// atomically return old value and set new value
int AtomicGetAndSet(int& lvalue, int new_value)
{
Lock(lvalue);
int result = lvalue;
lvalue = new_value;
Unlock(lvalue);
return result;
}
To me an atomic read looks like
int AtomicGet(int& lvalue)
{
Lock(lvalue);
int result = lvalue;
Unlock(lvalue);
return result;
}
I think (please correct me if I have this wrong) you're saying to rewrite
Get as
int AtomicGet(int& lvalue)
{
return GetAndSet(lvalue, lvalue);
}
But that doesn't work. If we expand the function call we see
int AtomicGet(int& a)
{
// Note that the second argument to GetAndSet is passed by value.
Simulate
// this by invoking copy constructor before locking.
int temp = a;
oops:
Lock(a);
int result = a;
a = temp;
Unlock(a);
return result;
}
If another thread does something (say Increment(a)) while Get() is at the
"oops" label, then Get will
return the incremented a (that is ok, we had no guarantee which a we would
get).
and put a back to its pre-incremented value (most certainly not ok for a
read).
In Win32 GetAndSet is named InterlockedExchange. The version of Get() that
works is a normal aligned 32-bit read (I sleep better if I make it a
volatile read).
Of course on Win32 you can write a working Get like this
int AtomicGet(int& a)
{
int result = 0;
InterlockedExchange(result, a);
return result;
}
But in this case the only thing InterlockedExchange did for you was to lock
result. To work it still needs integer copy construction to be atomic.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk