Boost logo

Boost :

From: Bill Wade (bill.wade_at_[hidden])
Date: 2000-08-30 17:42:35

I'm inclined to believe you want a class, but don't support operator
notation. To me it is obvious that

  a.AtomicGet() + b.AtomicGet();

is probably not an atomic operation. With

  a + b;

I may easily overlook the fact that some locking should be done.

Note that if the underlying system doesn't have built in support for all of
your operations, you will likely want to associate some other object (a
mutex) with the counter, meaning that atomic_t won't be a scalar type

This leads to an interesting design question. If the underlying system has
good support for read,write and increment, but not add or exchange, should
you make the class with the smaller interface available? Note that if you
end up using a mutex for add, you probably need to use the same mutex for
increment, losing the opportunity to do a "fast" increment.

> -----Original Message-----
> From: William Kempf [mailto:sirwillard_at_[hidden]]
> Sent: Wednesday, August 30, 2000 5:05 PM
> To: boost_at_[hidden]
> Subject: [boost] Threads: Atomic Counter
> 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, gregod at, cpdaniel at, john at