Page Speed Optimization Libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Public Member Functions | List of all members
net_instaweb::AtomicInt32 Class Reference

#include "atomic_int32.h"

Public Member Functions

 AtomicInt32 (int32 value)
int32 value () const
 Return the value currently stored. Has acquire semantics (see above).
void set_value (int32 value)
 Store value. Has release semantics (see above).
int32 NoBarrierIncrement (int32 amount)
int32 BarrierIncrement (int32 amount)
int32 CompareAndSwap (int32 expected_value, int32 new_value)

Detailed Description

An int32 flag that can be set atomically and be visible to other threads. Please be extra careful with this — it can go wrong in incomprehensible ways; most of the time, if you care about how the value of this flag relates to the value of other memory locations, you probably want to use a mutex instead.

In more detail: When communicating multiple values between threads, we need to rely on operations with acquire and release semantics. An example is something like this (first without atomic_int32): Writer thread: x_ = 5; x_ = 17; y_ = 3; Reader thread: y = y_; x = x_;

Here if the reader sees y=3, then it can still see either of x=17 OR x=5; either the writes to x_ and y_ or the reads of x_ and y_ can be reordered on some cpu architectures. Using atomic_int32 lets us protect against this:

Writer thread: x_ = 5; x_ = 17; atomic_int_.set_value(3); ///< release Reader thread: y = atomic_int_.value() // acquire x = x_;

Now if the reader sees y=3, x=17 and never 5. The release insures that set_value(3) happens after the stores to x_, and the acquire ensures that value() happens before the read of x_.

The important thing here is that without the acquire and release semantics (if atomic_int_ was an ordinary int variable, even a volatile one) loads and stores need not obey program order. Release semantics ensure that prior writes (according to program order) occur before the release operation. Acquire semantics ensure that subsequent reads (according to program order) occur after the acquire operation. If you don't have both guarantees, you must not assume anything about ordering constraints.

Note that Acquire and Release talk about how these operations relate to operations on other memory locations. All the operations on the AtomicInt32 behave as you would probably expect, though several of them (increment, CompareAndSwap) occur as atomic actions.

Member Function Documentation

int32 net_instaweb::AtomicInt32::BarrierIncrement ( int32  amount)

Atomically add an amount to the value stored, return the new value. Provides a full barrier — both acquire and release.

int32 net_instaweb::AtomicInt32::CompareAndSwap ( int32  expected_value,
int32  new_value 

Atomic compare and swap. If current value == expected_value, atomically replace it with new_value. Return the original value regardless of whether the swap occurred. Has release semantics as with set_value() (see above).

NOTE: does NOT have acquire semantics, so the value returned may not appear to be ordered with respect to subsequent reads of other memory locations – nor can we expect to see changes to other locations made by prior writers based on the read performed by CompareAndSwap. If you need acquire semantics, use the value() method and validate its result when you CompareAndSwap.

int32 net_instaweb::AtomicInt32::NoBarrierIncrement ( int32  amount)

Atomically add an amount to the value currently stored, return the new value. Has no ordering semantics with respect to operations on other memory locations.

The documentation for this class was generated from the following file: