Fix alignment of pg_atomic_uint64 variables on some 32bit platforms.
authorAndres Freund <[email protected]>
Sun, 11 Jan 2015 00:06:37 +0000 (01:06 +0100)
committerAndres Freund <[email protected]>
Sun, 11 Jan 2015 00:06:37 +0000 (01:06 +0100)
I failed to recognize that pg_atomic_uint64 wasn't guaranteed to be 8
byte aligned on some 32bit platforms - which it has to be on some
platforms to guarantee the desired atomicity and which we assert.

As this is all compiler specific code anyway we can just rely on
compiler specific tricks to enforce alignment.

I've been unable to find concrete documentation about the version that
introduce the sunpro alignment support, so that might need additional
guards.

I've verified that this works with gcc x86 32bit, but I don't have
access to any other 32bit environment.

Discussion: op.xpsjdkil0sbe7t@vld-kuci

Per report from Vladimir Koković.

src/include/port/atomics/arch-x86.h
src/include/port/atomics/generic-acc.h
src/include/port/atomics/generic-gcc.h
src/include/port/atomics/generic-msvc.h
src/include/port/atomics/generic-sunpro.h
src/include/port/atomics/generic-xlc.h

index fb5623d2dd15b7ee48b53be3e348b795216f3010..168a49c79345a7309f769e6cc07c2a3e7f0bb375 100644 (file)
@@ -73,6 +73,7 @@ typedef struct pg_atomic_uint32
 #define PG_HAVE_ATOMIC_U64_SUPPORT
 typedef struct pg_atomic_uint64
 {
+   /* alignment guaranteed due to being on a 64bit platform */
    volatile uint64 value;
 } pg_atomic_uint64;
 #endif
index e16e282597b200fe9495ef432b0ef99efc143924..c5639aadda0b6d11b3f6f653af41934f0e0dd2cd 100644 (file)
@@ -40,6 +40,12 @@ typedef struct pg_atomic_uint32
 #define PG_HAVE_ATOMIC_U64_SUPPORT
 typedef struct pg_atomic_uint64
 {
+   /*
+    * Alignment is guaranteed to be 64bit. Search for "Well-behaved
+    * application restrictions" => "Data alignment and data sharing" on HP's
+    * website. Unfortunately the URL doesn't seem to stable enough to
+    * include.
+    */
    volatile uint64 value;
 } pg_atomic_uint64;
 
index f19ad34cc00d351509a49b59f0bbddf12a076e94..fea1cb5e1358754287e765fed423516b05a22c76 100644 (file)
@@ -98,7 +98,7 @@ typedef struct pg_atomic_uint32
 
 typedef struct pg_atomic_uint64
 {
-   volatile uint64 value;
+   volatile uint64 value __attribute__((aligned(8)));
 } pg_atomic_uint64;
 
 #endif /* defined(HAVE_GCC__ATOMIC_INT64_CAS) || defined(HAVE_GCC__SYNC_INT64_CAS) */
index 1d763ab78c37631700f7e2e67bebe4b76b1d5db5..d259d6f51d085c1e056eb74479b2e51b702e13b7 100644 (file)
@@ -41,7 +41,7 @@ typedef struct pg_atomic_uint32
 } pg_atomic_uint32;
 
 #define PG_HAVE_ATOMIC_U64_SUPPORT
-typedef struct pg_atomic_uint64
+typedef struct __declspec(align(8)) pg_atomic_uint64
 {
    volatile uint64 value;
 } pg_atomic_uint64;
index b756fb979ce60133467026ac05cf5c6e051b7aba..7a3028ec3d07964d331788ea93a46bc006bf1216 100644 (file)
@@ -55,7 +55,13 @@ typedef struct pg_atomic_uint32
 #define PG_HAVE_ATOMIC_U64_SUPPORT
 typedef struct pg_atomic_uint64
 {
-   volatile uint64 value;
+   /*
+    * Syntax to enforce variable alignment should be supported by versions
+    * supporting atomic.h, but it's hard to find accurate documentation. If
+    * it proves to be a problem, we'll have to add more version checks for 64
+    * bit support.
+    */
+   volatile uint64 value __attribute__((__aligned__(8)));
 } pg_atomic_uint64;
 
 #endif /* HAVE_ATOMIC_H */
index 92bba6f04fdde98913741e158750efa3a749f612..7a4c12ae6cada2f9f0a890512e56af3fb61087f1 100644 (file)
@@ -32,7 +32,7 @@ typedef struct pg_atomic_uint32
 #define PG_HAVE_ATOMIC_U64_SUPPORT
 typedef struct pg_atomic_uint64
 {
-   volatile uint64 value;
+   volatile uint64 value __attribute__((__aligned__(8)));
 } pg_atomic_uint64;
 
 #endif /* __64BIT__ */