The Atomic::Counter class is an atomic counter. The counter is a signed integer with a
useful range of 31 bits (see Figure 7.1). Assume this is true when writing cross platform
code. Don’t rely on the fact that on some processors the atomic counter range is 32 bits.
All operations are implemented in assembler and guaranteed to be executed atomically
(i.e: as if it was one unsecable instruction). Atomic counters can be used in
single threaded as well as in multi-threaded applications. The atomicity of the
operations guarantees that the counter is modified and eventually tested without race
conditions.
On some processors (Sparc to not name them) there are only some rudimentary
atomic support instructions, and the implementation had to be done using spinlock
techniques. This influences:
-
Performance:
- Spinlocks are basically while loops. They consume CPU resources
waiting on a lock to be released if the counter is already in use. This lock
must then be acquired to perform the actual computation. The assembler
implementation tries to minimize the instruction number to keep the cost of
data protection as low as possible.
-
Range:
- The lock information costs one bit, taken from the counter. Thus the
guaranteed cross platform useful range of an atomic counter is 31 bits.
Synopsis
#include <lyric/Atomic.Counter.hpp>
class Atomic::Counter
{
public:
~Atomic::Counter ();
Atomic::Counter (int32 val = 0);
static Range<int32> range ();
void inc ();
void dec ();
bool inctz ();
bool dectz ();
private:
// Disable cloning
Atomic::Counter (const Atomic::Counter& counter);
Atomic::Counter& operator = (const Atomic::Counter& counter);
};
Description
-
˜Atomic::Counter () -
Destroys this atomic counter, releasing all used resources.
-
Atomic::Counter (uint32 val = 0) -
Constructs this atomic counter. The optional value argument can be given to
set the initial value of this counter. Without the initial value argument, this
atomic counter is initialized to zero.
-
Range<int32> range () static -
Returns the cross-platform useful range of an atomic counter. See Section 6.6.
The returned range stores the smallest 31 bit netagive integer as minimum,
and the largest 31 bit positive integer as maximum. However, during the use
of an atomic counter there is no enforced range checking: the returned range
is informative.
-
void inc () -
Atomically increases this counter by one.
-
void dec () -
Atomically decreases this counter by one.
-
bool inctz () -
Atomically increases this counter by one and tests if the resulting value
stored in this counter is zero. Returns true if this counter stores zero after
the increment, false if not.
-
bool dectz () -
Atomically decreases this counter by one and tests if the resulting value
stored in this counter is zero. Returns true if this counter stores zero after
the decrement, false if not.