Chapter 28. Concurrency
Prev | Part III. Extensions | Next

# Concurrency

## Design

### Interface to Locks and Mutexes

The file <ext/concurrence.h> contains all the higher-level constructs for playing with threads. In contrast to the atomics layer, the concurrence layer consists largely of types. All types are defined within `namespace __gnu_cxx`.

These types can be used in a portable manner, regardless of the specific environment. They are carefully designed to provide optimum efficiency and speed, abstracting out underlying thread calls and accesses when compiling for single-threaded situations (even on hosts that support multiple threads.)

The enumerated type `_Lock_policy` details the set of available locking policies: `_S_single`, `_S_mutex`, and `_S_atomic`.

- `_S_single`

  Indicates single-threaded code that does not need locking.

- `_S_mutex`

  Indicates multi-threaded code using thread-layer abstractions.

- `_S_atomic`

  Indicates multi-threaded code using atomic operations.

The compile-time constant `__default_lock_policy` is set to one of the three values above, depending on characteristics of the host environment and the current compilation flags.

Two more datatypes make up the rest of the interface: `__mutex`, and `__scoped_lock`.

The scoped lock idiom is well-discussed within the C++ community. This version takes a `__mutex` reference, and locks it during construction of `__scoped_locke` and unlocks it during destruction. This is an efficient way of locking critical sections, while retaining exception-safety.

### Interface to Atomic Functions

Two functions and one type form the base of atomic support.

The type `_Atomic_word` is a signed integral type supporting atomic operations.

The two functions functions are:

    _Atomic_word
    __exchange_and_add_dispatch(volatile _Atomic_word*, int);

    void
    __atomic_add_dispatch(volatile _Atomic_word*, int);

Both of these functions are declared in the header file <ext/atomicity.h>, and are in `namespace __gnu_cxx`.

- `__exchange_and_add_dispatch`

  Adds the second argument's value to the first argument. Returns the old value.

- `__atomic_add_dispatch`

  Adds the second argument's value to the first argument. Has no return value.

These functions forward to one of several specialized helper functions, depending on the circumstances. For instance,

`__exchange_and_add_dispatch`

Calls through to either of:

- `__exchange_and_add`

  Multi-thread version. Inlined if compiler-generated builtin atomics can be used, otherwise resolved at link time to a non-builtin code sequence.

- `__exchange_and_add_single`

  Single threaded version. Inlined.

However, only `__exchange_and_add_dispatch` and `__atomic_add_dispatch` should be used. These functions can be used in a portable manner, regardless of the specific environment. They are carefully designed to provide optimum efficiency and speed, abstracting out atomic accesses when they are not required (even on hosts that support compiler intrinsics for atomic operations.)

In addition, there are two macros

`_GLIBCXX_READ_MEM_BARRIER`

`_GLIBCXX_WRITE_MEM_BARRIER`

Which expand to the appropriate write and read barrier required by the host hardware and operating system.

Prev | Up | Next
Chapter 27. Demangling | Home | Implementation