Merge pull request #113 from tesselode/fix-multi-targets
[wdl/wdl-ol.git] / WDL / chunkalloc.h
bloba4aa5b554228407477854cb61d7b4b6be1942d87
1 #ifndef _WDL_CHUNKALLOC_H_
2 #define _WDL_CHUNKALLOC_H_
4 #include "wdltypes.h"
6 class WDL_ChunkAlloc
8 struct _hdr
10 struct _hdr *_next;
11 char data[16];
14 _hdr *m_chunks;
15 int m_chunksize, m_chunkused;
17 public:
19 WDL_ChunkAlloc(int chunksize=65500) { m_chunks=NULL; m_chunkused=0; m_chunksize=chunksize>16?chunksize:16; }
20 ~WDL_ChunkAlloc() { Free(); }
22 void Free()
24 _hdr *a = m_chunks;
25 m_chunks=0;
26 m_chunkused=0;
27 while (a) { _hdr *f=a; a=a->_next; free(f); }
30 void *Alloc(int sz, int align=0)
32 if (sz<1) return NULL;
34 if (align < 1 || (align & (align-1))) align=1;
36 if (m_chunks)
38 int use_sz=sz;
39 char *p = m_chunks->data + m_chunkused;
40 int a = ((int) (INT_PTR)p) & (align-1);
41 if (a)
43 use_sz += align-a;
44 p += align-a;
46 if (use_sz <= m_chunksize - m_chunkused)
48 m_chunkused += use_sz;
49 return p;
53 // we assume that malloc always gives at least 8 byte alignment, and our _next ptr may offset that by 4,
54 // so no need to allocate extra if less than 4 bytes of alignment requested
55 int use_align = (align>=4 ? align : 0);
56 int alloc_sz=sz+use_align;
57 if (alloc_sz < m_chunksize)
59 // if existing chunk has less free space in it than we would at chunksize, allocate chunksize
60 if (!m_chunks || m_chunkused > alloc_sz) alloc_sz=m_chunksize;
62 _hdr *nc = (_hdr *)malloc(sizeof(_hdr) + alloc_sz - 16);
63 if (!nc) return NULL;
65 int use_sz=sz;
66 char *ret = nc->data;
67 int a = ((int) (INT_PTR)ret) & (align-1);
68 if (a)
70 use_sz += align-a;
71 ret += align-a;
74 if (m_chunks && (m_chunksize-m_chunkused) >= (alloc_sz - use_sz))
76 // current chunk has as much or more free space than our chunk, put our chunk on the list second
77 nc->_next = m_chunks->_next;
78 m_chunks->_next=nc;
80 else
82 // push our chunk to the top of the list
83 nc->_next = m_chunks;
84 m_chunks=nc;
85 m_chunkused = alloc_sz >= m_chunksize ? use_sz : m_chunksize;
88 return ret;
91 char *StrDup(const char *s)
93 if (!s) return NULL;
94 const int l = (int) strlen(s)+1;
95 char *ret = (char*)Alloc(l);
96 if (!ret) return NULL;
97 memcpy(ret,s,l);
98 return ret;
103 #endif