docs/Writerside/topics/allocator.h.md

branch
docs/3.1
changeset 1169
6a33a5648027
parent 1146
151c057faf7c
--- a/docs/Writerside/topics/allocator.h.md	Fri Feb 07 17:55:28 2025 +0100
+++ b/docs/Writerside/topics/allocator.h.md	Sat Feb 08 14:13:59 2025 +0100
@@ -1,51 +1,114 @@
 # Allocator
 
-<warning>
-Outdated - Rewrite!
-</warning>
+The allocator interface provides a mechanism to implement own custom allocators 
+that can also be used in many other function in UCX.
+
+A default allocator implementation using the stdlib functions is
+available via the global symbol `cxDefaultAllocator`
+and UCX also provides a [memory pool](mempool.h.md) implementation.
+You are free to add additional own custom implementations.
+A general sketch that illustrates how to do this can be found [below](#custom-allocator).
+
+## Overview
+
+```C
+void *cxMalloc(const CxAllocator *allocator, size_t n);
+
+void *cxCalloc(const CxAllocator *allocator,
+               size_t nmemb, size_t size);
+
+void *cxRealloc(const CxAllocator *allocator, void *mem, size_t n);
+
+void *cxReallocArray(const CxAllocator *allocator, void *mem,
+                     size_t nmemb, size_t size);
+
+int cxReallocate(const CxAllocator *allocator, void **mem, size_t n);
+
+int cxReallocateArray(const CxAllocator *allocator, void **mem,
+                      size_t nmemb, size_t size);
+    
+void cxFree(const CxAllocator *allocator, void *mem);
+
+int cx_reallocate(void **mem, size_t size);
+
+int cx_reallocatearray(void **mem, size_t nmemb, size_t size);
+
+// predefined allocator that uses stdlib functions
+CxAllocator *cxDefaultAllocator;
+```
 
-The UCX allocator provides an interface for implementing an own memory allocation mechanism.
-Various function in UCX provide an additional alternative signature that takes an allocator as
-argument. A default allocator implementation using the stdlib memory management functions is
-available via the global symbol `cxDefaultAllocator`.
+> All UCX functions that are not _explicitly_ designed for taking an allocator argument
+> (recognizable by a `_a` suffix in the function's name) do support a `NULL` argument
+> in which case the `cxDefaultAllocator` will be used.
+
+## Description
+
+The functions `cxMalloc()`, `cxCalloc()`, `cxRealloc()`, `cxReallocArray()`, and `cxFree()`
+invoke the memory management functions specified in the `allocator` and should behave like
+their respective stdlibc pendants.
+Implementations of the allocator interface are strongly encouraged to guarantee this behavior,
+most prominently that invocations of `cxFree()` with a `NULL`-pointer for `mem` are ignored
+instead of causing segfault error.
+
+Additionally, UCX provides the functions `cxReallocate()` and `cxReallocateArray()`, as well as
+their independent pendants `cx_reallocate()` and `cx_reallocatearray()`.
+All those functions solve the problem that a possible reallocation might fail,
+leading to a quite common programming mistake:
+
+```C
+// common mistake - mem will be lost hen realloc() returns NULL
+mem = realloc(mem, capacity + 32);
+if (mem == NULL) // ... do error handling
+```
+
+The above code can be replaced with `cx_reallocate()` which keeps the pointer intact and returns an error code instead.
+
+```C
+// when cx_reallocate() fails, mem will still point to the old memory
+if (cx_reallocate(&mem, capacity + 32)) // ... do error handling
+```
+
+> Please pay special attention to always use `cxFree()` and the  `cxRealloc()`-family of functions
+> with the **same** allocator that was used to allocate the memory.
+{style="warning"}
+
+## Custom Allocator
 
 If you want to define your own allocator, you need to initialize the `CxAllocator` structure
 with a pointer to an allocator class (containing function pointers for the memory management
-functions) and an optional pointer to an arbitrary memory region that can be used to store
-state information for the allocator. An example is shown below:
+functions) and an optional pointer to custom data. An example is shown below:
 
 ```c
+
 struct my_allocator_state {
-    size_t total;
-    size_t avail;
-    char mem[];
+    // ... some internal state ...
 };
 
 static cx_allocator_class my_allocator_class = {
         my_malloc_impl,
-        my_realloc_impl,   // all these functions are somewhere defined
+        my_realloc_impl, // all these functions are somewhere defined
         my_calloc_impl,
         my_free_impl
 };
 
-CxAllocator create_my_allocator(size_t n) {
+CxAllocator create_my_allocator(void) {
     CxAllocator alloc;
     alloc.cl = &my_allocator_class;
-    alloc.data = calloc(1, sizeof(struct my_allocator_state) + n);
+    struct my_allocator_state *state = malloc(sizeof(*state));
+    // ... initialize state ...
+    alloc.data = state;
     return alloc;
 }
+
+void destroy_my_allocator(CxAllocator *al) {
+    struct my_allocator_state *state = al->state;
+    // ... destroy state --
+    free(state);
+}
 ```
 
-## Undocumented Symbols (TODO)
-
-### cxCalloc
-### cx_default_allocator
-### cxDefaultAllocator
-### cxFree
-### cxMalloc
-### cxRealloc
-### cxReallocArray
-### cx_reallocate_
-### cxReallocate_
-### cx_reallocatearray_
-### cxReallocateArray_
+<seealso>
+<category ref="apidoc">
+<a href="https://ucx.sourceforge.io/api/allocator_8h.html">allocator.h</a>
+</category>
+</seealso>

mercurial