diff options
author | Ben Gamari <ben@smart-cactus.org> | 2023-02-13 14:46:24 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2023-03-02 12:31:12 -0500 |
commit | 72087b1d3385f3cc51150bb17dbdaf4d88baeace (patch) | |
tree | 97f1590348a3729181b26d6083426159171e86ec | |
parent | 0a0e22f50550ab5ba2b789239cfdd7410662e120 (diff) | |
download | haskell-72087b1d3385f3cc51150bb17dbdaf4d88baeace.tar.gz |
rts: Introduce stgMallocAlignedBytes
(cherry picked from commit eeb5bd560942a4968980fb341d9ebca33ad3302b)
-rw-r--r-- | rts/Capability.c | 2 | ||||
-rw-r--r-- | rts/RtsUtils.c | 51 | ||||
-rw-r--r-- | rts/RtsUtils.h | 4 |
3 files changed, 54 insertions, 3 deletions
diff --git a/rts/Capability.c b/rts/Capability.c index 98c80887e5..f5514cbeee 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -1274,7 +1274,7 @@ freeCapabilities (void) Capability *cap = getCapability(i); freeCapability(cap); if (cap != &MainCapability) { - stgFree(cap); + stgFreeAligned(cap); } } #else diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c index d3dcdf3092..4cac10ba15 100644 --- a/rts/RtsUtils.c +++ b/rts/RtsUtils.c @@ -57,9 +57,9 @@ extern char *ctime_r(const time_t *, char *); void * stgMallocBytes (size_t n, char *msg) { - void *space; + void *space = malloc(n); - if ((space = malloc(n)) == NULL) { + if (space == NULL) { /* Quoting POSIX.1-2008 (which says more or less the same as ISO C99): * * "Upon successful completion with size not equal to 0, malloc() shall @@ -128,6 +128,53 @@ stgFree(void* p) free(p); } +// N.B. Allocations resulting from this function must be freed by +// `stgFreeAligned`, not `stgFree`. This is necessary due to the properties of Windows' `_aligned_malloc` +void * +stgMallocAlignedBytes (size_t n, size_t align, char *msg) +{ + void *space; + +#if defined(mingw32_HOST_OS) + space = _aligned_malloc(n, align); +#else + if (posix_memalign(&space, align, n)) { + space = NULL; // Allocation failed + } +#endif + + if (space == NULL) { + /* Quoting POSIX.1-2008 (which says more or less the same as ISO C99): + * + * "Upon successful completion with size not equal to 0, malloc() shall + * return a pointer to the allocated space. If size is 0, either a null + * pointer or a unique pointer that can be successfully passed to free() + * shall be returned. Otherwise, it shall return a null pointer and set + * errno to indicate the error." + * + * Consequently, a NULL pointer being returned by `malloc()` for a 0-size + * allocation is *not* to be considered an error. + */ + if (n == 0) return NULL; + + /* don't fflush(stdout); WORKAROUND bug in Linux glibc */ + rtsConfig.mallocFailHook((W_) n, msg); + stg_exit(EXIT_INTERNAL_ERROR); + } + IF_DEBUG(zero_on_gc, memset(space, 0xbb, n)); + return space; +} + +void +stgFreeAligned (void *p) +{ +#if defined(mingw32_HOST_OS) + _aligned_free(p); +#else + free(p); +#endif +} + /* ----------------------------------------------------------------------------- Stack/heap overflow -------------------------------------------------------------------------- */ diff --git a/rts/RtsUtils.h b/rts/RtsUtils.h index 1c5aac82a1..6af430750b 100644 --- a/rts/RtsUtils.h +++ b/rts/RtsUtils.h @@ -48,6 +48,10 @@ void *stgCallocBytes(size_t count, size_t size, char *msg) char *stgStrndup(const char *s, size_t n) STG_MALLOC STG_MALLOC1(stgFree); +void *stgMallocAlignedBytes(size_t n, size_t align, char *msg); + +void stgFreeAligned(void *p); + /* ----------------------------------------------------------------------------- * Misc other utilities * -------------------------------------------------------------------------- */ |