MT#55283 support zero-copy string references

If a string is already stored within the call's memory arena, skip
duplicating the string content when making a copy, and simply return the
same pointer.

Change-Id: I50107d87b2625234a395da21e1e4551585966a60
pull/1870/head
Richard Fuchs 7 months ago
parent 201c15489c
commit 9fbddb2e5e

@ -874,39 +874,51 @@ INLINE void *call_malloc(size_t l) {
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;
}
INLINE char *call_strdup_len(const char *s, size_t len) {
INLINE char *call_strdup_len(const char *s, size_t len, char *(*dup)(const char *, size_t)) {
char *r;
if (!s)
return NULL;
r = call_malloc(len + 1);
memcpy(r, s, len);
r[len] = 0;
dup = dup ?: call_dup;
r = dup(s, len);
return r;
}
INLINE char *call_strdup(const char *s) {
if (!s)
return NULL;
return call_strdup_len(s, strlen(s));
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);
return call_strdup_len(s->s, s->len, s->dup);
}
INLINE str call_str_cpy_len(const char *in, size_t len) {
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);
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_len(in ? in->s : NULL, in ? in->len : 0);
return call_str_cpy_fn(in ? in->s : NULL, in ? in->len : 0, in->dup);
}
INLINE str call_str_cpy_c(const char *in) {
return call_str_cpy_len(in, in ? strlen(in) : 0);

@ -15,6 +15,7 @@
struct _str {
char *s;
size_t len;
char *(*dup)(const char *, size_t);
};
typedef struct _str str;
@ -34,17 +35,17 @@ TYPED_GQUEUE(str, str)
#define FMT_M(x...) rtpe_common_config_ptr->log_mark_prefix, x, \
rtpe_common_config_ptr->log_mark_suffix
#define STR_NULL ((str) { NULL, 0 })
#define STR_EMPTY ((str) { "", 0 })
#define STR_CONST(s) ((str) { s, sizeof(s)-1 })
#define STR(s) ({ const char *__s = (s); (str) { (char *) (__s), (__s) ? strlen(__s) : 0 }; })
#define STR_PTR(s) (&((str) { (char *) (s), (s) ? strlen(s) : 0 }))
#define STR_NC(s) ((str) { (char *) (s), strlen(s) })
#define STR_GS(s) ((str) { (s)->str, (s)->len })
#define STR_LEN(s, len) ((str) { (char *) (s), len })
#define STR_LEN_ASSERT(s, len) ({ assert(sizeof(s) >= len); (str) { (char *) (s), len }; })
#define STR_DUP(s) ({ const char *__s = (s); size_t __l = strlen(__s); (str) { __g_memdup(__s, __l + 1), __l }; })
#define STR_CONST_BUF(buf) ((str) { (char *) &buf, sizeof(buf) })
#define STR_NULL ((str) { NULL, 0, NULL })
#define STR_EMPTY ((str) { "", 0, NULL })
#define STR_CONST(s) ((str) { s, sizeof(s)-1, NULL })
#define STR(s) ({ const char *__s = (s); (str) { (char *) (__s), (__s) ? strlen(__s) : 0, NULL }; })
#define STR_PTR(s) (&((str) { (char *) (s), (s) ? strlen(s) : 0, NULL }))
#define STR_NC(s) ((str) { (char *) (s), strlen(s), NULL })
#define STR_GS(s) ((str) { (s)->str, (s)->len, NULL })
#define STR_LEN(s, len) ((str) { (char *) (s), len, NULL })
#define STR_LEN_ASSERT(s, len) ({ assert(sizeof(s) >= len); (str) { (char *) (s), len, NULL }; })
#define STR_DUP(s) ({ const char *__s = (s); size_t __l = strlen(__s); (str) { __g_memdup(__s, __l + 1), __l, NULL }; })
#define STR_CONST_BUF(buf) ((str) { (char *) &buf, sizeof(buf), NULL })
@ -321,6 +322,7 @@ INLINE str *str_alloc(size_t len) {
r = malloc(sizeof(*r) + len + 1);
r->s = ((char *) r) + sizeof(*r);
r->len = 0;
r->dup = NULL;
return r;
}
INLINE str *str_dup(const str *s) {

Loading…
Cancel
Save