diff options
author | Ben Gamari <ben@smart-cactus.org> | 2023-02-13 13:13:05 -0500 |
---|---|---|
committer | Zubin Duggal <zubin.duggal@gmail.com> | 2023-02-22 17:04:38 +0530 |
commit | 0978122d26a749e02a1c3b1a77649da82a1fbccd (patch) | |
tree | 5c62269189e5dc5156cbc380d3b72edd51c6e2cb | |
parent | 923afa2f51c2e03aef1cc3094a13dbd86d38a283 (diff) | |
download | haskell-0978122d26a749e02a1c3b1a77649da82a1fbccd.tar.gz |
rts: Statically assert alignment of Capability
In #22965 we noticed that changes in the size of `Capability` can result
in unsound behavior due to the `align` pragma claiming an alignment
which we don't in practice observe. Avoid this by statically asserting
that the size is a multiple of the alignment.
(cherry picked from commit 1de404a6528b44bb50927383cb1acf237d21ee03)
-rw-r--r-- | rts/Capability.h | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/rts/Capability.h b/rts/Capability.h index d7c1916ad7..6ccfdccf10 100644 --- a/rts/Capability.h +++ b/rts/Capability.h @@ -27,6 +27,17 @@ #include "BeginPrivate.h" +// We never want a Capability to overlap a cache line with +// anything else, so round it up to a cache line size: +#if defined(s390x_HOST_ARCH) +#define CAPABILITY_ALIGNMENT 256 +#elif defined(mingw32_HOST_OS) +// N.B. it's quite unclear why this special case exists +#define CAPABILITY_ALIGNMENT 1 +#else +#define CAPABILITY_ALIGNMENT 64 +#endif + /* N.B. This must be consistent with CapabilityPublic in RtsAPI.h */ struct Capability_ { // State required by the STG virtual machine when running Haskell @@ -172,14 +183,12 @@ struct Capability_ { StgTRecHeader *free_trec_headers; uint32_t transaction_tokens; } // typedef Capability is defined in RtsAPI.h - // We never want a Capability to overlap a cache line with anything - // else, so round it up to a cache line size: -#if defined(s390x_HOST_ARCH) - ATTRIBUTE_ALIGNED(256) -#elif !defined(mingw32_HOST_OS) - ATTRIBUTE_ALIGNED(64) -#endif - ; + ATTRIBUTE_ALIGNED(CAPABILITY_ALIGNMENT) +; + +// We allocate arrays of Capabilities therefore we must ensure that the size is +// a multiple of the claimed alignment +GHC_STATIC_ASSERT(sizeof(struct Capability_) % CAPABILITY_ALIGNMENT == 0, "Capability size does not match cache size"); #if defined(THREADED_RTS) #define ASSERT_TASK_ID(task) ASSERT(task->id == osThreadId()) |