• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include "libimagequant.h"
3 #include "mempool.h"
4 #include <stdlib.h>
5 #include <stdint.h>
6 #include <assert.h>
7 
8 #define ALIGN_MASK 15UL
9 #define MEMPOOL_RESERVED ((sizeof(struct mempool)+ALIGN_MASK) & ~ALIGN_MASK)
10 
11 struct mempool
12 {
13   unsigned int used, size;
14   void *(*malloc) (size_t);
15   void (*free) (void *);
16   struct mempool *next;
17 };
18 LIQ_PRIVATE void *
mempool_create(mempool * mptr,const unsigned int size,unsigned int max_size,void * (* malloc)(size_t),void (* free)(void *))19 mempool_create (mempool * mptr, const unsigned int size, unsigned int max_size,
20     void *(*malloc) (size_t), void (*free) (void *))
21 {
22   mempool old;
23   uintptr_t mptr_used_start;
24 
25   if (*mptr && ((*mptr)->used + size) <= (*mptr)->size) {
26     unsigned int prevused = (*mptr)->used;
27     (*mptr)->used += (size + 15UL) & ~0xFUL;
28     return ((char *) (*mptr)) + prevused;
29   }
30 
31   old = *mptr;
32   if (!max_size)
33     max_size = (1 << 17);
34   max_size = size + ALIGN_MASK > max_size ? size + ALIGN_MASK : max_size;
35 
36   *mptr = malloc (MEMPOOL_RESERVED + max_size);
37   if (!*mptr)
38     return NULL;
39   **mptr = (struct mempool) {
40   .malloc = malloc,.free = free,.size = MEMPOOL_RESERVED + max_size,.used =
41         sizeof (struct mempool),.next = old,};
42   mptr_used_start = (uintptr_t) (*mptr) + (*mptr)->used;
43   (*mptr)->used += (ALIGN_MASK + 1 - (mptr_used_start & ALIGN_MASK)) & ALIGN_MASK;      // reserve bytes required to make subsequent allocations aligned
44   assert (!(((uintptr_t) (*mptr) + (*mptr)->used) & ALIGN_MASK));
45 
46   return mempool_alloc (mptr, size, size);
47 }
48 
49 LIQ_PRIVATE void *
mempool_alloc(mempool * mptr,unsigned int size,unsigned int max_size)50 mempool_alloc (mempool * mptr, unsigned int size, unsigned int max_size)
51 {
52   if (((*mptr)->used + size) <= (*mptr)->size) {
53     unsigned int prevused = (*mptr)->used;
54     (*mptr)->used += (size + ALIGN_MASK) & ~ALIGN_MASK;
55     return ((char *) (*mptr)) + prevused;
56   }
57 
58   return mempool_create (mptr, size, max_size, (*mptr)->malloc, (*mptr)->free);
59 }
60 
61 LIQ_PRIVATE void
mempool_destroy(mempool m)62 mempool_destroy (mempool m)
63 {
64   while (m) {
65     mempool next = m->next;
66     m->free (m);
67     m = next;
68   }
69 }
70