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)
