Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
fallback.h171 linesDownload Raw Back to atomics
1/*-------------------------------------------------------------------------2 *3 * fallback.h4 *    Fallback for platforms without spinlock and/or atomics support. Slower5 *    than native atomics support, but not unusably slow.6 *7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group8 * Portions Copyright (c) 1994, Regents of the University of California9 *10 * src/include/port/atomics/fallback.h11 *12 *-------------------------------------------------------------------------13 */14 15/* intentionally no include guards, should only be included by atomics.h */16#ifndef INSIDE_ATOMICS_H17#	error "should be included via atomics.h"18#endif19 20#ifndef pg_memory_barrier_impl21/*22 * If we have no memory barrier implementation for this architecture, we23 * fall back to acquiring and releasing a spinlock.  This might, in turn,24 * fall back to the semaphore-based spinlock implementation, which will be25 * amazingly slow.26 *27 * It's not self-evident that every possible legal implementation of a28 * spinlock acquire-and-release would be equivalent to a full memory barrier.29 * For example, I'm not sure that Itanium's acq and rel add up to a full30 * fence.  But all of our actual implementations seem OK in this regard.31 */32#define PG_HAVE_MEMORY_BARRIER_EMULATION33 34extern void pg_spinlock_barrier(void);35#define pg_memory_barrier_impl pg_spinlock_barrier36#endif37 38#ifndef pg_compiler_barrier_impl39/*40 * If the compiler/arch combination does not provide compiler barriers,41 * provide a fallback.  The fallback simply consists of a function call into42 * an externally defined function.  That should guarantee compiler barrier43 * semantics except for compilers that do inter translation unit/global44 * optimization - those better provide an actual compiler barrier.45 *46 * A native compiler barrier for sure is a lot faster than this...47 */48#define PG_HAVE_COMPILER_BARRIER_EMULATION49extern void pg_extern_compiler_barrier(void);50#define pg_compiler_barrier_impl pg_extern_compiler_barrier51#endif52 53 54/*55 * If we have atomics implementation for this platform, fall back to providing56 * the atomics API using a spinlock to protect the internal state. Possibly57 * the spinlock implementation uses semaphores internally...58 *59 * We have to be a bit careful here, as it's not guaranteed that atomic60 * variables are mapped to the same address in every process (e.g. dynamic61 * shared memory segments). We can't just hash the address and use that to map62 * to a spinlock. Instead assign a spinlock on initialization of the atomic63 * variable.64 */65#if !defined(PG_HAVE_ATOMIC_FLAG_SUPPORT) && !defined(PG_HAVE_ATOMIC_U32_SUPPORT)66 67#define PG_HAVE_ATOMIC_FLAG_SIMULATION68#define PG_HAVE_ATOMIC_FLAG_SUPPORT69 70typedef struct pg_atomic_flag71{72	/*73	 * To avoid circular includes we can't use s_lock as a type here. Instead74	 * just reserve enough space for all spinlock types. Some platforms would75	 * be content with just one byte instead of 4, but that's not too much76	 * waste.77	 */78#if defined(__hppa) || defined(__hppa__)	/* HP PA-RISC, GCC and HP compilers */79	int			sema[4];80#else81	int			sema;82#endif83	volatile bool value;84} pg_atomic_flag;85 86#endif /* PG_HAVE_ATOMIC_FLAG_SUPPORT */87 88#if !defined(PG_HAVE_ATOMIC_U32_SUPPORT)89 90#define PG_HAVE_ATOMIC_U32_SIMULATION91 92#define PG_HAVE_ATOMIC_U32_SUPPORT93typedef struct pg_atomic_uint3294{95	/* Check pg_atomic_flag's definition above for an explanation */96#if defined(__hppa) || defined(__hppa__)	/* HP PA-RISC */97	int			sema[4];98#else99	int			sema;100#endif101	volatile uint32 value;102} pg_atomic_uint32;103 104#endif /* PG_HAVE_ATOMIC_U32_SUPPORT */105 106#if !defined(PG_HAVE_ATOMIC_U64_SUPPORT)107 108#define PG_HAVE_ATOMIC_U64_SIMULATION109 110#define PG_HAVE_ATOMIC_U64_SUPPORT111typedef struct pg_atomic_uint64112{113	/* Check pg_atomic_flag's definition above for an explanation */114#if defined(__hppa) || defined(__hppa__)	/* HP PA-RISC */115	int			sema[4];116#else117	int			sema;118#endif119	volatile uint64 value;120} pg_atomic_uint64;121 122#endif /* PG_HAVE_ATOMIC_U64_SUPPORT */123 124#ifdef PG_HAVE_ATOMIC_FLAG_SIMULATION125 126#define PG_HAVE_ATOMIC_INIT_FLAG127extern void pg_atomic_init_flag_impl(volatile pg_atomic_flag *ptr);128 129#define PG_HAVE_ATOMIC_TEST_SET_FLAG130extern bool pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr);131 132#define PG_HAVE_ATOMIC_CLEAR_FLAG133extern void pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr);134 135#define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG136extern bool pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr);137 138#endif /* PG_HAVE_ATOMIC_FLAG_SIMULATION */139 140#ifdef PG_HAVE_ATOMIC_U32_SIMULATION141 142#define PG_HAVE_ATOMIC_INIT_U32143extern void pg_atomic_init_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 val_);144 145#define PG_HAVE_ATOMIC_WRITE_U32146extern void pg_atomic_write_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 val);147 148#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32149extern bool pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr,150												uint32 *expected, uint32 newval);151 152#define PG_HAVE_ATOMIC_FETCH_ADD_U32153extern uint32 pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_);154 155#endif /* PG_HAVE_ATOMIC_U32_SIMULATION */156 157 158#ifdef PG_HAVE_ATOMIC_U64_SIMULATION159 160#define PG_HAVE_ATOMIC_INIT_U64161extern void pg_atomic_init_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 val_);162 163#define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64164extern bool pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr,165												uint64 *expected, uint64 newval);166 167#define PG_HAVE_ATOMIC_FETCH_ADD_U64168extern uint64 pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_);169 170#endif /* PG_HAVE_ATOMIC_U64_SIMULATION */171 
codekingpro/portable-devtools · Team Ai