On Mon, Dec 15, 2025 at 12:27:25PM -0500, Greg Burd wrote:
> Got it, fixed in v9.

I tried to rearrange the s_lock.h changes to make it more obvious what is
specific to AArch64.  WDYT?

-- 
nathan
>From b304e07bfcafbb03166a583e40de550af24683f1 Mon Sep 17 00:00:00 2001
From: Dave Cramer <[email protected]>
Date: Sun, 13 Jul 2025 06:33:17 -0400
Subject: [PATCH v10 1/1] Enable the Microsoft Windows ARM64/MSVC platform

Add support for the ARM64 architecture on Windows 11 using MSVC compiler
addressing build issues and implementing proper memory synchronization
semantics for this platform.

* Implement spin_delay() with __isb(_ARM64_BARRIER_SY) intrinsic to emit
  the "ISB SY" instruction which matches the GCC/Clang approach to
  spinloop delay and emperical evidence that it out-scales the YIELD
  instruction in practice.

* Unconditionally choose to use the MSVC supplied intrinsic
  for CRC32 on ARM64.

* Implement the S_UNLOCK() macro using the InterlockedExchange()
  intrinsic on ARM64.

Author: Greg Burd <[email protected]>
Author: Dave Cramer <[email protected]>
Discussion: 
https://postgr.es/m/3c576ad7-d2da-4137-b791-5821da7cc370%40app.fastmail.com
---
 doc/src/sgml/installation.sgml |  3 ++-
 meson.build                    |  3 ++-
 src/include/storage/s_lock.h   | 23 +++++++++++++++++++----
 src/port/pg_crc32c_armv8.c     |  4 ++++
 src/tools/msvc_gendef.pl       |  8 ++++----
 5 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index fe8d73e1f8c..c903ccff988 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -3967,7 +3967,8 @@ 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 AArch64 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 d7c5193d4ce..3a083c469e6 100644
--- a/meson.build
+++ b/meson.build
@@ -2523,7 +2523,8 @@ int main(void)
 }
 '''
 
-  if cc.links(prog, name: '__crc32cb, __crc32ch, __crc32cw, and __crc32cd 
without -march=armv8-a+crc',
+  if (host_cpu == 'aarch64' and cc.get_id() == 'msvc') or \
+        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/storage/s_lock.h b/src/include/storage/s_lock.h
index 7f8f566bd40..e62141abf0a 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -602,13 +602,21 @@ typedef LONG slock_t;
 
 #define SPIN_DELAY() spin_delay()
 
-/* If using Visual C++ on Win64, inline assembly is unavailable.
- * Use a _mm_pause intrinsic instead of rep nop.
- */
-#if defined(_WIN64)
+#ifdef _M_ARM64
+static __forceinline void
+spin_delay(void)
+{
+       /* Research indicates ISB is better than __yield() on AArch64. */
+       __isb(_ARM64_BARRIER_SY);
+}
+#elif defined(_WIN64)
 static __forceinline void
 spin_delay(void)
 {
+       /*
+        * If using Visual C++ on Win64, inline assembly is unavailable.
+        * Use a _mm_pause intrinsic instead of rep nop.
+        */
        _mm_pause();
 }
 #else
@@ -621,12 +629,19 @@ spin_delay(void)
 #endif
 
 #include <intrin.h>
+#ifdef _M_ARM64
+#pragma intrinsic(_InterlockedExchange)
+
+/* _ReadWriteBarrier() is insufficient on non-TSO architectures. */
+#define S_UNLOCK(lock) _InterlockedExchange(lock, 0)
+#else
 #pragma intrinsic(_ReadWriteBarrier)
 
 #define S_UNLOCK(lock) \
        do { _ReadWriteBarrier(); (*(lock)) = 0; } while (0)
 
 #endif
+#endif
 
 
 #endif /* !defined(HAS_TEST_AND_SET) */
diff --git a/src/port/pg_crc32c_armv8.c b/src/port/pg_crc32c_armv8.c
index 5ba070bb99d..e49b383b26a 100644
--- a/src/port/pg_crc32c_armv8.c
+++ b/src/port/pg_crc32c_armv8.c
@@ -14,7 +14,11 @@
  */
 #include "c.h"
 
+#ifdef _MSC_VER
+#include <intrin.h>
+#else
 #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.39.5 (Apple Git-154)

Reply via email to