PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
fallback.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pg_atomic_flag
 
struct  pg_atomic_uint32
 
struct  pg_atomic_uint64
 

Macros

#define PG_HAVE_MEMORY_BARRIER_EMULATION
 
#define pg_memory_barrier_impl   pg_spinlock_barrier
 
#define PG_HAVE_COMPILER_BARRIER_EMULATION
 
#define pg_compiler_barrier_impl   pg_extern_compiler_barrier
 
#define PG_HAVE_ATOMIC_FLAG_SIMULATION
 
#define PG_HAVE_ATOMIC_FLAG_SUPPORT
 
#define PG_HAVE_ATOMIC_U32_SIMULATION
 
#define PG_HAVE_ATOMIC_U32_SUPPORT
 
#define PG_HAVE_ATOMIC_U64_SIMULATION
 
#define PG_HAVE_ATOMIC_U64_SUPPORT
 
#define PG_HAVE_ATOMIC_INIT_FLAG
 
#define PG_HAVE_ATOMIC_TEST_SET_FLAG
 
#define PG_HAVE_ATOMIC_CLEAR_FLAG
 
#define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG
 
#define PG_HAVE_ATOMIC_INIT_U32
 
#define PG_HAVE_ATOMIC_WRITE_U32
 
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
 
#define PG_HAVE_ATOMIC_FETCH_ADD_U32
 
#define PG_HAVE_ATOMIC_INIT_U64
 
#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64
 
#define PG_HAVE_ATOMIC_FETCH_ADD_U64
 

Typedefs

typedef struct pg_atomic_flag pg_atomic_flag
 
typedef struct pg_atomic_uint32 pg_atomic_uint32
 
typedef struct pg_atomic_uint64 pg_atomic_uint64
 

Functions

void pg_spinlock_barrier (void)
 
void pg_extern_compiler_barrier (void)
 
void pg_atomic_init_flag_impl (volatile pg_atomic_flag *ptr)
 
bool pg_atomic_test_set_flag_impl (volatile pg_atomic_flag *ptr)
 
void pg_atomic_clear_flag_impl (volatile pg_atomic_flag *ptr)
 
static bool pg_atomic_unlocked_test_flag_impl (volatile pg_atomic_flag *ptr)
 
void pg_atomic_init_u32_impl (volatile pg_atomic_uint32 *ptr, uint32 val_)
 
void pg_atomic_write_u32_impl (volatile pg_atomic_uint32 *ptr, uint32 val)
 
bool pg_atomic_compare_exchange_u32_impl (volatile pg_atomic_uint32 *ptr, uint32 *expected, uint32 newval)
 
uint32 pg_atomic_fetch_add_u32_impl (volatile pg_atomic_uint32 *ptr, int32 add_)
 
void pg_atomic_init_u64_impl (volatile pg_atomic_uint64 *ptr, uint64 val_)
 
bool pg_atomic_compare_exchange_u64_impl (volatile pg_atomic_uint64 *ptr, uint64 *expected, uint64 newval)
 
uint64 pg_atomic_fetch_add_u64_impl (volatile pg_atomic_uint64 *ptr, int64 add_)
 

Macro Definition Documentation

#define pg_compiler_barrier_impl   pg_extern_compiler_barrier

Definition at line 50 of file fallback.h.

#define PG_HAVE_ATOMIC_CLEAR_FLAG

Definition at line 131 of file fallback.h.

#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32

Definition at line 157 of file fallback.h.

#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64

Definition at line 172 of file fallback.h.

#define PG_HAVE_ATOMIC_FETCH_ADD_U32

Definition at line 161 of file fallback.h.

#define PG_HAVE_ATOMIC_FETCH_ADD_U64

Definition at line 176 of file fallback.h.

#define PG_HAVE_ATOMIC_FLAG_SIMULATION

Definition at line 67 of file fallback.h.

#define PG_HAVE_ATOMIC_FLAG_SUPPORT

Definition at line 68 of file fallback.h.

#define PG_HAVE_ATOMIC_INIT_FLAG

Definition at line 125 of file fallback.h.

#define PG_HAVE_ATOMIC_INIT_U32

Definition at line 151 of file fallback.h.

#define PG_HAVE_ATOMIC_INIT_U64

Definition at line 169 of file fallback.h.

#define PG_HAVE_ATOMIC_TEST_SET_FLAG

Definition at line 128 of file fallback.h.

#define PG_HAVE_ATOMIC_U32_SIMULATION

Definition at line 89 of file fallback.h.

#define PG_HAVE_ATOMIC_U32_SUPPORT

Definition at line 91 of file fallback.h.

#define PG_HAVE_ATOMIC_U64_SIMULATION

Definition at line 107 of file fallback.h.

#define PG_HAVE_ATOMIC_U64_SUPPORT

Definition at line 109 of file fallback.h.

#define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG

Definition at line 134 of file fallback.h.

#define PG_HAVE_ATOMIC_WRITE_U32

Definition at line 154 of file fallback.h.

#define PG_HAVE_COMPILER_BARRIER_EMULATION

Definition at line 48 of file fallback.h.

#define PG_HAVE_MEMORY_BARRIER_EMULATION

Definition at line 32 of file fallback.h.

#define pg_memory_barrier_impl   pg_spinlock_barrier

Definition at line 35 of file fallback.h.

Typedef Documentation

Function Documentation

void pg_atomic_clear_flag_impl ( volatile pg_atomic_flag ptr)

Definition at line 80 of file atomics.c.

References S_UNLOCK, and pg_atomic_flag::sema.

Referenced by pg_atomic_clear_flag().

81 {
82  S_UNLOCK((slock_t *) &ptr->sema);
83 }
int slock_t
Definition: s_lock.h:888
#define S_UNLOCK(lock)
Definition: s_lock.h:896
bool pg_atomic_compare_exchange_u32_impl ( volatile pg_atomic_uint32 ptr,
uint32 expected,
uint32  newval 
)

Definition at line 120 of file atomics.c.

References newval, pg_atomic_uint32::sema, SpinLockAcquire, SpinLockRelease, and pg_atomic_uint32::value.

Referenced by pg_atomic_compare_exchange_u32().

122 {
123  bool ret;
124 
125  /*
126  * Do atomic op under a spinlock. It might look like we could just skip
127  * the cmpxchg if the lock isn't available, but that'd just emulate a
128  * 'weak' compare and swap. I.e. one that allows spurious failures. Since
129  * several algorithms rely on a strong variant and that is efficiently
130  * implementable on most major architectures let's emulate it here as
131  * well.
132  */
133  SpinLockAcquire((slock_t *) &ptr->sema);
134 
135  /* perform compare/exchange logic */
136  ret = ptr->value == *expected;
137  *expected = ptr->value;
138  if (ret)
139  ptr->value = newval;
140 
141  /* and release lock */
142  SpinLockRelease((slock_t *) &ptr->sema);
143 
144  return ret;
145 }
int slock_t
Definition: s_lock.h:888
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
#define newval
bool pg_atomic_compare_exchange_u64_impl ( volatile pg_atomic_uint64 ptr,
uint64 *  expected,
uint64  newval 
)

Definition at line 183 of file atomics.c.

References newval, pg_atomic_uint64::sema, SpinLockAcquire, SpinLockRelease, and pg_atomic_uint64::value.

Referenced by pg_atomic_compare_exchange_u64(), and pg_atomic_read_u64_impl().

185 {
186  bool ret;
187 
188  /*
189  * Do atomic op under a spinlock. It might look like we could just skip
190  * the cmpxchg if the lock isn't available, but that'd just emulate a
191  * 'weak' compare and swap. I.e. one that allows spurious failures. Since
192  * several algorithms rely on a strong variant and that is efficiently
193  * implementable on most major architectures let's emulate it here as
194  * well.
195  */
196  SpinLockAcquire((slock_t *) &ptr->sema);
197 
198  /* perform compare/exchange logic */
199  ret = ptr->value == *expected;
200  *expected = ptr->value;
201  if (ret)
202  ptr->value = newval;
203 
204  /* and release lock */
205  SpinLockRelease((slock_t *) &ptr->sema);
206 
207  return ret;
208 }
int slock_t
Definition: s_lock.h:888
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
#define newval
uint32 pg_atomic_fetch_add_u32_impl ( volatile pg_atomic_uint32 ptr,
int32  add_ 
)

Definition at line 148 of file atomics.c.

References pg_atomic_uint32::sema, SpinLockAcquire, SpinLockRelease, and pg_atomic_uint32::value.

Referenced by pg_atomic_fetch_add_u32().

149 {
150  uint32 oldval;
151 
152  SpinLockAcquire((slock_t *) &ptr->sema);
153  oldval = ptr->value;
154  ptr->value += add_;
155  SpinLockRelease((slock_t *) &ptr->sema);
156  return oldval;
157 }
int slock_t
Definition: s_lock.h:888
#define SpinLockAcquire(lock)
Definition: spin.h:62
unsigned int uint32
Definition: c.h:258
#define SpinLockRelease(lock)
Definition: spin.h:64
uint64 pg_atomic_fetch_add_u64_impl ( volatile pg_atomic_uint64 ptr,
int64  add_ 
)

Definition at line 211 of file atomics.c.

References pg_atomic_uint64::sema, SpinLockAcquire, SpinLockRelease, and pg_atomic_uint64::value.

Referenced by pg_atomic_fetch_add_u64().

212 {
213  uint64 oldval;
214 
215  SpinLockAcquire((slock_t *) &ptr->sema);
216  oldval = ptr->value;
217  ptr->value += add_;
218  SpinLockRelease((slock_t *) &ptr->sema);
219  return oldval;
220 }
int slock_t
Definition: s_lock.h:888
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
void pg_atomic_init_flag_impl ( volatile pg_atomic_flag ptr)

Definition at line 55 of file atomics.c.

References s_init_lock_sema(), pg_atomic_flag::sema, SpinLockInit, and StaticAssertStmt.

Referenced by pg_atomic_init_flag().

56 {
57  StaticAssertStmt(sizeof(ptr->sema) >= sizeof(slock_t),
58  "size mismatch of atomic_flag vs slock_t");
59 
60 #ifndef HAVE_SPINLOCKS
61 
62  /*
63  * NB: If we're using semaphore based TAS emulation, be careful to use a
64  * separate set of semaphores. Otherwise we'd get in trouble if an atomic
65  * var would be manipulated while spinlock is held.
66  */
67  s_init_lock_sema((slock_t *) &ptr->sema, true);
68 #else
69  SpinLockInit((slock_t *) &ptr->sema);
70 #endif
71 }
int slock_t
Definition: s_lock.h:888
#define SpinLockInit(lock)
Definition: spin.h:60
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:746
void s_init_lock_sema(volatile slock_t *lock, bool nested)
Definition: spin.c:107
void pg_atomic_init_u32_impl ( volatile pg_atomic_uint32 ptr,
uint32  val_ 
)

Definition at line 89 of file atomics.c.

References s_init_lock_sema(), pg_atomic_uint32::sema, SpinLockInit, StaticAssertStmt, and pg_atomic_uint32::value.

Referenced by pg_atomic_init_u32().

90 {
91  StaticAssertStmt(sizeof(ptr->sema) >= sizeof(slock_t),
92  "size mismatch of atomic_uint32 vs slock_t");
93 
94  /*
95  * If we're using semaphore based atomic flags, be careful about nested
96  * usage of atomics while a spinlock is held.
97  */
98 #ifndef HAVE_SPINLOCKS
99  s_init_lock_sema((slock_t *) &ptr->sema, true);
100 #else
101  SpinLockInit((slock_t *) &ptr->sema);
102 #endif
103  ptr->value = val_;
104 }
int slock_t
Definition: s_lock.h:888
#define SpinLockInit(lock)
Definition: spin.h:60
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:746
void s_init_lock_sema(volatile slock_t *lock, bool nested)
Definition: spin.c:107
void pg_atomic_init_u64_impl ( volatile pg_atomic_uint64 ptr,
uint64  val_ 
)

Definition at line 165 of file atomics.c.

References s_init_lock_sema(), pg_atomic_uint64::sema, SpinLockInit, StaticAssertStmt, and pg_atomic_uint64::value.

Referenced by pg_atomic_init_u64().

166 {
167  StaticAssertStmt(sizeof(ptr->sema) >= sizeof(slock_t),
168  "size mismatch of atomic_uint64 vs slock_t");
169 
170  /*
171  * If we're using semaphore based atomic flags, be careful about nested
172  * usage of atomics while a spinlock is held.
173  */
174 #ifndef HAVE_SPINLOCKS
175  s_init_lock_sema((slock_t *) &ptr->sema, true);
176 #else
177  SpinLockInit((slock_t *) &ptr->sema);
178 #endif
179  ptr->value = val_;
180 }
int slock_t
Definition: s_lock.h:888
#define SpinLockInit(lock)
Definition: spin.h:60
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:746
void s_init_lock_sema(volatile slock_t *lock, bool nested)
Definition: spin.c:107
bool pg_atomic_test_set_flag_impl ( volatile pg_atomic_flag ptr)

Definition at line 74 of file atomics.c.

References pg_atomic_flag::sema, and TAS.

Referenced by pg_atomic_test_set_flag().

75 {
76  return TAS((slock_t *) &ptr->sema);
77 }
int slock_t
Definition: s_lock.h:888
#define TAS(lock)
Definition: s_lock.h:898
static bool pg_atomic_unlocked_test_flag_impl ( volatile pg_atomic_flag ptr)
inlinestatic

Definition at line 136 of file fallback.h.

Referenced by pg_atomic_unlocked_test_flag().

137 {
138  /*
139  * Can't do this efficiently in the semaphore based implementation - we'd
140  * have to try to acquire the semaphore - so always return true. That's
141  * correct, because this is only an unlocked test anyway. Do this in the
142  * header so compilers can optimize the test away.
143  */
144  return true;
145 }
void pg_atomic_write_u32_impl ( volatile pg_atomic_uint32 ptr,
uint32  val 
)

Definition at line 107 of file atomics.c.

References pg_atomic_uint32::sema, SpinLockAcquire, SpinLockRelease, val, and pg_atomic_uint32::value.

Referenced by pg_atomic_write_u32().

108 {
109  /*
110  * One might think that an unlocked write doesn't need to acquire the
111  * spinlock, but one would be wrong. Even an unlocked write has to cause a
112  * concurrent pg_atomic_compare_exchange_u32() (et al) to fail.
113  */
114  SpinLockAcquire((slock_t *) &ptr->sema);
115  ptr->value = val;
116  SpinLockRelease((slock_t *) &ptr->sema);
117 }
int slock_t
Definition: s_lock.h:888
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define SpinLockRelease(lock)
Definition: spin.h:64
long val
Definition: informix.c:689
void pg_extern_compiler_barrier ( void  )

Definition at line 45 of file atomics.c.

46 {
47  /* do nothing */
48 }
void pg_spinlock_barrier ( void  )

Definition at line 29 of file atomics.c.

References PostmasterPid.

30 {
31  /*
32  * NB: we have to be reentrant here, some barriers are placed in signal
33  * handlers.
34  *
35  * We use kill(0) for the fallback barrier as we assume that kernels on
36  * systems old enough to require fallback barrier support will include an
37  * appropriate barrier while checking the existence of the postmaster pid.
38  */
39  (void) kill(PostmasterPid, 0);
40 }
pid_t PostmasterPid
Definition: globals.c:87