atomics.h 15 KB

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