v12-0001-Add-functions-for-monotonic-advancement-of-atomi.patch

application/octet-stream

Filename: v12-0001-Add-functions-for-monotonic-advancement-of-atomi.patch
Type: application/octet-stream
Part: 0
Message: Re: LogwrtResult contended spinlock

Patch

Format: format-patch
Series: patch v12-0001
Subject: Add functions for monotonic advancement of atomic variables
File+
src/include/port/atomics.h 64 0
From 46a5b9451830a870bb23e80fec8428854a807970 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Date: Wed, 21 Feb 2024 10:46:02 +0000
Subject: [PATCH v12 1/3] Add functions for monotonic advancement of atomic
 variables

This commit adds functions for monotonically advancing the given
atomic variable with full barrier semantics.

An upcoming commit uses 64-bit monotonic function. But this commit
also adds 32-bit version just for the sake of completeness.
---
 src/include/port/atomics.h | 64 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/src/include/port/atomics.h b/src/include/port/atomics.h
index bf151037f7..b1f1c04b9f 100644
--- a/src/include/port/atomics.h
+++ b/src/include/port/atomics.h
@@ -400,6 +400,36 @@ pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
 	return pg_atomic_sub_fetch_u32_impl(ptr, sub_);
 }
 
+/*
+ * Monotonically advance the given variable using only atomic operations until
+ * it's at least the target value.
+ *
+ * Full barrier semantics (even when value is unchanged).
+ */
+static inline void
+pg_atomic_monotonic_advance_u32(volatile pg_atomic_uint32 *ptr, uint32 target_)
+{
+	uint32		currval;
+
+	AssertPointerAlignment(ptr, 4);
+
+	currval = pg_atomic_read_u32_impl(ptr);
+	if (currval >= target_)
+	{
+		pg_memory_barrier();
+		return;
+	}
+
+	AssertPointerAlignment(ptr, 4);
+	AssertPointerAlignment(currval, 4);
+
+	while (currval < target_)
+	{
+		if (pg_atomic_compare_exchange_u32_impl(ptr, &currval, target_))
+			break;
+	}
+}
+
 /* ----
  * The 64 bit operations have the same semantics as their 32bit counterparts
  * if they are available. Check the corresponding 32bit function for
@@ -514,6 +544,40 @@ pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
 	return pg_atomic_sub_fetch_u64_impl(ptr, sub_);
 }
 
+/*
+ * Monotonically advance the given variable using only atomic operations until
+ * it's at least the target value.
+ *
+ * Full barrier semantics (even when value is unchanged).
+ */
+static inline void
+pg_atomic_monotonic_advance_u64(volatile pg_atomic_uint64 *ptr, uint64 target_)
+{
+	uint64		currval;
+
+#ifndef PG_HAVE_ATOMIC_U64_SIMULATION
+	AssertPointerAlignment(ptr, 8);
+#endif
+
+	currval = pg_atomic_read_u64_impl(ptr);
+	if (currval >= target_)
+	{
+		pg_memory_barrier();
+		return;
+	}
+
+#ifndef PG_HAVE_ATOMIC_U64_SIMULATION
+	AssertPointerAlignment(ptr, 8);
+	AssertPointerAlignment(currval, 8);
+#endif
+
+	while (currval < target_)
+	{
+		if (pg_atomic_compare_exchange_u64_impl(ptr, &currval, target_))
+			break;
+	}
+}
+
 #undef INSIDE_ATOMICS_H
 
 #endif							/* ATOMICS_H */
-- 
2.34.1