Boost logo

Boost :

From: William Kempf (sirwillard_at_[hidden])
Date: 2000-08-30 17:05:16


Well, the discussion on the Mutex and ConditionVariable is winding
down. Though we aren't done there, I think it's still appropriate to
now move on to the next topic. So, I'll start the ball rolling by
discussing atomic counters.

Atomic counters are integral types that can be manipulated through
atomic functions, functions gauranteed to execute from start to end
with out fear of pre-emption causing corruption. Many platforms have
native operations that allow atomic operations on native integral
types, but we can't rely on this being the case. So, we need a type
other than the built in integral types that we can build the
necessary synchronization into for platforms with out such atomic
operations.

The first question that comes to my mind is, should the atomic type
be a class with member functions, or an opaque type that's
implementation defined (like time_t). The opaque type approach is
more suitable for C libraries than C++ libraries, but the idea still
appeals to me. With this approach the atomic operations would be
stand alone functions. With the more traditional C++ approach the
operations would (likely) be member functions.

If we use a C++ class we'll need to consider supporting a full range
of integer arithematic. Most atomic counter classes I've seen in
other libraries do this. However, I'm personally against this! With
built in operators the programmer is tempted to do something like the
following:

atomic_counter c = 5;
atomic_counter c2 = 5;
c = c + c2 + 10;

The result here may not be the expected 20 since another thread may
interrupt between operator calls. For some psychological reason this
is less likely to occur with function calls. Most programmers
immediately comprehend that they may be interrupted between function
calls while they might not make the same correlation with operator
calls.

I think the Win32 API provides most of the atomic operations we'd
want. They are:

Increment - Increments the counter by one.
Decrement - Decrements the counter by one.
Add - Adds an integral value to the counter (so subtraction is
supported by passing a negative integral value).
Exchange - Exchanges the counter with an integral value (or vice
versa).
CompareExchange - Compares the counter with an integral value and if
not equal exchanges with another integral value.

Multiplication and division aren't supported, but I don't think this
is something that needs support. Atomic counters aren't normally
used for arithematic types, but instead are usually used for
reference counting and tracking of flags.

Possible interface:

typedef ... atomic_t;
long increment(atomic_t& dest);
long decrement(atomic_t& dest);
long add(atomic_t& dest, long value);
long add(atomic_t& dest, const atomic_t& value);
long exchange(atomic_t& dest, long value);
long exchange(long& value, const atomic_t& value); // Note 1
long compare_exchange(atomic_t& dest, long compare, long value);

// Note 1: only needed if atomic_t isn't a long

Very little thought has gone into this. I'm just brainstorming in
order to open up discussion on this topic.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk