Port to new memory model

This commit is contained in:
Patrick Pelissier committed 2025-05-07 21:02:23 +02:00
1 parent bf617ab6ab
commit 9e63289a38
2 files changed
+46 -38

No files matched your search

+45 -37
View File
@@ -74,8 +74,7 @@ m_bstring_init(m_bstring_t s)
M_BSTRING_CONTRACT(s); M_BSTRING_CONTRACT(s);
} }
M_INLINE void M_P(void, m_bstring, _clear, m_bstring_t s)
m_bstring_clear(m_bstring_t s)
{ {
M_BSTRING_CONTRACT(s); M_BSTRING_CONTRACT(s);
M_MEMORY_FREE(uint8_t, s->ptr, s->alloc); M_MEMORY_FREE(uint8_t, s->ptr, s->alloc);
@@ -138,8 +137,7 @@ m_bstring_empty_p(const m_bstring_t v)
allocations. allocations.
Return a pointer to the writable string. Return a pointer to the writable string.
*/ */
M_INLINE uint8_t * M_P(uint8_t *, m_bstr1ng, _fit2size, m_bstring_t v, size_t size_alloc, bool exact_alloc)
m_bstr1ng_fit2size (m_bstring_t v, size_t size_alloc, bool exact_alloc)
{ {
// Very unlikely overflow case // Very unlikely overflow case
if (M_UNLIKELY_NOMEM (v->offset > v->offset + size_alloc)) { if (M_UNLIKELY_NOMEM (v->offset > v->offset + size_alloc)) {
@@ -187,52 +185,52 @@ m_bstr1ng_fit2size (m_bstring_t v, size_t size_alloc, bool exact_alloc)
} }
/* Push the byte 'c' in the bstring 'v' */ /* Push the byte 'c' in the bstring 'v' */
M_INLINE void M_P(void, m_bstring, _push_back, m_bstring_t v, uint8_t c)
m_bstring_push_back (m_bstring_t v, uint8_t c)
{ {
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
const size_t size = v->size; const size_t size = v->size;
uint8_t *ptr = m_bstr1ng_fit2size(v, size+1, false); // To overflow size+1, we need to have exhausted all memory
// which is not possible.
uint8_t *ptr = m_bstr1ng_fit2size M_R(v, size+1, false);
ptr[size] = c; ptr[size] = c;
v->size = size + 1; v->size = size + 1;
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
} }
/* Push the array of bytes from 'buffer' in the bstring 'v' */ /* Push the array of bytes from 'buffer' in the bstring 'v' */
M_INLINE void M_P(void, m_bstring, _push_back_bytes, m_bstring_t v, size_t n, const void *buffer)
m_bstring_push_back_bytes (m_bstring_t v, size_t n, const void *buffer)
{ {
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
const size_t size = v->size; const size_t size = v->size;
M_ASSERT_INDEX (size, size + n); M_ASSERT_INDEX (size, size + n);
uint8_t *ptr = m_bstr1ng_fit2size(v, size+n, false); // If size+n overflows, it means we are giving two objects which sizes
// sum to be greater than the available memory. The memory should have exhausted before that.
// The case is not possible, or the given size of the buffer is "faked".
uint8_t *ptr = m_bstr1ng_fit2size M_R(v, size+n, false);
memcpy(&ptr[size], buffer, n); memcpy(&ptr[size], buffer, n);
v->size = size + n; v->size = size + n;
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
} }
M_INLINE void M_P(void, m_bstring, _splice, m_bstring_t dst, m_bstring_t src)
m_bstring_splice(m_bstring_t dst, m_bstring_t src)
{ {
M_BSTRING_CONTRACT (dst); M_BSTRING_CONTRACT (dst);
M_BSTRING_CONTRACT (src); M_BSTRING_CONTRACT (src);
M_ASSERT(src != dst); M_ASSERT(src != dst);
m_bstring_push_back_bytes(dst, m_bstring_size(src), m_bstr1ng_cstr(src)); m_bstring_push_back_bytes M_R(dst, m_bstring_size(src), m_bstr1ng_cstr(src));
m_bstring_reset(src); m_bstring_reset(src);
} }
M_INLINE void M_P(void, m_bstring, _init_set, m_bstring_t v, const m_bstring_t org)
m_bstring_init_set(m_bstring_t v, const m_bstring_t org)
{ {
m_bstring_init(v); m_bstring_init(v);
m_bstring_push_back_bytes(v, m_bstring_size(org), m_bstr1ng_cstr(org)); m_bstring_push_back_bytes M_R(v, m_bstring_size(org), m_bstr1ng_cstr(org));
} }
M_INLINE void M_P(void, m_bstring, _set, m_bstring_t v, const m_bstring_t org)
m_bstring_set(m_bstring_t v, const m_bstring_t org)
{ {
m_bstring_reset(v); m_bstring_reset(v);
m_bstring_push_back_bytes(v, m_bstring_size(org), m_bstr1ng_cstr(org)); m_bstring_push_back_bytes M_R(v, m_bstring_size(org), m_bstr1ng_cstr(org));
} }
M_INLINE void M_INLINE void
@@ -240,13 +238,13 @@ m_bstring_init_move(m_bstring_t v, m_bstring_t org)
{ {
M_BSTRING_CONTRACT (org); M_BSTRING_CONTRACT (org);
memcpy(v, org, sizeof (m_bstring_t)); memcpy(v, org, sizeof (m_bstring_t));
// Make org an invalid representation
org->offset = (size_t) -1; org->offset = (size_t) -1;
} }
M_INLINE void M_P(void, m_bstring, _move, m_bstring_t v, m_bstring_t org)
m_bstring_move(m_bstring_t v, m_bstring_t org)
{ {
m_bstring_clear(v); m_bstring_clear M_R(v);
m_bstring_init_move(v, org); m_bstring_init_move(v, org);
} }
@@ -351,14 +349,16 @@ m_bstring_pop_front_bytes(size_t n, void *buffer, m_bstring_t v)
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
} }
M_INLINE void M_P(void, m_bstring, _push_bytes_at, m_bstring_t v, size_t pos, size_t n, const void *buffer)
m_bstring_push_bytes_at (m_bstring_t v, size_t pos, size_t n, const void *buffer)
{ {
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
const size_t size = v->size; const size_t size = v->size;
M_ASSERT_INDEX (pos, size+1); //pos == size ==> equivalent to _push_back_bytes M_ASSERT_INDEX (pos, size+1); //pos == size ==> equivalent to _push_back_bytes
M_ASSERT_INDEX (size, size + n); M_ASSERT_INDEX (size, size + n);
uint8_t *ptr = m_bstr1ng_fit2size(v, size+n, false); // If size+n overflows, it means we are giving two objects which sizes
// sum to be greater than the available memory. The memory should have exhausted before that.
// The case is not possible.
uint8_t *ptr = m_bstr1ng_fit2size M_R(v, size+n, false);
memmove(&ptr[pos+n], &ptr[pos], size-pos); memmove(&ptr[pos+n], &ptr[pos], size-pos);
memcpy(&ptr[pos], buffer, n); memcpy(&ptr[pos], buffer, n);
v->size = size + n; v->size = size + n;
@@ -379,21 +379,19 @@ m_bstring_pop_bytes_at(size_t n, void *buffer, m_bstring_t v, size_t pos)
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
} }
M_INLINE void M_P(void, m_bstring, _resize, m_bstring_t v, size_t n)
m_bstring_resize (m_bstring_t v, size_t n)
{ {
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
const size_t size = v->size; const size_t size = v->size;
if (n > size) { if (n > size) {
uint8_t *ptr = m_bstr1ng_fit2size(v, n, true); uint8_t *ptr = m_bstr1ng_fit2size M_R(v, n, true);
memset(&ptr[size], 0, n-size); memset(&ptr[size], 0, n-size);
} }
v->size = n; v->size = n;
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
} }
M_INLINE void M_P(void, m_bstring, _reserve, m_bstring_t v, size_t n)
m_bstring_reserve (m_bstring_t v, size_t n)
{ {
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
const size_t size = v->size; const size_t size = v->size;
@@ -411,7 +409,6 @@ m_bstring_reserve (m_bstring_t v, size_t n)
if (M_UNLIKELY_NOMEM (ptr == NULL)) { if (M_UNLIKELY_NOMEM (ptr == NULL)) {
M_MEMORY_FULL(uint8_t, n); M_MEMORY_FULL(uint8_t, n);
} }
// The string cannot be fully embedded anymore.
v->ptr = ptr; v->ptr = ptr;
v->alloc = n; v->alloc = n;
} }
@@ -423,6 +420,7 @@ m_bstring_view(const m_bstring_t v, size_t offset, size_t size_requested)
{ {
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
M_ASSERT_INDEX (offset+size_requested, v->size+1); M_ASSERT_INDEX (offset+size_requested, v->size+1);
(void) size_requested;
return &m_bstr1ng_cstr(v)[offset]; return &m_bstr1ng_cstr(v)[offset];
} }
@@ -434,6 +432,7 @@ m_bstring_acquire_access(m_bstring_t v, size_t offset, size_t size_requested)
{ {
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
M_ASSERT_INDEX (offset+size_requested, v->size+1); M_ASSERT_INDEX (offset+size_requested, v->size+1);
(void) size_requested;
// Break canonical representation (this will generate assertion if a normal API is called now) // Break canonical representation (this will generate assertion if a normal API is called now)
M_SWAP(size_t, v->size, v->alloc); M_SWAP(size_t, v->size, v->alloc);
return &m_bstr1ng_cstr(v)[offset]; return &m_bstr1ng_cstr(v)[offset];
@@ -460,8 +459,7 @@ m_bstring_fwrite(FILE *f, const m_bstring_t v)
return fwrite(m_bstr1ng_cstr(v), 1, m_bstring_size(v), f); return fwrite(m_bstr1ng_cstr(v), 1, m_bstring_size(v), f);
} }
M_INLINE bool M_P(bool, m_bstring, _fread, m_bstring_t v, FILE *f, size_t num)
m_bstring_fread(m_bstring_t v, FILE *f, size_t num)
{ {
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
M_ASSERT (f != NULL); M_ASSERT (f != NULL);
@@ -470,7 +468,7 @@ m_bstring_fread(m_bstring_t v, FILE *f, size_t num)
if (M_UNLIKELY(num == 0)) { if (M_UNLIKELY(num == 0)) {
return true; return true;
} }
uint8_t *ptr = m_bstr1ng_fit2size(v, num, true); uint8_t *ptr = m_bstr1ng_fit2size M_R(v, num, true);
size_t n = fread(ptr, 1, num, f); size_t n = fread(ptr, 1, num, f);
M_ASSERT (n <= num); M_ASSERT (n <= num);
v->size = n; v->size = n;
@@ -510,8 +508,7 @@ m_bstring_out_serial(m_serial_write_t serial, const m_bstring_t v)
and set the converted value in the byte string 'v'. and set the converted value in the byte string 'v'.
See serialization for return code. See serialization for return code.
*/ */
M_INLINE m_serial_return_code_t M_P(m_serial_return_code_t, m_bstring, _in_serial, m_bstring_t v, m_serial_read_t f)
m_bstring_in_serial(m_bstring_t v, m_serial_read_t f)
{ {
M_ASSERT (f != NULL && f->m_interface != NULL); M_ASSERT (f != NULL && f->m_interface != NULL);
M_BSTRING_CONTRACT (v); M_BSTRING_CONTRACT (v);
@@ -523,7 +520,7 @@ m_bstring_in_serial(m_bstring_t v, m_serial_read_t f)
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) { if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) {
return ret; return ret;
} }
uint8_t *ptr = m_bstr1ng_fit2size(v, estimated_size, true); uint8_t *ptr = m_bstr1ng_fit2size M_R(v, estimated_size, true);
do { do {
long long val; long long val;
ret = f->m_interface->read_integer(f, &val, 1); ret = f->m_interface->read_integer(f, &val, 1);
@@ -547,6 +544,17 @@ m_bstring_in_serial(m_bstring_t v, m_serial_read_t f)
OUT_SERIAL(m_bstring_out_serial), IN_SERIAL(m_bstring_in_serial), \ OUT_SERIAL(m_bstring_out_serial), IN_SERIAL(m_bstring_in_serial), \
) )
/* Define the OPLIST of a BYTE STRING using POOL */
#define M_BSTRING_POOL_OPLIST \
(INIT(m_bstring_init),INIT_SET(API_0P(m_bstring_init_set)), SET(API_0P(m_bstring_set)), \
INIT_MOVE(m_bstring_init_move), MOVE(API_0P(m_bstring_move)), \
SWAP(m_bstring_swap), RESET(m_bstring_reset), \
EMPTY_P(m_bstring_empty_p), \
CLEAR(API_0P(m_bstring_clear)), HASH(m_bstring_hash), EQUAL(m_bstring_equal_p), \
CMP(m_bstring_cmp), TYPE(m_bstring_t), GENTYPE(struct m_bstring_s*), \
OUT_SERIAL(m_bstring_out_serial), IN_SERIAL(API_0P(m_bstring_in_serial=) \
)
/********************************************************************************/ /********************************************************************************/
/* */ /* */
/* Define the small name (i.e. without the prefix) of the API provided by this */ /* Define the small name (i.e. without the prefix) of the API provided by this */
+1 -1
View File
@@ -131,7 +131,7 @@
{ \ { \
M_CALL_FREE(oplist, char, ptr, sizeof(node_t) + ptr->capacity * sizeof(type)); \ M_CALL_FREE(oplist, char, ptr, sizeof(node_t) + ptr->capacity * sizeof(type)); \
} \ } \
M_ILIST_DEF(M_F(name, _node_list), node_t, (DEL(M_F(name, _del_node))) ) \ M_ILIST_DEF(M_F(name, _node_list), node_t, (DEL(M_F(name, _del_node))) ) \
\ \
/* Define an internal iterator */ \ /* Define an internal iterator */ \
typedef struct M_F(name, _it2_s) { \ typedef struct M_F(name, _it2_s) { \