From de6ccc293edfb0d63e527a1a61047a8087701db2 Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Mon, 5 May 2025 21:35:06 +0200 Subject: [PATCH] Update doc Update M_USE_GLOBAL_CONTEXT definition to be simpler. --- README.md | 391 ++++++++++++++++++++++++++++++++++++++++++++++-------- m-core.h | 4 +- 2 files changed, 336 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 95d74ce4..112cafaf 100644 --- a/README.md +++ b/README.md @@ -9632,9 +9632,10 @@ The memory context can be an [arena allocator](https://www.rfleury.com/p/untangl > [!Note] > The memory context parameter is not stored in the container -> because it is not efficient in memory usage and is redundant when you -> create container of other containers (example `array` of `string_t`). -> It is always passed as argument of the functions. +> because it is not efficient in memory usage as it is redundant when you +> create container of other containers (example `array` of `string_t`): +> all `string_t` in the array would need to store the context which is duplicate information. +> Therefore it is always passed as argument of the functions. The user shall ensure of the coherence of the memory context for a given container so that the same memory context is used from its construction to its destruction. @@ -9650,12 +9651,12 @@ As such, it is safe not to call the destructors of these containers if you have If the destructor of a mutex is also a no-op on your system, this guarantee is extended to all containers (including the thread safe containers too). -In order to use such feature, you need to: +In order to use the local context feature, you need to: * define globally `M_USE_CONTEXT` with your type. * define globally an override of the memory functions `M_MEMORY_ALLOC`, `M_MEMORY_DEL`, `M_MEMORY_REALLOC` and `M_MEMORY_FREE` to use your context. -Example +Example: ```C // Define a memory context type @@ -9692,68 +9693,344 @@ static void my_free(void *ptr, size_t old, size_t base, context_t context) #include "m-array.h" ``` -This works great for local allocators for a thread. However some containers are designed to handle -objects accross several threads: shared pointer, communication queue, ... +This works great for local allocators for a thread. +However some containers are designed to handle +objects across several threads: shared pointer, communication queue, ... For such containers, a local allocator has no meaning: it will be very hard to ensure the same allocator -is used for both the producor thread and the user threads. +is used for both the producer thread and the user threads. As a consequence, shared pointer, communication queue container and all thread containers -will use a global memory context: -M\*LIB won't add a context argument to the functions of such containers. Instead it will generate -a local parameter initialize to the global memory context. -The global memory context is defined by the macro `M_USE_GLOBAL_CONTEXT` which shall define and initialize -the named argument to the global memory context. In the absence of definition of such macro, the default is -to initialize the context to '0'. The memory functions shall recognize such context as the global one. +use a global memory context instead: +M\*LIB doesn't add a context argument to the functions of such containers. Instead it uses +the global memory context and gives this one to the memory functions. -FIXME: if it is expensive, it is useless to initialize a local variable rather than using the global variable directly... -Seems difficult to fix without. +The exact value of the global memory context is defined by the macro `M_USE_GLOBAL_CONTEXT` which shall define its value. +In the absence of definition of such macro, the default is the value '0' +(The memory functions shall recognize such context as the global one). -The following methods are modified to support the memory context parameter: +context arguments shall be settable and trivially movable using the '=' C operator. + +The following methods are modified to support the memory context parameter (the first argument of theses functions is the memory context parameter): * m-string: - * _clear - * _clear_get_cstr - * _reserve - * _set_cstr - * _set_cstrn - * _set - * _set_n - * _init_set - * _init_set_cstr - * _move - * _push_back - * _cat_cstr - * _cat - * _replace_cstr - * _replace - * _replace_at - * _replace_all_cstr - * _replace_all - * _set_ui - * _set_si - * _vprintf - * _printf - * _cat_vprintf - * _cat_printf - * _set_ui - * _set_si - * _fgets - * _fget_word - * _get_str - * _in_str - * _parse_str - * _out_serial - * _in_serial - * _it_set_ref - * _push_u - * _split - * _join - * _out_serial - * _in_serial + * string_clear + * string_clear_get_str + * string_reserve + * string_set_str + * string_set_strn + * string_set + * string_set_n + * string_init_set + * string_init_set_str + * string_move + * string_push_back + * string_cat_str + * string_cat + * string_replace_str + * string_replace + * string_replace_at + * string_replace_all_str + * string_replace_all + * string_set_ui + * string_set_si + * string_vprintf + * string_printf + * string_cat_vprintf + * string_cat_printf + * string_set_ui + * string_set_si + * string_fgets + * string_fget_word + * string_get_str + * string_in_str + * string_parse_str + * string_out_serial + * string_in_serial + * string_it_set_ref + * string_push_u + * string_split + * string_join + * string_out_serial + * string_in_serial +* m-biset: + * bitset_clear + * bitset_set + * bitset_init_set + * bitset_move + * bitset_push_back + * bitset_resize + * bitset_reserve + * bitset_push_at + * bitset_in_str + * bitset_parse_str + * bitset_set_str + * bitset_get_str +* m-bstring: + * bstring_clear + * bstring_push_back + * bstring_push_back_bytes + * bstring_splice + * bstring_init_set + * bstring_set + * bstring_move + * bstring_push_bytes_at + * bstring_resize + * bstring_reserve + * bstring_fread + * bstring_out_serial + * bstring_in_serial +* m-algo: + * _fill + * _fill_n + * _fill_a + * _fill_an + * _transform + * _reduce + * _map_reduce + * _uniq + * _remove_val + * _remove_if +* m-array: + * _reset + * _clear + * _set + * _init_set + * _move + * _set_at + * _push_raw + * _push_back + * _push_new + * _push_move + * _push_at + * _resize + * _reserve + * _safe_get + * _pop_back + * _pop_until + * _pop_at + * _erase + * _insert_v + * _remove_v + * _insert + * _remove + * _special_stable_sort + * _splice + * _get_str + * _parse_str + * _in_str + * _out_serial + * _in_serial + * _ +* m-bptree: + * _init + * _reset + * _clear + * _copy_node + * _init_set + * _set + * _set_at + * _push + * _safe_get + * _erase + * _pop_at + * _move + * _get_str + * _parse_str + * _in_str + * _out_serial + * _in_serial +* m-deque: + * _init + * _reset + * _clear + * _push_back_raw + * _push_back + * _push_back_new + * _push_back_move + * _push_front_raw + * _push_front + * _push_front_new + * _push_front_move + * _pop_back + * _pop_back_move + * _pop_front + * _pop_front_move + * _remove + * _init_set + * _set + * _move + * _set_at + * _get_str + * _parse_str + * _in_str + * _out_serial + * _in_serial + * _ + * _ +* m-dict: + * _init + * _clear + * _push + * _set_at + * _safe_get + * _erase + * _init_set + * _set + * _move + * _reset + * _reserve + * _get_str + * _parse_str + * _in_str + * _out_serial + * _in_serial + * _splice + * _bulk_get + * _bulk_set + * _bulk_update +* m-i-list + * _reset + * _clear + * _move + * _remove +* m-list + * _reset + * _clear + * _push_raw + * _push_back + * _push_new + * _pop_back + * _push_move + * _pop_move + * _insert + * _remove + * _init_set + * _set + * _move + * _get_str + * _parse_str + * _in_str + * _out_serial + * _in_serial + * _ + * _ + * _ + * _push_back_raw + * _push_raw + * _push_back + * _push_back_new + * _push_back_move + * _push_move + * _push_front_raw + * _push_front + * _push_front_move + * _push_front_new +* m-prioqueue + * _init_set + * _set + * _clear + * _move + * _reset + * _push + * _pop + * _erase + * _update + * _in_str + * _get_str + * _parse_str + * _out_serial + * _in_serial +* m-queue: + * _init + * _clear + * _init_set + * _set + * _push + * _pop +* m-rbtree: + * _reset + * _clear + * _push + * _init_set + * _set + * _move + * _pop_at + * _remove + * _get_str + * _parse_str + * _in_str + * _out_serial + * _in_serial +* m-snapshot: + * _init + * _clear + * _init_set + * _set + * _move +* m-tree: + * _reset + * _clear + * _reserve + * _set_root + * _insert_up_raw + * _insert_up + * _move_up + * _insert_down_raw + * _insert_down + * _move_down + * _insert_child_raw + * _insert_child + * _move_child + * _insert_left_raw + * _insert_left + * _move_left + * _insert_right_raw + * _insert_right + * _move_right + * _remove + * _prune + * _init_set + * _set + * _move + * _get_str + * _parse_str + * _in_str + * name + * _ + * _ + * _ + * _ + * _ +* m-tuple: + * _init + * _init_set + * _init_emplace + * _set + * _emplace + * _clear + * _get_str + * _in_str + * _parse_str + * _out_serial + * _in_serial + * _move + * _reset +* m-variant: + * _init_set + * _set + * _clear + * _move + * _get_str + * _parse_str + * _in_str + * _out_serial + * _in_serial + * _reset + > [!Note] -> The API defined by `M_USE_CONTEXT` is experimental and may change incompatibily in the future. +> The API defined by `M_USE_CONTEXT` is experimental and may change incompatibly in the future. _________________ diff --git a/m-core.h b/m-core.h index 3a8eccb5..1ad5bb4e 100644 --- a/m-core.h +++ b/m-core.h @@ -422,7 +422,7 @@ M_BEGIN_PROTECTED_CODE // Default global memory context is to consider the global context as '0' if it is not defined. #ifndef M_USE_GLOBAL_CONTEXT -#define M_USE_GLOBAL_CONTEXT(varname) M_USE_CONTEXT varname = { 0 } +#define M_USE_GLOBAL_CONTEXT 0 #endif /* In order to support local context for memory functions, the prototypes and usages of some functions are modified @@ -465,7 +465,7 @@ M_BEGIN_PROTECTED_CODE # define M_R_EXPAND_void m_context # define M_R(...) (m_context, __VA_ARGS__) # define M_UNUSED_CONTEXT() (void) m_context -# define M_GLOBAL_CONTEXT() M_USE_GLOBAL_CONTEXT(m_context); (void) m_context +# define M_GLOBAL_CONTEXT() M_USE_CONTEXT m_context = { M_USE_GLOBAL_CONTEXT }; (void) m_context #endif // M_P: Expand to a prototype of a function that may trigger exception / accept memory context