diff --git a/docs/api/support/mem.rst b/docs/api/support/mem.rst index 9a629f06..61432080 100644 --- a/docs/api/support/mem.rst +++ b/docs/api/support/mem.rst @@ -3,4 +3,4 @@ Memory Allocation Helpers ========================= -.. kernel-doc:: include/vfn/support/mem.h +.. kernel-doc:: include/vfn/support/platform/posix/mem.h diff --git a/include/vfn/support/mem.h b/include/vfn/support/mem.h index 6773c4b1..e98e8fb1 100644 --- a/include/vfn/support/mem.h +++ b/include/vfn/support/mem.h @@ -40,41 +40,11 @@ static inline size_t __abort_on_overflow(unsigned int n, size_t sz) return n * sz; } -/** - * xmalloc - version of malloc that cannot fail - * @sz: number of bytes to allocate - * - * Call malloc, but only return NULL when @sz is zero. Otherwise, abort. - * - * Return: pointer to allocated memory - */ -static inline void *xmalloc(size_t sz) -{ - void *mem; - - if (unlikely(!sz)) - return NULL; - - mem = malloc(sz); - if (unlikely(!mem)) - backtrace_abort(); - - return mem; -} - -static inline void *zmalloc(size_t sz) -{ - void *mem; - - if (unlikely(!sz)) - return NULL; - - mem = calloc(1, sz); - if (unlikely(!mem)) - backtrace_abort(); - - return mem; -} +#ifdef __APPLE__ +# include "vfn/support/platform/driverkit/mem.h" +#else +# include "vfn/support/platform/posix/mem.h" +#endif static inline void *mallocn(unsigned int n, size_t sz) { @@ -98,17 +68,6 @@ static inline void *zmallocn(unsigned int n, size_t sz) return zmalloc(n * sz); } -static inline void *reallocn(void *mem, unsigned int n, size_t sz) -{ - if (would_overflow(n, sz)) { - fprintf(stderr, "allocation of %d * %zu bytes would overflow\n", n, sz); - - backtrace_abort(); - } - - return realloc(mem, n * sz); -} - #define _new_t(t, n, f) \ ((t *) f(n, sizeof(t))) diff --git a/include/vfn/support/platform/driverkit/mem.h b/include/vfn/support/platform/driverkit/mem.h new file mode 100644 index 00000000..9e8830ec --- /dev/null +++ b/include/vfn/support/platform/driverkit/mem.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later or MIT */ + +/* + * This file is part of libvfn. + * + * Copyright (C) 2024 The libvfn Authors. All Rights Reserved. + * + * This library (libvfn) is dual licensed under the GNU Lesser General + * Public License version 2.1 or later or the MIT license. See the + * COPYING and LICENSE files for more information. + */ + +#ifndef LIBVFN_SUPPORT_PLATFORM_DRIVERKIT_MEM_H +#define LIBVFN_SUPPORT_PLATFORM_DRIVERKIT_MEM_H + +#include +#include + +static inline void *xmalloc(size_t sz) +{ + void *mem; + + if (unlikely(!sz)) + return NULL; + + sz += sizeof(uint64_t); + + mem = IOMalloc(sz); + if (unlikely(!mem)) + backtrace_abort(); + + /* prepend length of allocationl (we need it on free) */ + *(uint64_t *)mem = sz; + + return (void *)(((char *)mem) + sizeof(uint64_t)); +} + +static inline void *zmalloc(size_t sz) +{ + void *mem; + + if (unlikely(!sz)) + return NULL; + + sz += sizeof(uint64_t); + + mem = IOMallocZero(sz); + if (unlikely(!mem)) + backtrace_abort(); + + /* prepend length of allocationl (we need it on free) */ + *(uint64_t *)mem = sz; + + return (void *)(((char *)mem) + sizeof(uint64_t)); +} + +static inline void free(void *ptr) +{ + void *real_ptr = (void *)(((uint8_t *)ptr) - sizeof(uint64_t)); + uint64_t len = *(uint64_t *)real_ptr; + + IOFree(real_ptr, len); +} + +#endif /* LIBVFN_SUPPORT_PLATFORM_DRIVERKIT_MEM_H */ diff --git a/include/vfn/support/platform/posix/mem.h b/include/vfn/support/platform/posix/mem.h new file mode 100644 index 00000000..ca362a6d --- /dev/null +++ b/include/vfn/support/platform/posix/mem.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later or MIT */ + +/* + * This file is part of libvfn. + * + * Copyright (C) 2022 The libvfn Authors. All Rights Reserved. + * + * This library (libvfn) is dual licensed under the GNU Lesser General + * Public License version 2.1 or later or the MIT license. See the + * COPYING and LICENSE files for more information. + */ + +#ifndef LIBVFN_SUPPORT_PLATFORM_POSIX_MEM_H +#define LIBVFN_SUPPORT_PLATFORM_POSIX_MEM_H + +/** + * xmalloc - version of malloc that cannot fail + * @sz: number of bytes to allocate + * + * Call malloc, but only return NULL when @sz is zero. Otherwise, abort. + * + * Return: pointer to allocated memory + */ +static inline void *xmalloc(size_t sz) +{ + void *mem; + + if (unlikely(!sz)) + return NULL; + + mem = malloc(sz); + if (unlikely(!mem)) + backtrace_abort(); + + return mem; +} + +static inline void *zmalloc(size_t sz) +{ + void *mem; + + if (unlikely(!sz)) + return NULL; + + mem = calloc(1, sz); + if (unlikely(!mem)) + backtrace_abort(); + + return mem; +} + +static inline void *reallocn(void *mem, unsigned int n, size_t sz) +{ + if (would_overflow(n, sz)) { + fprintf(stderr, "allocation of %d * %zu bytes would overflow\n", n, sz); + + backtrace_abort(); + } + + return realloc(mem, n * sz); +} + +#endif /* LIBVFN_SUPPORT_PLATFORM_POSIX_MEM_H */