aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/port/atomics.c21
-rw-r--r--src/include/port/atomics/fallback.h13
-rw-r--r--src/test/regress/regress.c14
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();