docs/Writerside/topics/mempool.h.md

branch
docs/3.1
changeset 1168
d92124c8db73
parent 1146
151c057faf7c
equal deleted inserted replaced
1167:feab7c1e80d4 1168:d92124c8db73
1 # Memory Pool 1 # Memory Pool
2
3 <warning>
4 Outdated - Rewrite!
5 </warning>
6 2
7 A memory pool is providing an allocator implementation that automatically deallocates the memory upon its destruction. 3 A memory pool is providing an allocator implementation that automatically deallocates the memory upon its destruction.
8 It also allows you to register destructor functions for the allocated memory, which are automatically called before 4 It also allows you to register destructor functions for the allocated memory, which are automatically called before
9 the memory is deallocated. 5 the memory is deallocated.
10 Additionally, you may also register _independent_ destructor functions within a pool in case some external library
11 allocated memory for you, which should be freed together with this pool.
12 6
13 Many UCX features support the use of an allocator. 7 Additionally, you may also register _independent_ destructor functions.
14 The [strings](string.h.md), for instance, provide several functions suffixed with `_a` that allow specifying an allocator. 8 This can be useful, for example, when some library allocates memory that you wish to destroy when the memory pool gets destroyed.
15 You can use this to keep track of the memory occupied by dynamically allocated strings and cleanup everything with
16 just a single call to `cxMempoolFree()`.
17 9
18 The following code illustrates this on the example of reading a CSV file into memory. 10 A memory pool can be used with all UCX features that support the use of an [allocator](allocator.h.md).
11 For example, the UCX [string](string.h.md) functions provide several variants suffixed with `_a` for that purpose.
12
13 ## Overview
14
15 ```C
16 CxMempool *cxMempoolCreate(size_t capacity, cx_destructor_func fnc);
17
18 CxMempool *cxMempoolCreateSimple(size_t capacity);
19
20 void cxMempoolFree(CxMempool *pool);
21
22 void cxMempoolSetDestructor(void *memory, cx_destructor_func fnc);
23
24 void cxMempoolRemoveDestructor(void *memory);
25
26 int cxMempoolRegister(CxMempool *pool, void *memory,
27 cx_destructor_func fnc);
28 ```
29
30 ## Description
31
32 A memory pool is created with the `cxMempoolCreate()` function with a default `capacity`
33 and an optional default destructor function `fnc`.
34 If specified, the default destructor function is registered for all freshly allocated memory within the pool,
35 as if `cxMempoolSetDestructor()` was called immediately after allocation.
36 When you set `fnc` is to `NULL` during pool creation, or use `cxMempoolCreateSimple`, no default destructor is registered.
37
38 After creating a memory pool `CxMempool *mpool`, you can access the provided allocator via `mpool->allocator`.
39
40 The functions `cxMempoolSetDestructor()` and `cxMempoolRemoveDestructor()` can be used to assign a specific destructor
41 function to an allocated object or remove any assigned destructor function, respectively.
42 The `memory` pointer points to the allocated object, which must have been allocated by any `CxMempool`'s provided allocator.
43
44 The `cxMempoolRegister()` function allocates a new wrapper object for `memory` with `pool`'s allocator that
45 will call the specified destructor function when destroyed.
46 Usually this function returns zero except for platforms where memory allocations are likely to fail,
47 in which case a non-zero value is returned.
48
49 ## Order of Destruction
50
51 When you call `cxMempoolFree()` the following actions are performed:
52
53 1. In any order, for each object in the pool
54 1. the destructor function assigned to that object is called
55 2. the object's memory is deallocated
56 2. The pool memory is deallocated
57 3. The pool structure is deallocated
58
59 ## Example
60
61 The following code illustrates how the contents of a CSV file are read into pooled memory.
19 ```C 62 ```C
20 #include <stdio.h> 63 #include <stdio.h>
21 #include <cx/mempool.h> 64 #include <cx/mempool.h>
22 #include <cx/linked_list.h> 65 #include <cx/linked_list.h>
23 #include <cx/string.h> 66 #include <cx/string.h>
29 cxstring column_b; 72 cxstring column_b;
30 cxstring column_c; 73 cxstring column_c;
31 } CSVData; 74 } CSVData;
32 75
33 int main(void) { 76 int main(void) {
34 CxMempool* pool = cxBasicMempoolCreate(128); 77 // create a simple pool for various different objects
78 CxMempool* pool = cxMempoolCreateSimple(128);
35 79
36 FILE *f = fopen("test.csv", "r"); 80 FILE *f = fopen("test.csv", "r");
37 if (!f) { 81 if (f == NULL) {
38 perror("Cannot open file"); 82 perror("Cannot open file");
39 return 1; 83 return 1;
40 } 84 }
41 // close the file automatically at pool destruction 85 // close the file automatically at pool destruction
42 cxMempoolRegister(pool, f, (cx_destructor_func) fclose); 86 cxMempoolRegister(pool, f, (cx_destructor_func) fclose);
43 87
44 // create a buffer using the memory pool for destruction 88 // create a buffer using the memory pool for destruction
45 CxBuffer *content = cxBufferCreate(NULL, 256, pool->allocator, CX_BUFFER_AUTO_EXTEND); 89 CxBuffer *content = cxBufferCreate(
90 NULL, 256, pool->allocator, CX_BUFFER_AUTO_EXTEND
91 );
46 92
47 // read the file into the buffer and turn it into a string 93 // read the file into the buffer and turn it into a string
48 cx_stream_copy(f, content, (cx_read_func) fread, cxBufferWriteFunc); 94 cx_stream_copy(
95 f, content, (cx_read_func) fread, cxBufferWriteFunc
96 );
49 fclose(f); 97 fclose(f);
50 cxstring contentstr = cx_strn(content->space, content->size); 98 cxstring contentstr = cx_strn(content->space, content->size);
51 99
52 // split the string into lines - use the mempool for allocating the target array 100 // split the string into lines
101 // use the memory pool to allocate the target array
53 cxstring* lines; 102 cxstring* lines;
54 size_t lc = cx_strsplit_a(pool->allocator, contentstr, 103 size_t lc = cx_strsplit_a(
55 CX_STR("\n"), SIZE_MAX, &lines); 104 pool->allocator, contentstr, cx_str("\n"), SIZE_MAX, &lines
105 );
56 106
57 // skip the header and parse the remaining data into a linked list 107 // skip the header and parse the remaining data into a linked list
58 // the nodes of the linked list shall also be allocated by the mempool 108 // the nodes of the list shall also be allocated by the pool
59 CxList* datalist = cxLinkedListCreate(pool->allocator, NULL, sizeof(CSVData)); 109 CxList* datalist = cxLinkedListCreate(
110 pool->allocator, NULL, sizeof(CSVData)
111 );
60 for (size_t i = 1 ; i < lc ; i++) { 112 for (size_t i = 1 ; i < lc ; i++) {
61 if (lines[i].length == 0) continue; 113 if (lines[i].length == 0) continue;
62 cxstring fields[3]; 114 cxstring fields[3];
63 size_t fc = cx_strsplit(lines[i], CX_STR(";"), 3, fields); 115 size_t fc = cx_strsplit(lines[i], cx_str(";"), 3, fields);
64 if (fc != 3) { 116 if (fc != 3) {
65 fprintf(stderr, "Syntax error in line %zu.\n", i); 117 fprintf(stderr, "Syntax error in line %zu.\n", i);
66 cxMempoolFree(pool); 118 cxMempoolFree(pool);
67 return 1; 119 return 1;
68 } 120 }
90 142
91 return 0; 143 return 0;
92 } 144 }
93 ``` 145 ```
94 146
95 ## Undocumented Symbols (TODO) 147 <seealso>
96 ### cxMempoolCreate 148 <category ref="apidoc">
97 ### cxMempoolFree 149 <a href="https://ucx.sourceforge.io/api/mempool_8h.html">mempool.h</a>
98 ### cxMempoolRegister 150 </category>
99 ### cxMempoolRemoveDestructor 151 </seealso>
100 ### cxMempoolSetDestructor

mercurial