1 #include "goomsl_heap.h"
2 #include <stdlib.h>
3
4 struct _GOOM_HEAP {
5 void **arrays;
6 int number_of_arrays;
7 int size_of_each_array;
8 int consumed_in_last_array;
9 };
10
11 /* Constructors / Destructor */
goom_heap_new(void)12 GoomHeap *goom_heap_new(void)
13 {
14 return goom_heap_new_with_granularity(4096);
15 }
16
goom_heap_new_with_granularity(int granularity)17 GoomHeap *goom_heap_new_with_granularity(int granularity)
18 {
19 GoomHeap *_this;
20 _this = (GoomHeap*)malloc(sizeof(GoomHeap));
21 _this->number_of_arrays = 0;
22 _this->size_of_each_array = granularity;
23 _this->consumed_in_last_array = 0;
24 _this->arrays = (void**)malloc(sizeof(void*));
25 return _this;
26 }
27
goom_heap_delete(GoomHeap * _this)28 void goom_heap_delete(GoomHeap *_this)
29 {
30 int i;
31 for (i=0;i<_this->number_of_arrays;++i) {
32 free(_this->arrays[i]);
33 }
34 free(_this->arrays);
35 free(_this);
36 }
37
align_it(GoomHeap * _this,int alignment)38 static void align_it(GoomHeap *_this, int alignment)
39 {
40 if ((alignment > 1) && (_this->number_of_arrays>0)) {
41 void *last_array = _this->arrays[_this->number_of_arrays - 1];
42 int last_address = (int)last_array + _this->consumed_in_last_array;
43 int decal = (last_address % alignment);
44 if (decal != 0) {
45 _this->consumed_in_last_array += alignment - decal;
46 }
47 }
48 }
49
goom_heap_malloc_with_alignment_prefixed(GoomHeap * _this,int nb_bytes,int alignment,int prefix_bytes)50 void *goom_heap_malloc_with_alignment_prefixed(GoomHeap *_this, int nb_bytes,
51 int alignment, int prefix_bytes)
52 {
53 void *retval = NULL;
54
55 /* d'abord on gere les problemes d'alignement */
56 _this->consumed_in_last_array += prefix_bytes;
57 align_it(_this, alignment);
58
59 /* ensuite on verifie que la quantite de memoire demandee tient dans le buffer */
60 if ((_this->consumed_in_last_array + nb_bytes >= _this->size_of_each_array)
61 || (_this->number_of_arrays == 0)) {
62
63 if (prefix_bytes + nb_bytes + alignment >= _this->size_of_each_array) {
64
65 /* Si la zone demandee est plus grosse que la granularitee */
66 /* On alloue un buffer plus gros que les autres */
67 _this->arrays = (void**)realloc(_this->arrays, sizeof(void*) * (_this->number_of_arrays+2));
68
69 _this->number_of_arrays += 1;
70 _this->consumed_in_last_array = prefix_bytes;
71
72 _this->arrays[_this->number_of_arrays - 1] = malloc(prefix_bytes + nb_bytes + alignment);
73 align_it(_this,alignment);
74 retval = (void*)((char*)_this->arrays[_this->number_of_arrays - 1] + _this->consumed_in_last_array);
75
76 /* puis on repart sur un nouveau buffer vide */
77 _this->number_of_arrays += 1;
78 _this->consumed_in_last_array = 0;
79 _this->arrays[_this->number_of_arrays - 1] = malloc(_this->size_of_each_array);
80 return retval;
81 }
82 else {
83 _this->number_of_arrays += 1;
84 _this->consumed_in_last_array = prefix_bytes;
85 _this->arrays = (void**)realloc(_this->arrays, sizeof(void*) * _this->number_of_arrays);
86
87 _this->arrays[_this->number_of_arrays - 1] = malloc(_this->size_of_each_array);
88 align_it(_this,alignment);
89 }
90 }
91 retval = (void*)((char*)_this->arrays[_this->number_of_arrays - 1] + _this->consumed_in_last_array);
92 _this->consumed_in_last_array += nb_bytes;
93 return retval;
94 }
95
goom_heap_malloc_with_alignment(GoomHeap * _this,int nb_bytes,int alignment)96 void *goom_heap_malloc_with_alignment(GoomHeap *_this, int nb_bytes, int alignment)
97 {
98 return goom_heap_malloc_with_alignment_prefixed(_this, nb_bytes, alignment, 0);
99 }
100
goom_heap_malloc(GoomHeap * _this,int nb_bytes)101 void *goom_heap_malloc(GoomHeap *_this, int nb_bytes)
102 {
103 return goom_heap_malloc_with_alignment(_this,nb_bytes,1);
104 }
105
106