aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/tests/evas_mempool.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/tests/evas_mempool.c')
-rw-r--r--libraries/eina/src/tests/evas_mempool.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/libraries/eina/src/tests/evas_mempool.c b/libraries/eina/src/tests/evas_mempool.c
new file mode 100644
index 0000000..fbc48fa
--- /dev/null
+++ b/libraries/eina/src/tests/evas_mempool.c
@@ -0,0 +1,200 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <stdlib.h>
6#include <string.h>
7
8#include "Evas_Data.h"
9#include "evas_mempool.h"
10
11//#define NOPOOL
12
13typedef struct _Pool Pool;
14
15struct _Pool
16{
17 int usage;
18 void *base;
19 Pool *prev, *next;
20};
21
22
23Pool *
24_evas_mp_pool_new(Evas_Mempool *pool)
25{
26#ifdef NOPOOL
27 static Pool thepool;
28 return &thepool;
29#else
30 Pool *p;
31 void **ptr;
32 int item_alloc, i;
33
34 item_alloc =
35 ((pool->item_size + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *);
36 p = malloc(sizeof(Pool) + (pool->pool_size * item_alloc));
37 ptr = (void **)(((unsigned char *)p) + sizeof(Pool));
38 p->usage = 0;
39 p->base = ptr;
40 for (i = 0; i < pool->pool_size - 1; i++)
41 {
42 *ptr = (void **)(((unsigned char *)ptr) + item_alloc);
43 ptr = *ptr;
44 }
45 *ptr = NULL;
46 return p;
47#endif
48}
49
50void
51_evas_mp_pool_free(Pool *p)
52{
53#if !defined(NOPOOL)
54 free(p);
55#endif
56}
57
58void *
59evas_mempool_malloc(Evas_Mempool *pool, int size)
60{
61#ifdef NOPOOL
62 return malloc(size);
63#else
64 Pool *p;
65 void *mem;
66
67 for (p = pool->first; p; p = p->next) // look 4 pool from 2nd bucket on
68 {
69 if (p->base) // base is not NULL - has a free slot
70 {
71 if (p->prev)
72 {
73 if (pool->last == p)
74 pool->last = p->prev;
75
76 p->prev->next = p->next;
77 p->prev = NULL;
78 p->next = pool->first;
79 p->next->prev = p;
80 pool->first = p;
81 }
82
83 break;
84 }
85 }
86 if (!p) // we have reached the end of the list - no free pools
87 {
88 p = _evas_mp_pool_new(pool);
89 if (!p)
90 return NULL;
91
92 p->prev = NULL;
93 p->next = pool->first;
94 if (p->next)
95 p->next->prev = p;
96
97 if (!pool->last)
98 pool->last = p;
99
100 pool->first = p;
101 }
102
103 mem = p->base; // this points to the next free block - so take it
104 p->base = *((void **)mem); // base now points to the next free block
105 if (!p->base) // move to end - it just filled up
106 if (p->next)
107 {
108 if (p->prev)
109 p->prev->next = p->next;
110 else
111 pool->first = p->next;
112
113 p->next->prev = p->prev;
114 ((Pool *)pool->last)->next = p;
115 p->prev = pool->last;
116 p->next = NULL;
117 pool->last = p;
118 }
119
120 p->usage++;
121 pool->usage++;
122 return mem;
123#endif
124}
125
126void
127evas_mempool_free(Evas_Mempool *pool, void *ptr)
128{
129#ifdef NOPOOL
130 free(ptr);
131#else
132 Pool *p;
133 void *pmem;
134 int item_alloc, psize;
135
136 item_alloc =
137 ((pool->item_size + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *);
138 psize = item_alloc * pool->pool_size;
139 for (p = (Pool *)(pool->first); p; p = p->next) // look 4 pool
140 {
141 pmem = (void *)(((unsigned char *)p) + sizeof(Pool)); // pool mem base
142 if ((ptr >= pmem) &&
143 ((unsigned char *)ptr < (((unsigned char *)pmem) + psize))) // is it in pool mem?
144 {
145 *((void **)ptr) = p->base; // freed node points to prev free node
146 p->base = ptr; // next free node is now the one we freed
147 p->usage--;
148 pool->usage--;
149 if (p->usage == 0) // free bucket
150 {
151 if (p->prev)
152 p->prev->next = p->next;
153
154 if (p->next)
155 p->next->prev = p->prev;
156
157 if (pool->last == p)
158 pool->last = p->prev;
159
160 if (pool->first == p)
161 pool->first = p->next;
162
163 _evas_mp_pool_free(p);
164 }
165 else if (p->prev) // if not the first - move to front
166 {
167 p->prev->next = p->next;
168 if (p->next)
169 p->next->prev = p->prev;
170
171 if (pool->last == p)
172 pool->last = p->prev;
173
174 p->prev = NULL;
175 p->next = pool->first;
176 p->next->prev = p;
177 pool->first = p;
178 }
179
180 break;
181 }
182 }
183#endif
184}
185
186
187void *
188evas_mempool_calloc(Evas_Mempool *pool, int size)
189{
190#ifdef NOPOOL
191 return calloc(1, size);
192#else
193 void *mem;
194
195 mem = evas_mempool_malloc(pool, size);
196 memset(mem, 0, size);
197 return mem;
198#endif
199}
200