ucx/mempool.c

Sun, 17 Dec 2023 15:33:50 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 17 Dec 2023 15:33:50 +0100
changeset 800
30d484806c2b
parent 775
e5909dff0dbf
child 834
6a466635eace
permissions
-rw-r--r--

fix faulty string to int conversion utilities

Probably it was expected that errno is set to EINVAL when illegal characters are encountered. But this is not standard and does not happen on every system, allowing illegal strings to be parsed as valid integers.

775
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include "cx/mempool.h"
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30 #include "cx/utils.h"
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <string.h>
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33 struct cx_mempool_memory_s {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
34 /** The destructor. */
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
35 cx_destructor_func destructor;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
36 /** The actual memory. */
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
37 char c[];
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
38 };
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40 static void *cx_mempool_malloc(
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 void *p,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42 size_t n
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43 ) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44 struct cx_mempool_s *pool = p;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 if (pool->size >= pool->capacity) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47 size_t newcap = pool->capacity - (pool->capacity % 16) + 16;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 struct cx_mempool_memory_s **newdata = realloc(pool->data, newcap*sizeof(struct cx_mempool_memory_s*));
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 if (newdata == NULL) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50 return NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 pool->data = newdata;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 pool->capacity = newcap;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 struct cx_mempool_memory_s *mem = malloc(sizeof(cx_destructor_func) + n);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57 if (mem == NULL) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58 return NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 mem->destructor = pool->auto_destr;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 pool->data[pool->size] = mem;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 pool->size++;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65 return mem->c;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 static void *cx_mempool_calloc(
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69 void *p,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 size_t nelem,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 size_t elsize
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
72 ) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
73 size_t msz;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
74 if (cx_szmul(nelem, elsize, &msz)) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 return NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 void *ptr = cx_mempool_malloc(p, msz);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 if (ptr == NULL) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 return NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81 memset(ptr, 0, nelem * elsize);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 return ptr;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 static void *cx_mempool_realloc(
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 void *p,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 void *ptr,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88 size_t n
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 ) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 struct cx_mempool_s *pool = p;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 struct cx_mempool_memory_s *mem, *newm;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 mem = (struct cx_mempool_memory_s*)(((char *) ptr) - sizeof(cx_destructor_func));
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94 newm = realloc(mem, n + sizeof(cx_destructor_func));
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 if (newm == NULL) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 return NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 if (mem != newm) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 cx_for_n(i, pool->size) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 if (pool->data[i] == mem) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 pool->data[i] = newm;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 return ((char*)newm) + sizeof(cx_destructor_func);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 abort();
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 } else {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 return ptr;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 static void cx_mempool_free(
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 void *p,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 void *ptr
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 ) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 struct cx_mempool_s *pool = p;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 struct cx_mempool_memory_s *mem = (struct cx_mempool_memory_s *)
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119 ((char *) ptr - sizeof(cx_destructor_func));
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 cx_for_n(i, pool->size) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 if (mem == pool->data[i]) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 if (mem->destructor) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 mem->destructor(mem->c);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 free(mem);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 size_t last_index = pool->size - 1;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 if (i != last_index) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 pool->data[i] = pool->data[last_index];
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 pool->data[last_index] = NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 pool->size--;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 return;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
136 abort();
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
138
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139 void cxMempoolDestroy(CxMempool *pool) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140 struct cx_mempool_memory_s *mem;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141 cx_for_n(i, pool->size) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
142 mem = pool->data[i];
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
143 if (mem->destructor) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144 mem->destructor(mem->c);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
145 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 free(mem);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 free(pool->data);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 free((void*) pool->allocator);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 free(pool);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153 void cxMempoolSetDestructor(
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 void *ptr,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 cx_destructor_func func
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 ) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 *(cx_destructor_func *) ((char *) ptr - sizeof(cx_destructor_func)) = func;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 struct cx_mempool_foreign_mem_s {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161 cx_destructor_func destr;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162 void* mem;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 };
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 static void cx_mempool_destr_foreign_mem(void* ptr) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 struct cx_mempool_foreign_mem_s *fm = ptr;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 fm->destr(fm->mem);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170 int cxMempoolRegister(
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 CxMempool *pool,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 void *memory,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 cx_destructor_func destr
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 ) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 struct cx_mempool_foreign_mem_s *fm = cx_mempool_malloc(
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 pool,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 sizeof(struct cx_mempool_foreign_mem_s)
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 );
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 if (fm == NULL) return 1;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 fm->mem = memory;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 fm->destr = destr;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 *(cx_destructor_func *) ((char *) fm - sizeof(cx_destructor_func)) = cx_mempool_destr_foreign_mem;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185 return 0;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 static cx_allocator_class cx_mempool_allocator_class = {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189 cx_mempool_malloc,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 cx_mempool_realloc,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 cx_mempool_calloc,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192 cx_mempool_free
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 };
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 CxMempool *cxMempoolCreate(
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
196 size_t capacity,
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 cx_destructor_func destr
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 ) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199 size_t poolsize;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 if (cx_szmul(capacity, sizeof(struct cx_mempool_memory_s*), &poolsize)) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201 return NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 struct cx_mempool_s *pool =
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205 malloc(sizeof(struct cx_mempool_s));
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206 if (pool == NULL) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 return NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
209
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
210 CxAllocator *provided_allocator = malloc(sizeof(CxAllocator));
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 if (provided_allocator == NULL) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212 free(pool);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 return NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 provided_allocator->cl = &cx_mempool_allocator_class;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 provided_allocator->data = pool;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 pool->allocator = provided_allocator;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 pool->data = malloc(poolsize);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 if (pool->data == NULL) {
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 free(provided_allocator);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 free(pool);
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 return NULL;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 }
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 pool->size = 0;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 pool->capacity = capacity;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 pool->auto_destr = destr;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
231 return (CxMempool *) pool;
e5909dff0dbf update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232 }

mercurial