public inbox for [email protected]  
help / color / mirror / Atom feed
From: Greg Burd <[email protected]>
To: PostgreSQL Hackers <[email protected]>
Subject: Re: Trying out <stdatomic.h>
Date: Sun, 23 Nov 2025 10:22:47 -0500
Message-ID: <[email protected]> (raw)
In-Reply-To: <CA+hUKGKFvu3zyvv3aaj5hHs9VtWcjFAmisOwOc7aOZNc5AF3NA@mail.gmail.com>
References: <CA+hUKGKFvu3zyvv3aaj5hHs9VtWcjFAmisOwOc7aOZNc5AF3NA@mail.gmail.com>


On Mon, Nov 10, 2025, at 8:17 AM, Thomas Munro wrote:
> Hi,
>
> Here is an experimental patch to try out standard C (and C++) atomics
> to implement port/atomics.h, and also add more types and operations.
> It's mostly just redirecting our names to the standard ones, except
> for our barriers and slightly extended pg_atomic_flag, so there isn't
> much left of the code.
>
> Here also is a semi-independent patch to implement storage/spin.h with
> pg_atomic_flag.  It keeps a small amount of the architecture-specific
> magic, but moves it out to src/port/spin_delay.h.
>
> I'm not saying they're correct, performant or portable yet, that'll
> require studying codegen and performance on a bunch of weird and
> wonderful systems, but they at least passes basic testing on the usual
> suspects and CI systems, except for Windows which needs a newer
> toolchain so I haven't tried yet.  It should hopefully just work™ on
> VS 2022 (same version that provides <threads.h>, about which more
> soon).
>
> All that being the case, it's not far enough along to be a serious
> proposal, but I imagine others will be looking into things like this
> since we pulled the trigger on C11 and I figured I might as well share
> a basic working patch set to avoid duplicated effort...   Hopefully it
> works well enough to kick the tyres and try to find the difficult
> problems, test it out on weird systems, etc etc.
>
> Attachments:
> * v1-0001-Add-some-missing-include-limits.h.patch
> * v1-0002-Redefine-port-atomics.h-on-top-of-stdatomic.h.patch
> * v1-0003-Use-atomics-API-to-implement-spinlocks.patch
> * v1-0004-Remove-configure-meson-checks-for-atomics.patch

Hello Thomas,

First off, thanks for working on this set of changes.  I like your changes in general, except for removing Solaris/Illumos (but I get it).  ;-P

As mentioned on a separate thread about fixing ARM64 support when building with MSVC on Win11 [1] I tried out this patch.  The reply on that thread had an issue with _mm_pause() in spin_delay(), it turns out we need to use __yield() [2].  I went ahead and fixed that, so ignore that patch on the other thread [1].  The new patch attached that layers on top of your work and supports that platform, there was one minor change that was required:


#ifdef _MSC_VER

	/*
	 * If using Visual C++ on Win64, inline assembly is unavailable.  Use a
	 * _mm_pause intrinsic instead of rep nop. For ARM64, use the __yield()
	 * intrinsic which emits the YIELD instruction as a hint to the processor.
	 */
#if defined(_M_ARM64)
	__yield();
#elif defined(_WIN64)
	_mm_pause();
#else
	/* See comment for gcc code. Same code, MASM syntax */
	__asm		rep nop;
#endif
#endif							/* _MSC_VER */


Visual Studio 2026 (Community)
cl (msvc 19.50.35718 "Microsoft (R) C/C++ Optimizing Compiler Version 19.50.35718 for ARM64")
link 14.50.35718.0


tests are passing, best.

-greg

[1] https://www.postgresql.org/message-id/3c576ad7-d2da-4137-b791-5821da7cc370%40app.fastmail.com
[2] https://learn.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-180

Attachments:

  [application/octet-stream] v20251123-0001-WIP-ARM64-MSVC-stdatomic.patch (4.4K, 2-v20251123-0001-WIP-ARM64-MSVC-stdatomic.patch)
  download | inline diff:
From 295161e09c41658841a902c57f99da54395b20dd Mon Sep 17 00:00:00 2001
From: Greg Burd <[email protected]>
Date: Sun, 23 Nov 2025 07:58:47 -0500
Subject: [PATCH v20251123] WIP ARM64/MSVC stdatomic

---
 doc/src/sgml/installation.sgml |  2 +-
 meson.build                    | 15 ++++++++++++++-
 src/include/port/spin_delay.h  |  7 +++++--
 src/port/pg_crc32c_armv8.c     |  2 ++
 src/tools/msvc_gendef.pl       |  8 ++++----
 5 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index fe8d73e1f8c..3f8d512a906 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -3967,7 +3967,7 @@ configure ... LDFLAGS="-R /usr/sfw/lib:/opt/sfw/lib:/usr/local/lib"
    <sect3 id="install-windows-full-64-bit">
     <title>Special Considerations for 64-Bit Windows</title>
     <para>
-     PostgreSQL will only build for the x64 architecture on 64-bit Windows.
+     PostgreSQL will only build for the x64 and ARM64 architectures on 64-bit Windows.
     </para>
     <para>
      Mixing 32- and 64-bit versions in the same build tree is not supported.
diff --git a/meson.build b/meson.build
index 1a2005e75c4..18637180ab1 100644
--- a/meson.build
+++ b/meson.build
@@ -2158,6 +2158,11 @@ endforeach
 
 
 if cc.get_id() == 'msvc'
+  # Add ARM64 architecture flag for Windows 11 ARM64 for correct intrensics
+  if host_machine.system() == 'windows' and host_machine.cpu_family() == 'aarch64'
+    add_project_arguments('/arch:armv9.4', language: ['c', 'cpp'])
+  endif
+
   cflags_warn += [
     # Warnings to disable:
     # from /W1:
@@ -2367,6 +2372,11 @@ if host_cpu == 'x86' or host_cpu == 'x86_64'
   else
 
     prog = '''
+#ifdef _MSC_VER
+#include <intrin.h>
+#else
+#include <arm_acle.h>
+#endif
 #include <nmmintrin.h>
 unsigned int crc;
 
@@ -2450,7 +2460,10 @@ int main(void)
 }
 '''
 
-  if cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd without -march=armv8-a+crc',
+  if cc.get_id() == 'msvc'
+    cdata.set('USE_ARMV8_CRC32C', 1)
+    have_optimized_crc = true
+  elif cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd without -march=armv8-a+crc',
       args: test_c_args)
     # Use ARM CRC Extension unconditionally
     cdata.set('USE_ARMV8_CRC32C', 1)
diff --git a/src/include/port/spin_delay.h b/src/include/port/spin_delay.h
index c583698af8e..f944c8362da 100644
--- a/src/include/port/spin_delay.h
+++ b/src/include/port/spin_delay.h
@@ -69,9 +69,12 @@ pg_spin_delay(void)
 
 	/*
 	 * If using Visual C++ on Win64, inline assembly is unavailable.  Use a
-	 * _mm_pause intrinsic instead of rep nop.
+	 * _mm_pause intrinsic instead of rep nop. For ARM64, use the __yield()
+	 * intrinsic which emits the YIELD instruction as a hint to the processor.
 	 */
-#if defined(_WIN64)
+#if defined(_M_ARM64)
+	__yield();
+#elif defined(_WIN64)
 	_mm_pause();
 #else
 	/* See comment for gcc code. Same code, MASM syntax */
diff --git a/src/port/pg_crc32c_armv8.c b/src/port/pg_crc32c_armv8.c
index 5ba070bb99d..6a155ddde1e 100644
--- a/src/port/pg_crc32c_armv8.c
+++ b/src/port/pg_crc32c_armv8.c
@@ -14,7 +14,9 @@
  */
 #include "c.h"
 
+#ifndef _MSC_VER
 #include <arm_acle.h>
+#endif
 
 #include "port/pg_crc32c.h"
 
diff --git a/src/tools/msvc_gendef.pl b/src/tools/msvc_gendef.pl
index 868aad51b09..c92c94c4775 100644
--- a/src/tools/msvc_gendef.pl
+++ b/src/tools/msvc_gendef.pl
@@ -118,9 +118,9 @@ sub writedef
 	{
 		my $isdata = $def->{$f} eq 'data';
 
-		# Strip the leading underscore for win32, but not x64
+		# Strip the leading underscore for win32, but not x64 and aarch64
 		$f =~ s/^_//
-		  unless ($arch eq "x86_64");
+		  unless ($arch eq "x86_64" || $arch eq "aarch64");
 
 		# Emit just the name if it's a function symbol, or emit the name
 		# decorated with the DATA option for variables.
@@ -141,7 +141,7 @@ sub writedef
 sub usage
 {
 	die("Usage: msvc_gendef.pl --arch <arch> --deffile <deffile> --tempdir <tempdir> files-or-directories\n"
-		  . "    arch: x86 | x86_64\n"
+		  . "    arch: x86 | x86_64 | aarch64\n"
 		  . "    deffile: path of the generated file\n"
 		  . "    tempdir: directory for temporary files\n"
 		  . "    files or directories: object files or directory containing object files\n"
@@ -158,7 +158,7 @@ GetOptions(
 	'tempdir:s' => \$tempdir,) or usage();
 
 usage("arch: $arch")
-  unless ($arch eq 'x86' || $arch eq 'x86_64');
+  unless ($arch eq 'x86' || $arch eq 'x86_64' || $arch eq 'aarch64');
 
 my @files;
 
-- 
2.52.0.windows.1



view thread (19+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected]
  Subject: Re: Trying out <stdatomic.h>
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox