atomics.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. /*-------------------------------------------------------------------------
  2. *
  3. * atomics.h
  4. * Atomic operations.
  5. *
  6. * Hardware and compiler dependent functions for manipulating memory
  7. * atomically and dealing with cache coherency. Used to implement locking
  8. * facilities and lockless algorithms/data structures.
  9. *
  10. * To bring up postgres on a platform/compiler at the very least
  11. * implementations for the following operations should be provided:
  12. * * pg_compiler_barrier(), pg_write_barrier(), pg_read_barrier()
  13. * * pg_atomic_compare_exchange_u32(), pg_atomic_fetch_add_u32()
  14. * * pg_atomic_test_set_flag(), pg_atomic_init_flag(), pg_atomic_clear_flag()
  15. * * PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY should be defined if appropriate.
  16. *
  17. * There exist generic, hardware independent, implementations for several
  18. * compilers which might be sufficient, although possibly not optimal, for a
  19. * new platform. If no such generic implementation is available spinlocks (or
  20. * even OS provided semaphores) will be used to implement the API.
  21. *
  22. * Implement _u64 atomics if and only if your platform can use them
  23. * efficiently (and obviously correctly).
  24. *
  25. * Use higher level functionality (lwlocks, spinlocks, heavyweight locks)
  26. * whenever possible. Writing correct code using these facilities is hard.
  27. *
  28. * For an introduction to using memory barriers within the PostgreSQL backend,
  29. * see src/backend/storage/lmgr/README.barrier
  30. *
  31. * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  32. * Portions Copyright (c) 1994, Regents of the University of California
  33. *
  34. * src/include/port/atomics.h
  35. *
  36. *-------------------------------------------------------------------------
  37. */
  38. #ifndef ATOMICS_H
  39. #define ATOMICS_H
  40. #ifdef FRONTEND
  41. #error "atomics.h may not be included from frontend code"
  42. #endif
  43. #define INSIDE_ATOMICS_H
  44. #include <limits.h>
  45. /*
  46. * First a set of architecture specific files is included.
  47. *
  48. * These files can provide the full set of atomics or can do pretty much
  49. * nothing if all the compilers commonly used on these platforms provide
  50. * usable generics.
  51. *
  52. * Don't add an inline assembly of the actual atomic operations if all the
  53. * common implementations of your platform provide intrinsics. Intrinsics are
  54. * much easier to understand and potentially support more architectures.
  55. *
  56. * It will often make sense to define memory barrier semantics here, since
  57. * e.g. generic compiler intrinsics for x86 memory barriers can't know that
  58. * postgres doesn't need x86 read/write barriers do anything more than a
  59. * compiler barrier.
  60. *
  61. */
  62. #if defined(__arm__) || defined(__arm) || \
  63. defined(__aarch64__) || defined(__aarch64)
  64. #include "port/atomics/arch-arm.h"
  65. #elif defined(__i386__) || defined(__i386) || defined(__x86_64__)
  66. #include "port/atomics/arch-x86.h"
  67. #elif defined(__ia64__) || defined(__ia64)
  68. #include "port/atomics/arch-ia64.h"
  69. #elif defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
  70. #include "port/atomics/arch-ppc.h"
  71. #elif defined(__hppa) || defined(__hppa__)
  72. #include "port/atomics/arch-hppa.h"
  73. #endif
  74. /*
  75. * Compiler specific, but architecture independent implementations.
  76. *
  77. * Provide architecture independent implementations of the atomic
  78. * facilities. At the very least compiler barriers should be provided, but a
  79. * full implementation of
  80. * * pg_compiler_barrier(), pg_write_barrier(), pg_read_barrier()
  81. * * pg_atomic_compare_exchange_u32(), pg_atomic_fetch_add_u32()
  82. * using compiler intrinsics are a good idea.
  83. */
  84. /*
  85. * gcc or compatible, including clang and icc. Exclude xlc. The ppc64le "IBM
  86. * XL C/C++ for Linux, V13.1.2" emulates gcc, but __sync_lock_test_and_set()
  87. * of one-byte types elicits SIGSEGV. That bug was gone by V13.1.5 (2016-12).
  88. */
  89. #if (defined(__GNUC__) || defined(__INTEL_COMPILER)) && !(defined(__IBMC__) || defined(__IBMCPP__))
  90. #include "port/atomics/generic-gcc.h"
  91. #elif defined(_MSC_VER)
  92. #include "port/atomics/generic-msvc.h"
  93. #elif defined(__hpux) && defined(__ia64) && !defined(__GNUC__)
  94. #include "port/atomics/generic-acc.h"
  95. #elif defined(__SUNPRO_C) && !defined(__GNUC__)
  96. #include "port/atomics/generic-sunpro.h"
  97. #else
  98. /*
  99. * Unsupported compiler, we'll likely use slower fallbacks... At least
  100. * compiler barriers should really be provided.
  101. */
  102. #endif
  103. /*
  104. * Provide a full fallback of the pg_*_barrier(), pg_atomic**_flag and
  105. * pg_atomic_* APIs for platforms without sufficient spinlock and/or atomics
  106. * support. In the case of spinlock backed atomics the emulation is expected
  107. * to be efficient, although less so than native atomics support.
  108. */
  109. #include "port/atomics/fallback.h"
  110. /*
  111. * Provide additional operations using supported infrastructure. These are
  112. * expected to be efficient if the underlying atomic operations are efficient.
  113. */
  114. #include "port/atomics/generic.h"
  115. /*
  116. * pg_compiler_barrier - prevent the compiler from moving code across
  117. *
  118. * A compiler barrier need not (and preferably should not) emit any actual
  119. * machine code, but must act as an optimization fence: the compiler must not
  120. * reorder loads or stores to main memory around the barrier. However, the
  121. * CPU may still reorder loads or stores at runtime, if the architecture's
  122. * memory model permits this.
  123. */
  124. #define pg_compiler_barrier() pg_compiler_barrier_impl()
  125. /*
  126. * pg_memory_barrier - prevent the CPU from reordering memory access
  127. *
  128. * A memory barrier must act as a compiler barrier, and in addition must
  129. * guarantee that all loads and stores issued prior to the barrier are
  130. * completed before any loads or stores issued after the barrier. Unless
  131. * loads and stores are totally ordered (which is not the case on most
  132. * architectures) this requires issuing some sort of memory fencing
  133. * instruction.
  134. */
  135. #define pg_memory_barrier() pg_memory_barrier_impl()
  136. /*
  137. * pg_(read|write)_barrier - prevent the CPU from reordering memory access
  138. *
  139. * A read barrier must act as a compiler barrier, and in addition must
  140. * guarantee that any loads issued prior to the barrier are completed before
  141. * any loads issued after the barrier. Similarly, a write barrier acts
  142. * as a compiler barrier, and also orders stores. Read and write barriers
  143. * are thus weaker than a full memory barrier, but stronger than a compiler
  144. * barrier. In practice, on machines with strong memory ordering, read and
  145. * write barriers may require nothing more than a compiler barrier.
  146. */
  147. #define pg_read_barrier() pg_read_barrier_impl()
  148. #define pg_write_barrier() pg_write_barrier_impl()
  149. /*
  150. * Spinloop delay - Allow CPU to relax in busy loops
  151. */
  152. #define pg_spin_delay() pg_spin_delay_impl()
  153. /*
  154. * pg_atomic_init_flag - initialize atomic flag.
  155. *
  156. * No barrier semantics.
  157. */
  158. static inline void
  159. pg_atomic_init_flag(volatile pg_atomic_flag *ptr)
  160. {
  161. pg_atomic_init_flag_impl(ptr);
  162. }
  163. /*
  164. * pg_atomic_test_set_flag - TAS()
  165. *
  166. * Returns true if the flag has successfully been set, false otherwise.
  167. *
  168. * Acquire (including read barrier) semantics.
  169. */
  170. static inline bool
  171. pg_atomic_test_set_flag(volatile pg_atomic_flag *ptr)
  172. {
  173. return pg_atomic_test_set_flag_impl(ptr);
  174. }
  175. /*
  176. * pg_atomic_unlocked_test_flag - Check if the lock is free
  177. *
  178. * Returns true if the flag currently is not set, false otherwise.
  179. *
  180. * No barrier semantics.
  181. */
  182. static inline bool
  183. pg_atomic_unlocked_test_flag(volatile pg_atomic_flag *ptr)
  184. {
  185. return pg_atomic_unlocked_test_flag_impl(ptr);
  186. }
  187. /*
  188. * pg_atomic_clear_flag - release lock set by TAS()
  189. *
  190. * Release (including write barrier) semantics.
  191. */
  192. static inline void
  193. pg_atomic_clear_flag(volatile pg_atomic_flag *ptr)
  194. {
  195. pg_atomic_clear_flag_impl(ptr);
  196. }
  197. /*
  198. * pg_atomic_init_u32 - initialize atomic variable
  199. *
  200. * Has to be done before any concurrent usage..
  201. *
  202. * No barrier semantics.
  203. */
  204. static inline void
  205. pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
  206. {
  207. AssertPointerAlignment(ptr, 4);
  208. pg_atomic_init_u32_impl(ptr, val);
  209. }
  210. /*
  211. * pg_atomic_read_u32 - unlocked read from atomic variable.
  212. *
  213. * The read is guaranteed to return a value as it has been written by this or
  214. * another process at some point in the past. There's however no cache
  215. * coherency interaction guaranteeing the value hasn't since been written to
  216. * again.
  217. *
  218. * No barrier semantics.
  219. */
  220. static inline uint32
  221. pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
  222. {
  223. AssertPointerAlignment(ptr, 4);
  224. return pg_atomic_read_u32_impl(ptr);
  225. }
  226. /*
  227. * pg_atomic_write_u32 - write to atomic variable.
  228. *
  229. * The write is guaranteed to succeed as a whole, i.e. it's not possible to
  230. * observe a partial write for any reader. Note that this correctly interacts
  231. * with pg_atomic_compare_exchange_u32, in contrast to
  232. * pg_atomic_unlocked_write_u32().
  233. *
  234. * No barrier semantics.
  235. */
  236. static inline void
  237. pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
  238. {
  239. AssertPointerAlignment(ptr, 4);
  240. pg_atomic_write_u32_impl(ptr, val);
  241. }
  242. /*
  243. * pg_atomic_unlocked_write_u32 - unlocked write to atomic variable.
  244. *
  245. * The write is guaranteed to succeed as a whole, i.e. it's not possible to
  246. * observe a partial write for any reader. But note that writing this way is
  247. * not guaranteed to correctly interact with read-modify-write operations like
  248. * pg_atomic_compare_exchange_u32. This should only be used in cases where
  249. * minor performance regressions due to atomics emulation are unacceptable.
  250. *
  251. * No barrier semantics.
  252. */
  253. static inline void
  254. pg_atomic_unlocked_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
  255. {
  256. AssertPointerAlignment(ptr, 4);
  257. pg_atomic_unlocked_write_u32_impl(ptr, val);
  258. }
  259. /*
  260. * pg_atomic_exchange_u32 - exchange newval with current value
  261. *
  262. * Returns the old value of 'ptr' before the swap.
  263. *
  264. * Full barrier semantics.
  265. */
  266. static inline uint32
  267. pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
  268. {
  269. AssertPointerAlignment(ptr, 4);
  270. return pg_atomic_exchange_u32_impl(ptr, newval);
  271. }
  272. /*
  273. * pg_atomic_compare_exchange_u32 - CAS operation
  274. *
  275. * Atomically compare the current value of ptr with *expected and store newval
  276. * iff ptr and *expected have the same value. The current value of *ptr will
  277. * always be stored in *expected.
  278. *
  279. * Return true if values have been exchanged, false otherwise.
  280. *
  281. * Full barrier semantics.
  282. */
  283. static inline bool
  284. pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr,
  285. uint32 *expected, uint32 newval)
  286. {
  287. AssertPointerAlignment(ptr, 4);
  288. AssertPointerAlignment(expected, 4);
  289. return pg_atomic_compare_exchange_u32_impl(ptr, expected, newval);
  290. }
  291. /*
  292. * pg_atomic_fetch_add_u32 - atomically add to variable
  293. *
  294. * Returns the value of ptr before the arithmetic operation.
  295. *
  296. * Full barrier semantics.
  297. */
  298. static inline uint32
  299. pg_atomic_fetch_add_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
  300. {
  301. AssertPointerAlignment(ptr, 4);
  302. return pg_atomic_fetch_add_u32_impl(ptr, add_);
  303. }
  304. /*
  305. * pg_atomic_fetch_sub_u32 - atomically subtract from variable
  306. *
  307. * Returns the value of ptr before the arithmetic operation. Note that sub_
  308. * may not be INT_MIN due to platform limitations.
  309. *
  310. * Full barrier semantics.
  311. */
  312. static inline uint32
  313. pg_atomic_fetch_sub_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
  314. {
  315. AssertPointerAlignment(ptr, 4);
  316. Assert(sub_ != INT_MIN);
  317. return pg_atomic_fetch_sub_u32_impl(ptr, sub_);
  318. }
  319. /*
  320. * pg_atomic_fetch_and_u32 - atomically bit-and and_ with variable
  321. *
  322. * Returns the value of ptr before the arithmetic operation.
  323. *
  324. * Full barrier semantics.
  325. */
  326. static inline uint32
  327. pg_atomic_fetch_and_u32(volatile pg_atomic_uint32 *ptr, uint32 and_)
  328. {
  329. AssertPointerAlignment(ptr, 4);
  330. return pg_atomic_fetch_and_u32_impl(ptr, and_);
  331. }
  332. /*
  333. * pg_atomic_fetch_or_u32 - atomically bit-or or_ with variable
  334. *
  335. * Returns the value of ptr before the arithmetic operation.
  336. *
  337. * Full barrier semantics.
  338. */
  339. static inline uint32
  340. pg_atomic_fetch_or_u32(volatile pg_atomic_uint32 *ptr, uint32 or_)
  341. {
  342. AssertPointerAlignment(ptr, 4);
  343. return pg_atomic_fetch_or_u32_impl(ptr, or_);
  344. }
  345. /*
  346. * pg_atomic_add_fetch_u32 - atomically add to variable
  347. *
  348. * Returns the value of ptr after the arithmetic operation.
  349. *
  350. * Full barrier semantics.
  351. */
  352. static inline uint32
  353. pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
  354. {
  355. AssertPointerAlignment(ptr, 4);
  356. return pg_atomic_add_fetch_u32_impl(ptr, add_);
  357. }
  358. /*
  359. * pg_atomic_sub_fetch_u32 - atomically subtract from variable
  360. *
  361. * Returns the value of ptr after the arithmetic operation. Note that sub_ may
  362. * not be INT_MIN due to platform limitations.
  363. *
  364. * Full barrier semantics.
  365. */
  366. static inline uint32
  367. pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
  368. {
  369. AssertPointerAlignment(ptr, 4);
  370. Assert(sub_ != INT_MIN);
  371. return pg_atomic_sub_fetch_u32_impl(ptr, sub_);
  372. }
  373. /* ----
  374. * The 64 bit operations have the same semantics as their 32bit counterparts
  375. * if they are available. Check the corresponding 32bit function for
  376. * documentation.
  377. * ----
  378. */
  379. static inline void
  380. pg_atomic_init_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
  381. {
  382. /*
  383. * Can't necessarily enforce alignment - and don't need it - when using
  384. * the spinlock based fallback implementation. Therefore only assert when
  385. * not using it.
  386. */
  387. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  388. AssertPointerAlignment(ptr, 8);
  389. #endif
  390. pg_atomic_init_u64_impl(ptr, val);
  391. }
  392. static inline uint64
  393. pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
  394. {
  395. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  396. AssertPointerAlignment(ptr, 8);
  397. #endif
  398. return pg_atomic_read_u64_impl(ptr);
  399. }
  400. static inline void
  401. pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
  402. {
  403. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  404. AssertPointerAlignment(ptr, 8);
  405. #endif
  406. pg_atomic_write_u64_impl(ptr, val);
  407. }
  408. static inline uint64
  409. pg_atomic_exchange_u64(volatile pg_atomic_uint64 *ptr, uint64 newval)
  410. {
  411. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  412. AssertPointerAlignment(ptr, 8);
  413. #endif
  414. return pg_atomic_exchange_u64_impl(ptr, newval);
  415. }
  416. static inline bool
  417. pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr,
  418. uint64 *expected, uint64 newval)
  419. {
  420. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  421. AssertPointerAlignment(ptr, 8);
  422. AssertPointerAlignment(expected, 8);
  423. #endif
  424. return pg_atomic_compare_exchange_u64_impl(ptr, expected, newval);
  425. }
  426. static inline uint64
  427. pg_atomic_fetch_add_u64(volatile pg_atomic_uint64 *ptr, int64 add_)
  428. {
  429. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  430. AssertPointerAlignment(ptr, 8);
  431. #endif
  432. return pg_atomic_fetch_add_u64_impl(ptr, add_);
  433. }
  434. static inline uint64
  435. pg_atomic_fetch_sub_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
  436. {
  437. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  438. AssertPointerAlignment(ptr, 8);
  439. #endif
  440. Assert(sub_ != PG_INT64_MIN);
  441. return pg_atomic_fetch_sub_u64_impl(ptr, sub_);
  442. }
  443. static inline uint64
  444. pg_atomic_fetch_and_u64(volatile pg_atomic_uint64 *ptr, uint64 and_)
  445. {
  446. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  447. AssertPointerAlignment(ptr, 8);
  448. #endif
  449. return pg_atomic_fetch_and_u64_impl(ptr, and_);
  450. }
  451. static inline uint64
  452. pg_atomic_fetch_or_u64(volatile pg_atomic_uint64 *ptr, uint64 or_)
  453. {
  454. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  455. AssertPointerAlignment(ptr, 8);
  456. #endif
  457. return pg_atomic_fetch_or_u64_impl(ptr, or_);
  458. }
  459. static inline uint64
  460. pg_atomic_add_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 add_)
  461. {
  462. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  463. AssertPointerAlignment(ptr, 8);
  464. #endif
  465. return pg_atomic_add_fetch_u64_impl(ptr, add_);
  466. }
  467. static inline uint64
  468. pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
  469. {
  470. #ifndef PG_HAVE_ATOMIC_U64_SIMULATION
  471. AssertPointerAlignment(ptr, 8);
  472. #endif
  473. Assert(sub_ != PG_INT64_MIN);
  474. return pg_atomic_sub_fetch_u64_impl(ptr, sub_);
  475. }
  476. #undef INSIDE_ATOMICS_H
  477. #endif /* ATOMICS_H */