diff options
-rw-r--r-- | cmd/sbc_harness/fs_harness_uptime_txt.c | 4 | ||||
-rw-r--r-- | lib9p/srv.c | 4 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_shutdown.c | 4 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_slowread.c | 4 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_whoami.c | 6 | ||||
-rw-r--r-- | libcr_ipc/chan.c | 4 | ||||
-rw-r--r-- | libhw_cr/host_net.c | 3 | ||||
-rw-r--r-- | libhw_cr/rp2040_hwspi.c | 6 | ||||
-rw-r--r-- | libhw_cr/w5500_ll.h | 6 | ||||
-rw-r--r-- | libmisc/include/libmisc/alloc.h | 26 | ||||
-rw-r--r-- | libmisc/map.c | 3 |
11 files changed, 50 insertions, 20 deletions
diff --git a/cmd/sbc_harness/fs_harness_uptime_txt.c b/cmd/sbc_harness/fs_harness_uptime_txt.c index 1425bf9..dd5c681 100644 --- a/cmd/sbc_harness/fs_harness_uptime_txt.c +++ b/cmd/sbc_harness/fs_harness_uptime_txt.c @@ -5,10 +5,10 @@ */ #include <stdio.h> /* for snprintf() */ -#include <stdlib.h> /* for malloc(), free() */ #include <libhw/generic/alarmclock.h> #include <util9p/static.h> +#include <libmisc/alloc.h> /* for heap_alloc(), free() */ #include "fs_harness_uptime_txt.h" @@ -91,7 +91,7 @@ static lo_interface lib9p_srv_fio uptime_file_fopen(struct uptime_file *self, st assert(self); assert(ctx); - struct uptime_fio *ret = malloc(sizeof(struct uptime_fio)); + struct uptime_fio *ret = heap_alloc(1, struct uptime_fio); ret->parent = self; ret->buf_len = 0; diff --git a/lib9p/srv.c b/lib9p/srv.c index 5c50130..a681952 100644 --- a/lib9p/srv.c +++ b/lib9p/srv.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -#include <alloca.h> #include <inttypes.h> /* for PRI* */ #include <limits.h> /* for SSIZE_MAX, not set by newlib */ #include <stddef.h> /* for size_t */ @@ -17,6 +16,7 @@ #include <libcr/coroutine.h> #include <libcr_ipc/chan.h> #include <libcr_ipc/mutex.h> +#include <libmisc/alloc.h> #include <libmisc/assert.h> #include <libmisc/endian.h> #include <libmisc/map.h> @@ -739,7 +739,7 @@ static void handle_Tversion(struct srv_req *ctx, if (map_len(&ctx->parent_sess->reqs)) { /* Flush all in-progress requests, and wait for them * to finish. */ - struct cr_select_arg *list = alloca(sizeof(struct cr_select_arg) * map_len(&ctx->parent_sess->reqs)); + struct cr_select_arg *list = stack_alloc(map_len(&ctx->parent_sess->reqs), struct cr_select_arg); while (map_len(&ctx->parent_sess->reqs)) { size_t i = 0; bool flushed; diff --git a/lib9p/tests/test_server/fs_shutdown.c b/lib9p/tests/test_server/fs_shutdown.c index e872b78..e7375ef 100644 --- a/lib9p/tests/test_server/fs_shutdown.c +++ b/lib9p/tests/test_server/fs_shutdown.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -#include <stdlib.h> +#include <libmisc/alloc.h> #include "fs_shutdown.h" @@ -68,7 +68,7 @@ static lo_interface lib9p_srv_fio shutdown_file_fopen(struct shutdown_file *self assert(self); assert(ctx); - struct shutdown_fio *ret = malloc(sizeof(struct shutdown_fio)); + struct shutdown_fio *ret = heap_alloc(1, struct shutdown_fio); ret->parent = self; return lo_box_shutdown_fio_as_lib9p_srv_fio(ret); diff --git a/lib9p/tests/test_server/fs_slowread.c b/lib9p/tests/test_server/fs_slowread.c index c94fba0..4567fef 100644 --- a/lib9p/tests/test_server/fs_slowread.c +++ b/lib9p/tests/test_server/fs_slowread.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -#include <stdlib.h> +#include <libmisc/alloc.h> #include "fs_slowread.h" @@ -68,7 +68,7 @@ static lo_interface lib9p_srv_fio slowread_file_fopen(struct slowread_file *self assert(self); assert(ctx); - struct slowread_fio *ret = malloc(sizeof(struct slowread_fio)); + struct slowread_fio *ret = heap_alloc(1, struct slowread_fio); ret->parent = self; return lo_box_slowread_fio_as_lib9p_srv_fio(ret); diff --git a/lib9p/tests/test_server/fs_whoami.c b/lib9p/tests/test_server/fs_whoami.c index 560e31f..653ac4b 100644 --- a/lib9p/tests/test_server/fs_whoami.c +++ b/lib9p/tests/test_server/fs_whoami.c @@ -5,7 +5,9 @@ */ #include <stdio.h> /* for snprintf() */ -#include <stdlib.h> /* for malloc(), realloc(), free() */ +#include <stdlib.h> /* for realloc(), free() */ + +#include <libmisc/alloc.h> #include "fs_whoami.h" @@ -89,7 +91,7 @@ static lo_interface lib9p_srv_fio whoami_file_fopen(struct whoami_file *self, st assert(self); assert(ctx); - struct whoami_fio *ret = malloc(sizeof(struct whoami_fio)); + struct whoami_fio *ret = heap_alloc(1, struct whoami_fio); ret->parent = self; ret->buf_len = 0; ret->buf = NULL; diff --git a/libcr_ipc/chan.c b/libcr_ipc/chan.c index 6cbe890..f20b8a0 100644 --- a/libcr_ipc/chan.c +++ b/libcr_ipc/chan.c @@ -4,10 +4,10 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -#include <alloca.h> /* for alloca() */ #include <string.h> /* for memcpy() */ #include <libcr/coroutine.h> /* for cid_t, cr_* */ +#include <libmisc/alloc.h> #include <libmisc/assert.h> #include <libmisc/rand.h> @@ -150,7 +150,7 @@ size_t cr_select_v(size_t arg_cnt, struct cr_select_arg arg_vec[]) { struct cr_select_waiters waiters = { .cnt = arg_cnt, .args = arg_vec, - .nodes = alloca(sizeof(struct cr_chan_waiter) * arg_cnt), + .nodes = stack_alloc(arg_cnt, struct _cr_chan_waiter_list_node), }; for (size_t i = 0; i < arg_cnt; i++) { waiters.nodes[i] = (struct _cr_chan_waiter_list_node){ .val = { diff --git a/libhw_cr/host_net.c b/libhw_cr/host_net.c index 6ed6e46..ba634a6 100644 --- a/libhw_cr/host_net.c +++ b/libhw_cr/host_net.c @@ -19,6 +19,7 @@ #include <signal.h> /* for siginfo_t, struct sigaction, enum sigval, sigaction(), SA_SIGINFO */ #include <libcr/coroutine.h> +#include <libmisc/alloc.h> #include <libmisc/assert.h> #include <libmisc/macro.h> #include <libobj/obj.h> @@ -283,7 +284,7 @@ static void *hostnet_pthread_writev(void *_args) { struct hostnet_pthread_writev_args *args = _args; size_t count = 0; - struct iovec *iov = alloca(sizeof(struct iovec)*args->iovcnt); + struct iovec *iov = stack_alloc(args->iovcnt, struct iovec); for (int i = 0; i < args->iovcnt; i++) { iov[i] = args->iov[i]; count += args->iov[i].iov_len; diff --git a/libhw_cr/rp2040_hwspi.c b/libhw_cr/rp2040_hwspi.c index d181650..29a7bac 100644 --- a/libhw_cr/rp2040_hwspi.c +++ b/libhw_cr/rp2040_hwspi.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -#include <alloca.h> #include <inttypes.h> /* for PRIu{n} */ #include <hardware/clocks.h> /* for clock_get_hz() and clk_peri */ @@ -12,6 +11,7 @@ #include <hardware/spi.h> #include <libcr/coroutine.h> +#include <libmisc/alloc.h> #include <libmisc/assert.h> #define LOG_NAME RP2040_SPI @@ -198,8 +198,8 @@ static void rp2040_hwspi_readwritev(struct rp2040_hwspi *self, const struct dupl * happens, so the IRQ machinery doesn't need to be engaged * at all. */ - struct dma_alias1 *tx_data_blocks = alloca(sizeof(struct dma_alias1)*(pruned_iovcnt+1)); - struct dma_alias0 *rx_data_blocks = alloca(sizeof(struct dma_alias0)*(pruned_iovcnt+1)); + struct dma_alias1 *tx_data_blocks = stack_alloc(pruned_iovcnt+1, struct dma_alias1); + struct dma_alias0 *rx_data_blocks = stack_alloc(pruned_iovcnt+1, struct dma_alias0); static_assert(!DMA_IS_TRIGGER(typeof(tx_data_blocks[0]), ctrl)); static_assert(DMA_IS_TRIGGER(typeof(rx_data_blocks[0]), ctrl)); diff --git a/libhw_cr/w5500_ll.h b/libhw_cr/w5500_ll.h index 2506cd2..8b98f9d 100644 --- a/libhw_cr/w5500_ll.h +++ b/libhw_cr/w5500_ll.h @@ -10,10 +10,10 @@ #ifndef _LIBHW_CR_W5500_LL_H_ #define _LIBHW_CR_W5500_LL_H_ -#include <alloca.h> /* for alloca() */ #include <stdint.h> /* for uint{n}_t */ #include <string.h> /* for memcmp() */ +#include <libmisc/alloc.h> /* for stack_alloc() */ #include <libmisc/assert.h> /* for assert(), static_assert() */ #include <libmisc/endian.h> /* for uint16be_t */ @@ -94,7 +94,7 @@ w5500ll_writev( (block & CTL_MASK_BLOCK) | CTL_W | CTL_OM_VDM, }; int inner_cnt = 1+io_slice_cnt(iov, iovcnt, skip, max); - struct duplex_iovec *inner = alloca(sizeof(struct duplex_iovec)*inner_cnt); + struct duplex_iovec *inner = stack_alloc(inner_cnt, struct duplex_iovec); inner[0] = (struct duplex_iovec){ .iov_read_to = IOVEC_DISCARD, .iov_write_from = header, @@ -131,7 +131,7 @@ w5500ll_readv( (block & CTL_MASK_BLOCK) | CTL_R | CTL_OM_VDM, }; int inner_cnt = 1+io_slice_cnt(iov, iovcnt, 0, max); - struct duplex_iovec *inner = alloca(sizeof(struct duplex_iovec)*inner_cnt); + struct duplex_iovec *inner = stack_alloc(inner_cnt, struct duplex_iovec); inner[0] = (struct duplex_iovec){ .iov_read_to = IOVEC_DISCARD, .iov_write_from = header, diff --git a/libmisc/include/libmisc/alloc.h b/libmisc/include/libmisc/alloc.h new file mode 100644 index 0000000..afddbce --- /dev/null +++ b/libmisc/include/libmisc/alloc.h @@ -0,0 +1,26 @@ +/* libmisc/alloc.h - Type-safe wrappers around alloca and malloc + * + * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIBMISC_ALLOC_H_ +#define _LIBMISC_ALLOC_H_ + +#include <alloca.h> /* for alloca() */ +#include <stdlib.h> /* for calloc(), free() */ +#include <string.h> /* for memset() */ + +#define stack_alloc(N, TYP) ({ \ + size_t _size; \ + TYP *_ret = NULL; \ + if (!__builtin_mul_overflow(N, sizeof(TYP), &_size)) { \ + _ret = alloca(_size); \ + memset(_ret, 0, _size); \ + } \ + _ret; \ +}) + +#define heap_alloc(N, TYP) ((TYP *)calloc(N, sizeof(TYP))) + +#endif /* _LIBMISC_ALLOC_H_ */ diff --git a/libmisc/map.c b/libmisc/map.c index 7629c8c..cc34c16 100644 --- a/libmisc/map.c +++ b/libmisc/map.c @@ -8,6 +8,7 @@ #include <string.h> #include <libmisc/hash.h> +#include <libmisc/alloc.h> #include <libmisc/assert.h> #include <libmisc/map.h> @@ -63,7 +64,7 @@ static inline void _map_lookup(struct _map *m, void *keyp, static inline void _map_resize(struct _map *m, size_t new_nbuckets) { assert(m); assert(new_nbuckets); - struct _map_kv_list *new_buckets = calloc(new_nbuckets, sizeof(struct _map_kv_list)); + struct _map_kv_list *new_buckets = heap_alloc(new_nbuckets, struct _map_kv_list); for (size_t i = 0; i < m->nbuckets; i++) { while (m->buckets[i].front) { struct _map_kv_list_node *kv = m->buckets[i].front; |