Description
The following is a collection of compiler macros to provide atomic
access to integer and pointer-sized values.
The macros that have 'int' in the name will operate on pointers to
gint and guint. The macros with 'pointer' in the name will operate
on pointers to any pointer-sized value, including gsize. There is
no support for 64bit operations on platforms with 32bit pointers
because it is not generally possible to perform these operations
atomically.
The get, set and exchange operations for integers and pointers
nominally operate on gint and gpointer, respectively. Of the
arithmetic operations, the 'add' operation operates on (and returns)
signed integer values (gint and gssize) and the 'and', 'or', and
'xor' operations operate on (and return) unsigned integer values
(guint and gsize).
All of the operations act as a full compiler and (where appropriate)
hardware memory barrier. Acquire and release or producer and
consumer barrier semantics are not available through this API.
It is very important that all accesses to a particular integer or
pointer be performed using only this API and that different sizes of
operation are not mixed or used on overlapping memory regions. Never
read or assign directly from or to a value -- always use this API.
For simple reference counting purposes you should use
g_atomic_int_inc() and g_atomic_int_dec_and_test(). Other uses that
fall outside of simple reference counting patterns are prone to
subtle bugs and occasionally undefined behaviour. It is also worth
noting that since all of these operations require global
synchronisation of the entire machine, they can be quite slow. In
the case of performing multiple atomic operations it can often be
faster to simply acquire a mutex lock around the critical area,
perform the operations normally and then release the lock.
Functions
g_atomic_int_get ()
gint
g_atomic_int_get (const volatile gint *atomic);
Gets the current value of atomic
.
This call acts as a full compiler and hardware
memory barrier (before the get).
Returns
the value of the integer
Since: 2.4
g_atomic_int_set ()
void
g_atomic_int_set (volatile gint *atomic,
gint newval);
Sets the value of atomic
to newval
.
This call acts as a full compiler and hardware
memory barrier (after the set).
Since: 2.4
g_atomic_int_inc ()
void
g_atomic_int_inc (gint *atomic);
Increments the value of atomic
by 1.
Think of this operation as an atomic version of { *atomic += 1; }.
This call acts as a full compiler and hardware memory barrier.
Since: 2.4
g_atomic_int_dec_and_test ()
gboolean
g_atomic_int_dec_and_test (gint *atomic);
Decrements the value of atomic
by 1.
Think of this operation as an atomic version of
{ *atomic -= 1; return (*atomic == 0); }.
This call acts as a full compiler and hardware memory barrier.
Returns
TRUE if the resultant value is zero
Since: 2.4
g_atomic_int_compare_and_exchange ()
gboolean
g_atomic_int_compare_and_exchange (volatile gint *atomic,
gint oldval,
gint newval);
Compares atomic
to oldval
and, if equal, sets it to newval
.
If atomic
was not equal to oldval
then no change occurs.
This compare and exchange is done atomically.
Think of this operation as an atomic version of
{ if (*atomic == oldval) { *atomic = newval; return TRUE; } else return FALSE; }.
This call acts as a full compiler and hardware memory barrier.
Returns
TRUE if the exchange took place
Since: 2.4
g_atomic_int_add ()
gint
g_atomic_int_add (volatile gint *atomic,
gint val);
Atomically adds val
to the value of atomic
.
Think of this operation as an atomic version of
{ tmp = *atomic; *atomic += val; return tmp; }.
This call acts as a full compiler and hardware memory barrier.
Before version 2.30, this function did not return a value
(but g_atomic_int_exchange_and_add() did, and had the same meaning).
Returns
the value of atomic
before the add, signed
Since: 2.4
g_atomic_int_and ()
guint
g_atomic_int_and (volatile guint *atomic,
guint val);
Performs an atomic bitwise 'and' of the value of atomic
and val
,
storing the result back in atomic
.
This call acts as a full compiler and hardware memory barrier.
Think of this operation as an atomic version of
{ tmp = *atomic; *atomic &= val; return tmp; }.
Returns
the value of atomic
before the operation, unsigned
Since: 2.30
g_atomic_int_or ()
guint
g_atomic_int_or (volatile guint *atomic,
guint val);
Performs an atomic bitwise 'or' of the value of atomic
and val
,
storing the result back in atomic
.
Think of this operation as an atomic version of
{ tmp = *atomic; *atomic |= val; return tmp; }.
This call acts as a full compiler and hardware memory barrier.
Returns
the value of atomic
before the operation, unsigned
Since: 2.30
g_atomic_int_xor ()
guint
g_atomic_int_xor (volatile guint *atomic,
guint val);
Performs an atomic bitwise 'xor' of the value of atomic
and val
,
storing the result back in atomic
.
Think of this operation as an atomic version of
{ tmp = *atomic; *atomic ^= val; return tmp; }.
This call acts as a full compiler and hardware memory barrier.
Returns
the value of atomic
before the operation, unsigned
Since: 2.30
g_atomic_pointer_get ()
gpointer
g_atomic_pointer_get (const volatile void *atomic);
Gets the current value of atomic
.
This call acts as a full compiler and hardware
memory barrier (before the get).
Returns
the value of the pointer
Since: 2.4
g_atomic_pointer_set ()
void
g_atomic_pointer_set (volatile void *atomic,
gpointer newval);
Sets the value of atomic
to newval
.
This call acts as a full compiler and hardware
memory barrier (after the set).
Since: 2.4
g_atomic_pointer_compare_and_exchange ()
gboolean
g_atomic_pointer_compare_and_exchange (volatile void *atomic,
gpointer oldval,
gpointer newval);
Compares atomic
to oldval
and, if equal, sets it to newval
.
If atomic
was not equal to oldval
then no change occurs.
This compare and exchange is done atomically.
Think of this operation as an atomic version of
{ if (*atomic == oldval) { *atomic = newval; return TRUE; } else return FALSE; }.
This call acts as a full compiler and hardware memory barrier.
Returns
TRUE if the exchange took place
Since: 2.4
g_atomic_pointer_add ()
gssize
g_atomic_pointer_add (volatile void *atomic,
gssize val);
Atomically adds val
to the value of atomic
.
Think of this operation as an atomic version of
{ tmp = *atomic; *atomic += val; return tmp; }.
This call acts as a full compiler and hardware memory barrier.
Returns
the value of atomic
before the add, signed
Since: 2.30
g_atomic_pointer_and ()
gsize
g_atomic_pointer_and (volatile void *atomic,
gsize val);
Performs an atomic bitwise 'and' of the value of atomic
and val
,
storing the result back in atomic
.
Think of this operation as an atomic version of
{ tmp = *atomic; *atomic &= val; return tmp; }.
This call acts as a full compiler and hardware memory barrier.
Returns
the value of atomic
before the operation, unsigned
Since: 2.30
g_atomic_pointer_or ()
gsize
g_atomic_pointer_or (volatile void *atomic,
gsize val);
Performs an atomic bitwise 'or' of the value of atomic
and val
,
storing the result back in atomic
.
Think of this operation as an atomic version of
{ tmp = *atomic; *atomic |= val; return tmp; }.
This call acts as a full compiler and hardware memory barrier.
Returns
the value of atomic
before the operation, unsigned
Since: 2.30
g_atomic_pointer_xor ()
gsize
g_atomic_pointer_xor (volatile void *atomic,
gsize val);
Performs an atomic bitwise 'xor' of the value of atomic
and val
,
storing the result back in atomic
.
Think of this operation as an atomic version of
{ tmp = *atomic; *atomic ^= val; return tmp; }.
This call acts as a full compiler and hardware memory barrier.
Returns
the value of atomic
before the operation, unsigned
Since: 2.30
g_atomic_int_exchange_and_add ()
gint
g_atomic_int_exchange_and_add (volatile gint *atomic,
gint val);
g_atomic_int_exchange_and_add has been deprecated since version 2.30 and should not be used in newly-written code.
Use g_atomic_int_add() instead.
This function existed before g_atomic_int_add() returned the prior
value of the integer (which it now does). It is retained only for
compatibility reasons. Don't use this function in new code.
Returns
the value of atomic
before the add, signed
Since: 2.4