From a28b2b541581d100e77a237498dcb78a289d6463 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 10 Jan 2025 14:47:20 -0400 Subject: [PATCH] MT#61822 generalise memory arena Introduce global generic memory arena variable, instead of having just a call-specific memory arena. This makes it possible to use memory arena outside of call contexts. Define previous call-specific functions in terms of the generic ones. Change-Id: Icde4f63f02dacbf8abfbaf107ea8b5bbe18d5eb8 --- daemon/Makefile | 2 +- daemon/arena.c | 3 ++ daemon/call.c | 4 +-- include/arena.h | 74 ++++++++++++++++++++++++++++++++++++++++++++ include/call.h | 82 ++++++++----------------------------------------- t/.gitignore | 1 + t/Makefile | 6 ++-- 7 files changed, 97 insertions(+), 75 deletions(-) create mode 100644 daemon/arena.c create mode 100644 include/arena.h diff --git a/daemon/Makefile b/daemon/Makefile index c044789b4..6cd7711ad 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -92,7 +92,7 @@ SRCS= main.c kernel.c helpers.c control_tcp.c call.c control_udp.c redis.c \ crypto.c rtp.c call_interfaces.strhash.c dtls.c log.c cli.c graphite.c ice.c \ media_socket.c homer.c recording.c statistics.c cdr.c ssrc.c iptables.c tcp_listener.c \ codec.c load.c dtmf.c timerthread.c media_player.c jitter_buffer.c t38.c websocket.c \ - mqtt.c janus.strhash.c audio_player.c + mqtt.c janus.strhash.c audio_player.c arena.c ifneq ($(without_nftables),yes) SRCS+= nftables.c endif diff --git a/daemon/arena.c b/daemon/arena.c new file mode 100644 index 000000000..94654ff45 --- /dev/null +++ b/daemon/arena.c @@ -0,0 +1,3 @@ +#include "arena.h" + +__thread memory_arena_t *memory_arena; diff --git a/daemon/call.c b/daemon/call.c index b377acfb9..e969fba87 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -4306,7 +4306,7 @@ static void __call_free(call_t *c) { g_slice_free1(sizeof(*ps), ps); } - call_buffer_free(&c->buffer); + memory_arena_free(&c->buffer); ice_fragments_cleanup(c->sdp_fragments, true); t_hash_table_destroy(c->sdp_fragments); rwlock_destroy(&c->master_lock); @@ -4319,7 +4319,7 @@ static call_t *call_create(const str *callid) { ilog(LOG_NOTICE, "Creating new call"); c = obj_alloc0(call_t, __call_free); - call_buffer_init(&c->buffer); + memory_arena_init(&c->buffer); rwlock_init(&c->master_lock); c->tags = tags_ht_new(); c->viabranches = tags_ht_new(); diff --git a/include/arena.h b/include/arena.h new file mode 100644 index 000000000..daf692565 --- /dev/null +++ b/include/arena.h @@ -0,0 +1,74 @@ +#ifndef _ARENA_H_ +#define _ARENA_H_ + +#include "compat.h" +#include "bencode.h" + +typedef bencode_buffer_t memory_arena_t; + +extern __thread memory_arena_t *memory_arena; + +#define memory_arena_init bencode_buffer_init +#define memory_arena_free bencode_buffer_free + +INLINE void *memory_arena_alloc(size_t l) { + void *ret; + ret = bencode_buffer_alloc(memory_arena, l); + return ret; +} +INLINE char *memory_arena_dup(const char *b, size_t len) { + char *ret = memory_arena_alloc(len + 1); + memcpy(ret, b, len); + ret[len] = '\0'; + return ret; +} +INLINE char *memory_arena_ref(const char *b, size_t len) { + return (char *) b; +} +INLINE char *memory_arena_strdup_len(const char *s, size_t len, char *(*dup)(const char *, size_t)) { + char *r; + if (!s) + return NULL; + dup = dup ?: memory_arena_dup; + r = dup(s, len); + return r; +} + +INLINE char *memory_arena_strdup(const char *s) { + if (!s) + return NULL; + return memory_arena_strdup_len(s, strlen(s), NULL); +} +INLINE char *memory_arena_strdup_str(const str *s) { + if (!s) + return NULL; + return memory_arena_strdup_len(s->s, s->len, s->dup); +} +INLINE str memory_arena_str_cpy_fn(const char *in, size_t len, char *(*dup)(const char *, size_t)) { + str out; + if (!in) { + out = STR_NULL; + return out; + } + out.s = memory_arena_strdup_len(in, len, dup); + out.len = len; + out.dup = memory_arena_ref; + return out; +} +INLINE str memory_arena_str_cpy_len(const char *in, size_t len) { + return memory_arena_str_cpy_fn(in, len, NULL); +} +INLINE str memory_arena_str_cpy(const str *in) { + return memory_arena_str_cpy_fn((in ? in->s : NULL), (in ? in->len : 0), (in ? in->dup : NULL)); +} +INLINE str memory_arena_str_cpy_c(const char *in) { + return memory_arena_str_cpy_len(in, in ? strlen(in) : 0); +} +INLINE str *memory_arena_str_dup(const str *in) { + str *out; + out = memory_arena_alloc(sizeof(*out)); + *out = memory_arena_str_cpy_len(in->s, in->len); + return out; +} + +#endif diff --git a/include/call.h b/include/call.h index 04223bc4f..3d3794720 100644 --- a/include/call.h +++ b/include/call.h @@ -293,6 +293,7 @@ enum block_dtmf_mode { #include "crypto.h" #include "dtls.h" #include "dtmf.h" +#include "arena.h" struct control_stream; @@ -315,11 +316,6 @@ struct janus_session; struct audio_player; struct media_subscription; -typedef bencode_buffer_t call_buffer_t; -#define call_buffer_alloc bencode_buffer_alloc -#define call_buffer_init bencode_buffer_init -#define call_buffer_free bencode_buffer_free - @@ -728,7 +724,7 @@ struct call { */ struct obj obj; - call_buffer_t buffer; + memory_arena_t buffer; // use a single poller for all sockets within the call struct poller *poller; @@ -887,71 +883,17 @@ const rtp_payload_type *__rtp_stats_codec(struct call_media *m); #include "str.h" #include "rtp.h" -INLINE void *call_malloc(size_t l) { - void *ret; - ret = call_buffer_alloc(&call_memory_arena->buffer, l); - return ret; -} -INLINE char *call_dup(const char *b, size_t len) { - char *ret = call_malloc(len + 1); - memcpy(ret, b, len); - ret[len] = '\0'; - return ret; -} -INLINE char *call_ref(const char *b, size_t len) { - return (char *) b; -} +#define call_malloc memory_arena_alloc +#define call_dup memory_arena_dup +#define call_ref memory_arena_ref -INLINE char *call_strdup_len(const char *s, size_t len, char *(*dup)(const char *, size_t)) { - char *r; - if (!s) - return NULL; - dup = dup ?: call_dup; - r = dup(s, len); - return r; -} +#define call_strdup memory_arena_strdup +#define call_strdup_str memory_arena_strdup_str +#define call_str_cpy_len memory_arena_str_cpy_len +#define call_str_cpy memory_arena_str_cpy +#define call_str_cpy_c memory_arena_str_cpy_c +#define call_str_dup memory_arena_str_dup -INLINE char *call_strdup(const char *s) { - if (!s) - return NULL; - return call_strdup_len(s, strlen(s), NULL); -} -INLINE char *call_strdup_str(const str *s) { - if (!s) - return NULL; - return call_strdup_len(s->s, s->len, s->dup); -} -INLINE str call_str_cpy_fn(const char *in, size_t len, char *(*dup)(const char *, size_t)) { - str out; - if (!in) { - out = STR_NULL; - return out; - } - out.s = call_strdup_len(in, len, dup); - out.len = len; - out.dup = call_ref; - return out; -} -INLINE str call_str_cpy_len(const char *in, size_t len) { - return call_str_cpy_fn(in, len, NULL); -} -INLINE str call_str_cpy(const str *in) { - return call_str_cpy_fn((in ? in->s : NULL), (in ? in->len : 0), (in ? in->dup : NULL)); -} -INLINE str call_str_cpy_c(const char *in) { - return call_str_cpy_len(in, in ? strlen(in) : 0); -} -INLINE str *call_str_dup(const str *in) { - str *out; - out = call_malloc(sizeof(*out)); - *out = call_str_cpy_len(in->s, in->len); - return out; -} -INLINE str *call_str_init_dup(char *s) { - str t; - t = STR(s); - return call_str_dup(&t); -} INLINE void __call_unkernelize(call_t *call, const char *reason) { for (__auto_type l = call->monologues.head; l; l = l->next) { struct call_monologue *ml = l->data; @@ -980,10 +922,12 @@ INLINE void call_memory_arena_release(void) { return; obj_put(call_memory_arena); call_memory_arena = NULL; + memory_arena = NULL; } INLINE void call_memory_arena_set(call_t *c) { call_memory_arena_release(); call_memory_arena = obj_get(c); + memory_arena = &c->buffer; } #endif diff --git a/t/.gitignore b/t/.gitignore index 98710b716..81eb775cc 100644 --- a/t/.gitignore +++ b/t/.gitignore @@ -88,3 +88,4 @@ test-amr-encode bufferpool.c uring.c aead-decrypt +arena.c diff --git a/t/Makefile b/t/Makefile index 2f72befff..d0ae716db 100644 --- a/t/Makefile +++ b/t/Makefile @@ -83,7 +83,7 @@ DAEMONSRCS+= control_ng_flags_parser.c codec.c call.c ice.c kernel.c media_socke dtls.c recording.c statistics.c rtcp.c redis.c iptables.c graphite.c \ cookie_cache.c udp_listener.c homer.c load.c cdr.c dtmf.c timerthread.c \ media_player.c jitter_buffer.c t38.c tcp_listener.c mqtt.c websocket.c cli.c \ - audio_player.c + audio_player.c arena.c HASHSRCS+= call_interfaces.c control_ng.c sdp.c janus.c LIBASM= mvr2s_x64_avx2.S mvr2s_x64_avx512.S mix_in_x64_avx2.S mix_in_x64_avx512bw.S mix_in_x64_sse2.S endif @@ -256,7 +256,7 @@ test-stats: test-stats.o $(COMMONOBJS) codeclib.strhash.o resample.o codec.o ssr streambuf.o cookie_cache.o udp_listener.o homer.o load.o cdr.o dtmf.o timerthread.o \ media_player.o jitter_buffer.o dtmflib.o t38.o tcp_listener.o mqtt.o janus.strhash.o \ websocket.o cli.o mvr2s_x64_avx2.o mvr2s_x64_avx512.o audio_player.o mix_buffer.o \ - mix_in_x64_avx2.o mix_in_x64_sse2.o mix_in_x64_avx512bw.o bufferpool.o uring.o + mix_in_x64_avx2.o mix_in_x64_sse2.o mix_in_x64_avx512bw.o bufferpool.o uring.o arena.o test-transcode: test-transcode.o $(COMMONOBJS) codeclib.strhash.o resample.o codec.o ssrc.o call.o ice.o helpers.o \ kernel.o media_socket.o stun.o bencode.o socket.o poller.o dtls.o recording.o statistics.o \ @@ -265,7 +265,7 @@ test-transcode: test-transcode.o $(COMMONOBJS) codeclib.strhash.o resample.o cod streambuf.o cookie_cache.o udp_listener.o homer.o load.o cdr.o dtmf.o timerthread.o \ media_player.o jitter_buffer.o dtmflib.o t38.o tcp_listener.o mqtt.o janus.strhash.o websocket.o \ cli.o mvr2s_x64_avx2.o mvr2s_x64_avx512.o audio_player.o mix_buffer.o \ - mix_in_x64_avx2.o mix_in_x64_sse2.o mix_in_x64_avx512bw.o bufferpool.o uring.o + mix_in_x64_avx2.o mix_in_x64_sse2.o mix_in_x64_avx512bw.o bufferpool.o uring.o arena.o test-resample: test-resample.o $(COMMONOBJS) codeclib.strhash.o resample.o dtmflib.o mvr2s_x64_avx2.o \ mvr2s_x64_avx512.o