LCOV - differential code coverage report
Current view: top level - src/include/port - atomics.h (source / functions) Coverage Total Hit GIC CBC ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 100.0 % 90 90 76 14 76
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 27 27 27 27
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 100.0 % 90 90 76 14 76
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 50.0 % 54 27 27 27

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

Generated by: LCOV version v1.16-55-g56c0a2a