diff options
author | Ben Gamari <ben@smart-cactus.org> | 2023-02-13 14:46:24 -0500 |
---|---|---|
committer | Zubin Duggal <zubin.duggal@gmail.com> | 2023-02-22 17:04:46 +0530 |
commit | 512c37e77ae09fe2a7e47afa559ffb835f5b0267 (patch) | |
tree | a2a405722ebd8db8475b93a2ff66484d021167da | |
parent | 0978122d26a749e02a1c3b1a77649da82a1fbccd (diff) | |
download | haskell-512c37e77ae09fe2a7e47afa559ffb835f5b0267.tar.gz |
rts: Introduce stgMallocAlignedBytes
(cherry picked from commit 04336d2f11e49f7d00392f05d4fd48abdd231fc0)
(cherry picked from commit 48ecd4b4dca42cf482847d7629c91d2b44eae252)
-rw-r--r-- | rts/RtsUtils.c | 51 | ||||
-rw-r--r-- | rts/RtsUtils.h | 4 |
2 files changed, 53 insertions, 2 deletions
diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c index ca01bdb6e0..d72a6a4be4 100644 --- a/rts/RtsUtils.c +++ b/rts/RtsUtils.c @@ -59,9 +59,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 @@ -130,6 +130,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 c87aedb3a7..41120b0417 100644 --- a/rts/RtsUtils.h +++ b/rts/RtsUtils.h @@ -29,6 +29,10 @@ char *stgStrndup(const char *s, size_t n); void stgFree(void* p); +void *stgMallocAlignedBytes(size_t n, size_t align, char *msg); + +void stgFreeAligned(void *p); + /* ----------------------------------------------------------------------------- * Misc other utilities * -------------------------------------------------------------------------- */ |