This source file includes following definitions.
- mca_allocator_basic_component_open
- mca_allocator_basic_component_close
- mca_allocator_basic_component_init
- mca_allocator_basic_combine_prev
- mca_allocator_basic_combine_next
- mca_allocator_basic_alloc
- mca_allocator_basic_realloc
- mca_allocator_basic_free
- mca_allocator_basic_compact
- mca_allocator_basic_finalize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include "opal_config.h"
26 #include "allocator_basic.h"
27 #include "opal/constants.h"
28
29
30
31 mca_allocator_base_component_t mca_allocator_basic_component = {
32
33
34
35
36 {
37 MCA_ALLOCATOR_BASE_VERSION_2_0_0,
38
39 "basic",
40 OPAL_MAJOR_VERSION,
41 OPAL_MINOR_VERSION,
42 OPAL_RELEASE_VERSION,
43 mca_allocator_basic_component_open,
44 mca_allocator_basic_component_close
45 },
46 {
47
48 MCA_BASE_METADATA_PARAM_CHECKPOINT
49 },
50 mca_allocator_basic_component_init
51 };
52
53
54 OBJ_CLASS_INSTANCE(
55 mca_allocator_basic_segment_t,
56 opal_free_list_item_t,
57 NULL,
58 NULL);
59
60
61 int mca_allocator_basic_component_open(void)
62 {
63 return OPAL_SUCCESS;
64 }
65
66
67 int mca_allocator_basic_component_close(void)
68 {
69 return OPAL_SUCCESS;
70 }
71
72
73
74
75
76
77 mca_allocator_base_module_t* mca_allocator_basic_component_init(
78 bool enable_mpi_threads,
79 mca_allocator_base_component_segment_alloc_fn_t segment_alloc,
80 mca_allocator_base_component_segment_free_fn_t segment_free,
81 void *context)
82 {
83 mca_allocator_basic_module_t *module = (mca_allocator_basic_module_t *)
84 malloc(sizeof(mca_allocator_basic_module_t));
85 if (NULL == module) {
86 return NULL;
87 }
88
89 module->super.alc_alloc = mca_allocator_basic_alloc;
90 module->super.alc_realloc = mca_allocator_basic_realloc;
91 module->super.alc_free = mca_allocator_basic_free;
92 module->super.alc_compact = mca_allocator_basic_compact;
93 module->super.alc_finalize = mca_allocator_basic_finalize;
94 module->super.alc_context = context;
95 module->seg_alloc = segment_alloc;
96 module->seg_free = segment_free;
97 OBJ_CONSTRUCT(&module->seg_list, opal_list_t);
98 OBJ_CONSTRUCT(&module->seg_lock, opal_mutex_t);
99 OBJ_CONSTRUCT(&module->seg_descriptors, opal_free_list_t);
100
101 opal_free_list_init (&module->seg_descriptors,
102 sizeof(mca_allocator_basic_segment_t),
103 opal_cache_line_size,
104 OBJ_CLASS(mca_allocator_basic_segment_t),
105 0,opal_cache_line_size,
106 0,
107 -1,
108 16,
109 NULL, 0, NULL, NULL, NULL);
110
111 return &module->super;
112 }
113
114
115
116
117
118 static void mca_allocator_basic_combine_prev(
119 mca_allocator_basic_module_t* module,
120 mca_allocator_basic_segment_t* seg)
121 {
122 opal_list_item_t* item = opal_list_get_prev(seg);
123 if(item != opal_list_get_begin(&module->seg_list)) {
124 mca_allocator_basic_segment_t *prev = (mca_allocator_basic_segment_t*)item;
125 if(prev->seg_addr + prev->seg_size == seg->seg_addr) {
126 prev->seg_size += seg->seg_size;
127 opal_list_remove_item(&module->seg_list, &seg->seg_item.super);
128 opal_free_list_return (&module->seg_descriptors, &seg->seg_item);
129 return;
130 }
131 }
132 }
133
134 static void mca_allocator_basic_combine_next(
135 mca_allocator_basic_module_t* module,
136 mca_allocator_basic_segment_t* seg)
137 {
138 opal_list_item_t *item = opal_list_get_next(seg);
139 if(item != opal_list_get_end(&module->seg_list)) {
140 mca_allocator_basic_segment_t *next = (mca_allocator_basic_segment_t*)item;
141 if(seg->seg_addr + seg->seg_size == next->seg_addr) {
142 next->seg_addr = seg->seg_addr;
143 next->seg_size += seg->seg_size;
144 opal_list_remove_item(&module->seg_list, &seg->seg_item.super);
145 opal_free_list_return (&module->seg_descriptors, &seg->seg_item);
146 return;
147 }
148 }
149 }
150
151
152
153
154
155
156
157
158
159
160
161
162
163 void *mca_allocator_basic_alloc(
164 mca_allocator_base_module_t * base,
165 size_t size,
166 size_t align)
167 {
168 mca_allocator_basic_module_t* module = (mca_allocator_basic_module_t*)base;
169 mca_allocator_basic_segment_t* seg;
170 unsigned char* addr;
171 size_t allocated_size;
172 OPAL_THREAD_LOCK(&module->seg_lock);
173
174
175 size += sizeof(size_t);
176
177 size += sizeof(size_t) - (size & (sizeof(size_t) - 1));
178
179 OPAL_LIST_FOREACH(seg, &module->seg_list, mca_allocator_basic_segment_t) {
180
181 if(seg->seg_size > size) {
182 addr = seg->seg_addr;
183 seg->seg_addr += size;
184 seg->seg_size -= size;
185 OPAL_THREAD_UNLOCK(&module->seg_lock);
186 *(size_t*)addr = size;
187 return addr+sizeof(size_t);
188 } else if (seg->seg_size == size) {
189 addr = seg->seg_addr;
190 opal_list_remove_item(&module->seg_list, (opal_list_item_t *) seg);
191 opal_free_list_return (&module->seg_descriptors, (opal_free_list_item_t *) seg);
192 OPAL_THREAD_UNLOCK(&module->seg_lock);
193 *(size_t*)addr = size;
194 return addr+sizeof(size_t);
195 }
196 }
197
198
199 allocated_size = size;
200 if(NULL == (addr = (unsigned char *)module->seg_alloc(module->super.alc_context, &allocated_size))) {
201 OPAL_THREAD_UNLOCK(&module->seg_lock);
202 return NULL;
203 }
204
205
206 if(allocated_size > size) {
207 seg = (mca_allocator_basic_segment_t *) opal_free_list_get (&module->seg_descriptors);
208 if (NULL == seg) {
209 OPAL_THREAD_UNLOCK(&module->seg_lock);
210 return NULL;
211 }
212 seg->seg_addr = addr + size;
213 seg->seg_size = allocated_size - size;
214 opal_list_append (&module->seg_list, (opal_list_item_t *) seg);
215 }
216
217 *(size_t*)addr = size;
218 OPAL_THREAD_UNLOCK(&module->seg_lock);
219 return addr+sizeof(size_t);
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238 void * mca_allocator_basic_realloc(
239 mca_allocator_base_module_t * base,
240 void * ptr,
241 size_t size)
242 {
243 unsigned char* addr = ((unsigned char*)ptr) - sizeof(size_t);
244 size_t alloc_size = *(size_t*)addr;
245 if(size <= alloc_size)
246 return ptr;
247 addr = (unsigned char *)mca_allocator_basic_alloc(base, size, 0);
248 if(addr == NULL)
249 return addr;
250 memcpy(addr,ptr,alloc_size);
251 mca_allocator_basic_free(base,ptr);
252 return addr;
253 }
254
255
256
257
258
259
260
261
262
263
264
265
266 void mca_allocator_basic_free(
267 mca_allocator_base_module_t * base,
268 void * ptr)
269 {
270 mca_allocator_basic_module_t* module = (mca_allocator_basic_module_t*)base;
271 mca_allocator_basic_segment_t* seg;
272 unsigned char* addr = (unsigned char*)ptr - sizeof(size_t);
273 size_t size = *(size_t*)addr;
274 OPAL_THREAD_LOCK(&module->seg_lock);
275
276
277 OPAL_LIST_FOREACH(seg, &module->seg_list, mca_allocator_basic_segment_t) {
278 if (seg->seg_addr < addr) {
279
280
281 if(seg->seg_addr + seg->seg_size == addr) {
282 seg->seg_size += size;
283 mca_allocator_basic_combine_next(module, seg);
284 OPAL_THREAD_UNLOCK(&module->seg_lock);
285 return;
286 }
287
288
289 } else {
290
291
292 if(addr + size == seg->seg_addr) {
293 seg->seg_addr = addr;
294 seg->seg_size += size;
295 mca_allocator_basic_combine_prev(module, seg);
296 OPAL_THREAD_UNLOCK(&module->seg_lock);
297 return;
298
299
300 } else {
301 mca_allocator_basic_segment_t* new_seg;
302 new_seg = (mca_allocator_basic_segment_t *)
303 opal_free_list_get (&module->seg_descriptors);
304 if(NULL == new_seg) {
305 OPAL_THREAD_UNLOCK(&module->seg_lock);
306 return;
307 }
308 new_seg->seg_addr = addr;
309 new_seg->seg_size = size;
310 opal_list_insert_pos(&module->seg_list, &seg->seg_item.super, (opal_list_item_t *) new_seg);
311 OPAL_THREAD_UNLOCK(&module->seg_lock);
312 return;
313 }
314 }
315 }
316
317
318 seg = (mca_allocator_basic_segment_t *) opal_free_list_get (&module->seg_descriptors);
319 if(NULL == seg) {
320 OPAL_THREAD_UNLOCK(&module->seg_lock);
321 return;
322 }
323 seg->seg_addr = addr;
324 seg->seg_size = size;
325 opal_list_append(&module->seg_list, (opal_list_item_t *) seg);
326 OPAL_THREAD_UNLOCK(&module->seg_lock);
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342 int mca_allocator_basic_compact(mca_allocator_base_module_t * mem)
343 {
344 return OPAL_SUCCESS;
345 }
346
347
348
349
350
351
352
353
354
355
356
357 int mca_allocator_basic_finalize(mca_allocator_base_module_t * base)
358 {
359 mca_allocator_basic_module_t* module = (mca_allocator_basic_module_t*)base;
360
361 while (NULL != opal_list_remove_first(&module->seg_list)) {
362 continue;
363 }
364 OBJ_DESTRUCT(&module->seg_list);
365 OBJ_DESTRUCT(&module->seg_lock);
366 OBJ_DESTRUCT(&module->seg_descriptors);
367 free(module);
368 return OPAL_SUCCESS;
369 }
370
371