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
pull/1897/head
Richard Fuchs 4 months ago
parent df37f0884a
commit a28b2b5415

@ -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

@ -0,0 +1,3 @@
#include "arena.h"
__thread memory_arena_t *memory_arena;

@ -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();

@ -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

@ -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

1
t/.gitignore vendored

@ -88,3 +88,4 @@ test-amr-encode
bufferpool.c
uring.c
aead-decrypt
arena.c

@ -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

Loading…
Cancel
Save