Search code examples
catomicc11

Atomic structure in C?


I want to make the entire contents of a small C structure atomic, but the documentation appears to show that only primitive data types as fields within the struct can be made atomic.

For example, I want to do:

#include <stdint.h>
#include <stdbool.h>
#include <stdatomic.h>

typedef struct my_obj_s {
  int16_t a;
  int16_t b;
  bool is_initialized;
} my_obj_t;

_Atomic my_obj_t my_atomic_object;

but only appear to be able to do:

typedef struct my_obj_s {
  atomic_char16_t a;
  atomic_char16_t b;
  atomic_bool is_initialized;
} my_obj_t;

Is there no way to achieve atomicity on anything larger than a primitive data type (short of bracketing reads/writes in locks/mutexes/etc)?


Solution

  • Yes, you are allowed to use the _Atomic qualifier for structures.

    With these structures you then basically only have the restricted possibilities of access through the atomic_... type generic functions (or by structure assignment), you can't access the individual fields. The most useful of these functions is probably atomic_compare_exchange_weak.

    If your structure does not fit into a wide register, platforms usually implement these atomic types by using some kind of lock that is stored outside of your structure. If it does, they use the native capacities of the platform. Such properties may depend on your compiler options, in particular you'd have to ensure that these are the same for all your compiled objects.

    For gcc usually -march=native triggers the best features for that, for example the use of 128 bit native atomics if they are available.