diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/port/atomics.c | 21 | ||||
-rw-r--r-- | src/include/port/atomics/fallback.h | 13 | ||||
-rw-r--r-- | src/test/regress/regress.c | 14 |
3 files changed, 21 insertions, 27 deletions
diff --git a/src/backend/port/atomics.c b/src/backend/port/atomics.c index e4e4734dd23..caa84bf2b62 100644 --- a/src/backend/port/atomics.c +++ b/src/backend/port/atomics.c @@ -68,18 +68,35 @@ pg_atomic_init_flag_impl(volatile pg_atomic_flag *ptr) #else SpinLockInit((slock_t *) &ptr->sema); #endif + + ptr->value = false; } bool pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr) { - return TAS((slock_t *) &ptr->sema); + uint32 oldval; + + SpinLockAcquire((slock_t *) &ptr->sema); + oldval = ptr->value; + ptr->value = true; + SpinLockRelease((slock_t *) &ptr->sema); + + return oldval == 0; } void pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr) { - S_UNLOCK((slock_t *) &ptr->sema); + SpinLockAcquire((slock_t *) &ptr->sema); + ptr->value = false; + SpinLockRelease((slock_t *) &ptr->sema); +} + +bool +pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr) +{ + return ptr->value == 0; } #endif /* PG_HAVE_ATOMIC_FLAG_SIMULATION */ diff --git a/src/include/port/atomics/fallback.h b/src/include/port/atomics/fallback.h index 7b9dcad8073..88a967ad5b9 100644 --- a/src/include/port/atomics/fallback.h +++ b/src/include/port/atomics/fallback.h @@ -80,6 +80,7 @@ typedef struct pg_atomic_flag #else int sema; #endif + volatile bool value; } pg_atomic_flag; #endif /* PG_HAVE_ATOMIC_FLAG_SUPPORT */ @@ -132,17 +133,7 @@ extern bool pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr); extern void pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr); #define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG -static inline bool -pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr) -{ - /* - * Can't do this efficiently in the semaphore based implementation - we'd - * have to try to acquire the semaphore - so always return true. That's - * correct, because this is only an unlocked test anyway. Do this in the - * header so compilers can optimize the test away. - */ - return true; -} +extern bool pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr); #endif /* PG_HAVE_ATOMIC_FLAG_SIMULATION */ diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index e14322c798a..8bc562ee4f0 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -633,7 +633,6 @@ wait_pid(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } -#ifndef PG_HAVE_ATOMIC_FLAG_SIMULATION static void test_atomic_flag(void) { @@ -663,7 +662,6 @@ test_atomic_flag(void) pg_atomic_clear_flag(&flag); } -#endif /* PG_HAVE_ATOMIC_FLAG_SIMULATION */ static void test_atomic_uint32(void) @@ -846,19 +844,7 @@ PG_FUNCTION_INFO_V1(test_atomic_ops); Datum test_atomic_ops(PG_FUNCTION_ARGS) { - /* --- - * Can't run the test under the semaphore emulation, it doesn't handle - * checking two edge cases well: - * - pg_atomic_unlocked_test_flag() always returns true - * - locking a already locked flag blocks - * it seems better to not test the semaphore fallback here, than weaken - * the checks for the other cases. The semaphore code will be the same - * everywhere, whereas the efficient implementations wont. - * --- - */ -#ifndef PG_HAVE_ATOMIC_FLAG_SIMULATION test_atomic_flag(); -#endif test_atomic_uint32(); |