efl

Форк
0
/
evas_mempool.c 
206 строк · 4.5 Кб
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
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
12
# define UNUSED __attribute__ ((__unused__))
13
#else
14
# define UNUSED
15
#endif
16

17
//#define NOPOOL
18

19
typedef struct _Pool Pool;
20

21
struct _Pool
22
{
23
   int usage;
24
   void *base;
25
   Pool *prev, *next;
26
};
27

28

29
Pool *
30
_evas_mp_pool_new(Evas_Mempool *pool)
31
{
32
#ifdef NOPOOL
33
   static Pool thepool;
34
   return &thepool;
35
#else
36
   Pool *p;
37
   void **ptr;
38
   int item_alloc, i;
39

40
   item_alloc =
41
      ((pool->item_size + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *);
42
   p = malloc(sizeof(Pool) + (pool->pool_size * item_alloc));
43
   if (!p) return NULL;
44
   ptr = (void **)(((unsigned char *)p) + sizeof(Pool));
45
   p->usage = 0;
46
   p->base = ptr;
47
   for (i = 0; i < pool->pool_size - 1; i++)
48
     {
49
        *ptr = (void **)(((unsigned char *)ptr) + item_alloc);
50
        ptr = *ptr;
51
     }
52
   *ptr = NULL;
53
   return p;
54
#endif
55
}
56

57
void
58
_evas_mp_pool_free(Pool *p)
59
{
60
#if !defined(NOPOOL)
61
   free(p);
62
#endif
63
}
64

65
void *
66
evas_mempool_malloc(Evas_Mempool *pool, int size UNUSED)
67
{
68
#ifdef NOPOOL
69
   return malloc(size);
70
#else
71
   Pool *p;
72
   void *mem;
73

74
   for (p = pool->first; p; p = p->next) // look 4 pool from 2nd bucket on
75
     {
76
        if (p->base) // base is not NULL - has a free slot
77
          {
78
             if (p->prev)
79
               {
80
                  if (pool->last == p)
81
                     pool->last = p->prev;
82

83
                  p->prev->next = p->next;
84
                  p->prev = NULL;
85
                  p->next = pool->first;
86
                  p->next->prev = p;
87
                  pool->first = p;
88
               }
89

90
             break;
91
          }
92
     }
93
   if (!p) // we have reached the end of the list - no free pools
94
     {
95
        p = _evas_mp_pool_new(pool);
96
        if (!p)
97
           return NULL;
98

99
        p->prev = NULL;
100
        p->next = pool->first;
101
        if (p->next)
102
           p->next->prev = p;
103

104
        if (!pool->last)
105
           pool->last = p;
106

107
        pool->first = p;
108
     }
109

110
   mem = p->base; // this points to the next free block - so take it
111
   p->base = *((void **)mem); // base now points to the next free block
112
   if (!p->base) // move to end - it just filled up
113
      if (p->next)
114
        {
115
           if (p->prev)
116
              p->prev->next = p->next;
117
           else
118
              pool->first = p->next;
119

120
           p->next->prev = p->prev;
121
           ((Pool *)pool->last)->next = p;
122
           p->prev = pool->last;
123
           p->next = NULL;
124
           pool->last = p;
125
        }
126

127
   p->usage++;
128
   pool->usage++;
129
   return mem;
130
#endif
131
}
132

133
void
134
evas_mempool_free(Evas_Mempool *pool, void *ptr)
135
{
136
#ifdef NOPOOL
137
   free(ptr);
138
#else
139
   Pool *p;
140
   void *pmem;
141
   int item_alloc, psize;
142

143
   item_alloc =
144
      ((pool->item_size + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *);
145
   psize = item_alloc * pool->pool_size;
146
   for (p = (Pool *)(pool->first); p; p = p->next) // look 4 pool
147
     {
148
        pmem = (void *)(((unsigned char *)p) + sizeof(Pool)); // pool mem base
149
        if ((ptr >= pmem) &&
150
            ((unsigned char *)ptr < (((unsigned char *)pmem) + psize))) // is it in pool mem?
151
          {
152
             *((void **)ptr) = p->base; // freed node points to prev free node
153
             p->base = ptr; // next free node is now the one we freed
154
             p->usage--;
155
             pool->usage--;
156
             if (p->usage == 0) // free bucket
157
               {
158
                  if (p->prev)
159
                     p->prev->next = p->next;
160

161
                  if (p->next)
162
                     p->next->prev = p->prev;
163

164
                  if (pool->last == p)
165
                     pool->last = p->prev;
166

167
                  if (pool->first == p)
168
                     pool->first = p->next;
169

170
                  _evas_mp_pool_free(p);
171
               }
172
             else if (p->prev) // if not the first - move to front
173
               {
174
                  p->prev->next = p->next;
175
                  if (p->next)
176
                     p->next->prev = p->prev;
177

178
                  if (pool->last == p)
179
                     pool->last = p->prev;
180

181
                  p->prev = NULL;
182
                  p->next = pool->first;
183
                  p->next->prev = p;
184
                  pool->first = p;
185
               }
186

187
             break;
188
          }
189
     }
190
#endif
191
}
192

193

194
void *
195
evas_mempool_calloc(Evas_Mempool *pool, int size)
196
{
197
#ifdef NOPOOL
198
   return calloc(1, size);
199
#else
200
   void *mem;
201

202
   mem = evas_mempool_malloc(pool, size);
203
   memset(mem, 0, size);
204
   return mem;
205
#endif
206
}
207

208

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.