PostgreSQL Source Code git master
atomics.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * atomics.c
4 * Non-Inline parts of the atomics implementation
5 *
6 * Portions Copyright (c) 2013-2025, PostgreSQL Global Development Group
7 *
8 *
9 * IDENTIFICATION
10 * src/backend/port/atomics.c
11 *
12 *-------------------------------------------------------------------------
13 */
14#include "postgres.h"
15
16#include "miscadmin.h"
17#include "port/atomics.h"
18#include "storage/spin.h"
19
20
21#ifdef PG_HAVE_ATOMIC_U64_SIMULATION
22
23void
25{
26 StaticAssertDecl(sizeof(ptr->sema) >= sizeof(slock_t),
27 "size mismatch of atomic_uint64 vs slock_t");
28
29 SpinLockInit((slock_t *) &ptr->sema);
30 ptr->value = val_;
31}
32
33bool
35 uint64 *expected, uint64 newval)
36{
37 bool ret;
38
39 /*
40 * Do atomic op under a spinlock. It might look like we could just skip
41 * the cmpxchg if the lock isn't available, but that'd just emulate a
42 * 'weak' compare and swap. I.e. one that allows spurious failures. Since
43 * several algorithms rely on a strong variant and that is efficiently
44 * implementable on most major architectures let's emulate it here as
45 * well.
46 */
47 SpinLockAcquire((slock_t *) &ptr->sema);
48
49 /* perform compare/exchange logic */
50 ret = ptr->value == *expected;
51 *expected = ptr->value;
52 if (ret)
53 ptr->value = newval;
54
55 /* and release lock */
56 SpinLockRelease((slock_t *) &ptr->sema);
57
58 return ret;
59}
60
63{
64 uint64 oldval;
65
66 SpinLockAcquire((slock_t *) &ptr->sema);
67 oldval = ptr->value;
68 ptr->value += add_;
69 SpinLockRelease((slock_t *) &ptr->sema);
70 return oldval;
71}
72
73#endif /* PG_HAVE_ATOMIC_U64_SIMULATION */
uint64 pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
Definition: atomics.c:62
void pg_atomic_init_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 val_)
Definition: atomics.c:24
bool pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 *expected, uint64 newval)
Definition: atomics.c:34
int64_t int64
Definition: c.h:485
uint64_t uint64
Definition: c.h:489
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:893
#define newval
#define SpinLockInit(lock)
Definition: spin.h:57
#define SpinLockRelease(lock)
Definition: spin.h:61
#define SpinLockAcquire(lock)
Definition: spin.h:59
volatile uint64 value
Definition: fallback.h:29