1 /* |
1 /* |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 * |
3 * |
4 * Copyright 2016 Olaf Wintermann. All rights reserved. |
4 * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. |
5 * |
5 * |
6 * Redistribution and use in source and binary forms, with or without |
6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions are met: |
7 * modification, are permitted provided that the following conditions are met: |
8 * |
8 * |
9 * 1. Redistributions of source code must retain the above copyright |
9 * 1. Redistributions of source code must retain the above copyright |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 */ |
27 */ |
28 |
28 |
|
29 #include "ucx/mempool.h" |
|
30 |
29 #include <stdlib.h> |
31 #include <stdlib.h> |
30 #include <string.h> |
32 #include <string.h> |
31 #include <stdio.h> |
33 #include <stdio.h> |
32 #ifdef __cplusplus |
34 #ifdef __cplusplus |
33 #define __STDC_FORMAT_MACROS |
35 #define __STDC_FORMAT_MACROS |
34 #endif |
36 #endif |
35 #include <inttypes.h> |
37 #include <inttypes.h> |
36 |
|
37 #include "mempool.h" |
|
38 |
38 |
39 /** Capsule for destructible memory chunks. */ |
39 /** Capsule for destructible memory chunks. */ |
40 typedef struct { |
40 typedef struct { |
41 /** The destructor for the memory chunk. */ |
41 /** The destructor for the memory chunk. */ |
42 ucx_destructor destructor; |
42 ucx_destructor destructor; |
54 ucx_destructor destructor; |
54 ucx_destructor destructor; |
55 /** A pointer to the data. */ |
55 /** A pointer to the data. */ |
56 void *ptr; |
56 void *ptr; |
57 } ucx_regdestr; |
57 } ucx_regdestr; |
58 |
58 |
59 UCX_EXTERN void ucx_mempool_shared_destr(void* ptr) { |
59 #ifdef __cplusplus |
|
60 extern "C" |
|
61 #endif |
|
62 void ucx_mempool_shared_destr(void* ptr) { |
60 ucx_regdestr *rd = (ucx_regdestr*)ptr; |
63 ucx_regdestr *rd = (ucx_regdestr*)ptr; |
61 rd->destructor(rd->ptr); |
64 rd->destructor(rd->ptr); |
62 } |
65 } |
63 |
66 |
64 UcxMempool *ucx_mempool_new(size_t n) { |
67 UcxMempool *ucx_mempool_new(size_t n) { |
|
68 size_t poolsz; |
|
69 if(ucx_szmul(n, sizeof(void*), &poolsz)) { |
|
70 return NULL; |
|
71 } |
|
72 |
65 UcxMempool *pool = (UcxMempool*)malloc(sizeof(UcxMempool)); |
73 UcxMempool *pool = (UcxMempool*)malloc(sizeof(UcxMempool)); |
66 if (!pool) { |
74 if (!pool) { |
67 return NULL; |
75 return NULL; |
68 } |
76 } |
69 |
77 |
70 pool->data = (void**) malloc(n * sizeof(void*)); |
78 pool->data = (void**) malloc(poolsz); |
71 if (pool->data == NULL) { |
79 if (pool->data == NULL) { |
72 free(pool); |
80 free(pool); |
73 return NULL; |
81 return NULL; |
74 } |
82 } |
75 |
83 |
95 int ucx_mempool_chcap(UcxMempool *pool, size_t newcap) { |
103 int ucx_mempool_chcap(UcxMempool *pool, size_t newcap) { |
96 if (newcap < pool->ndata) { |
104 if (newcap < pool->ndata) { |
97 return 1; |
105 return 1; |
98 } |
106 } |
99 |
107 |
100 void **data = (void**) realloc(pool->data, newcap*sizeof(void*)); |
108 size_t newcapsz; |
|
109 if(ucx_szmul(newcap, sizeof(void*), &newcapsz)) { |
|
110 return 1; |
|
111 } |
|
112 |
|
113 void **data = (void**) realloc(pool->data, newcapsz); |
101 if (data) { |
114 if (data) { |
102 pool->data = data; |
115 pool->data = data; |
103 pool->size = newcap; |
116 pool->size = newcap; |
104 return 0; |
117 return 0; |
105 } else { |
118 } else { |
106 return 1; |
119 return 1; |
107 } |
120 } |
108 } |
121 } |
109 |
122 |
110 void *ucx_mempool_malloc(UcxMempool *pool, size_t n) { |
123 void *ucx_mempool_malloc(UcxMempool *pool, size_t n) { |
|
124 if(((size_t)-1) - sizeof(ucx_destructor) < n) { |
|
125 return NULL; |
|
126 } |
|
127 |
111 if (pool->ndata >= pool->size) { |
128 if (pool->ndata >= pool->size) { |
112 size_t newcap = pool->size*2; |
129 size_t newcap = pool->size*2; |
113 if (newcap < pool->size || ucx_mempool_chcap(pool, newcap)) { |
130 if (newcap < pool->size || ucx_mempool_chcap(pool, newcap)) { |
114 return NULL; |
131 return NULL; |
115 } |
132 } |
127 |
144 |
128 return &(mem->c); |
145 return &(mem->c); |
129 } |
146 } |
130 |
147 |
131 void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize) { |
148 void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize) { |
132 void *ptr = ucx_mempool_malloc(pool, nelem*elsize); |
149 size_t msz; |
|
150 if(ucx_szmul(nelem, elsize, &msz)) { |
|
151 return NULL; |
|
152 } |
|
153 |
|
154 void *ptr = ucx_mempool_malloc(pool, msz); |
133 if (!ptr) { |
155 if (!ptr) { |
134 return NULL; |
156 return NULL; |
135 } |
157 } |
136 memset(ptr, 0, nelem * elsize); |
158 memset(ptr, 0, nelem * elsize); |
137 return ptr; |
159 return ptr; |
138 } |
160 } |
139 |
161 |
140 void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n) { |
162 void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n) { |
|
163 if(((size_t)-1) - sizeof(ucx_destructor) < n) { |
|
164 return NULL; |
|
165 } |
|
166 |
141 char *mem = ((char*)ptr) - sizeof(ucx_destructor); |
167 char *mem = ((char*)ptr) - sizeof(ucx_destructor); |
142 char *newm = (char*) realloc(mem, n + sizeof(ucx_destructor)); |
168 char *newm = (char*) realloc(mem, n + sizeof(ucx_destructor)); |
143 if (!newm) { |
169 if (!newm) { |
144 return NULL; |
170 return NULL; |
145 } |
171 } |