2 * mempool.c: efficient memory allocation
4 * MonoMemPool is for fast allocation of memory. We free
5 * all memory when the pool is destroyed.
8 * Dietmar Maurer (dietmar@ximian.com)
10 * (C) 2001 Ximian, Inc.
20 * MonoMemPool is for fast allocation of memory. We free
21 * all memory when the pool is destroyed.
26 #define MONO_MEMPOOL_PAGESIZE 8192
29 #define G_LIKELY(a) (a)
30 #define G_UNLIKELY(a) (a)
39 double pad; /* to assure proper alignment */
47 * Returns: a new memory pool.
52 MonoMemPool *pool = g_malloc (MONO_MEMPOOL_PAGESIZE);
55 pool->pos = (guint8*)pool + sizeof (MonoMemPool);
56 pool->end = pool->pos + MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
57 pool->d.allocated = pool->size = MONO_MEMPOOL_PAGESIZE;
62 * mono_mempool_destroy:
63 * @pool: the memory pool to destroy
65 * Free all memory associated with this pool.
68 mono_mempool_destroy (MonoMemPool *pool)
81 * mono_mempool_invalidate:
82 * @pool: the memory pool to invalidate
84 * Fill the memory associated with this pool to 0x2a (42). Useful for debugging.
87 mono_mempool_invalidate (MonoMemPool *pool)
94 memset (p, 42, p->size);
100 mono_mempool_empty (MonoMemPool *pool)
102 pool->pos = (guint8*)pool + sizeof (MonoMemPool);
103 pool->end = pool->pos + MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
107 * mono_mempool_stats:
108 * @pool: the momory pool we need stats for
110 * Print a few stats about the mempool
113 mono_mempool_stats (MonoMemPool *pool)
117 guint32 still_free = 0;
121 still_free += p->end - p->pos;
126 g_print ("Mempool %p stats:\n", pool);
127 g_print ("Total mem allocated: %d\n", pool->d.allocated);
128 g_print ("Num chunks: %d\n", count);
129 g_print ("Free memory: %d\n", still_free);
134 * mono_mempool_alloc:
135 * @pool: the momory pool to destroy
136 * @size: size of the momory block
138 * Allocates a new block of memory in @pool.
140 * Returns: the address of a newly allocated memory block.
143 mono_mempool_alloc (MonoMemPool *pool, guint size)
147 size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
150 pool->pos = (guint8*)rval + size;
152 if (G_UNLIKELY (pool->pos >= pool->end)) {
155 MonoMemPool *np = g_malloc (sizeof (MonoMemPool) + size);
156 np->next = pool->next;
158 np->pos = (guint8*)np + sizeof (MonoMemPool);
159 np->size = sizeof (MonoMemPool) + size;
160 np->end = np->pos + np->size - sizeof (MonoMemPool);
161 pool->d.allocated += sizeof (MonoMemPool) + size;
162 return (guint8*)np + sizeof (MonoMemPool);
164 MonoMemPool *np = g_malloc (MONO_MEMPOOL_PAGESIZE);
165 np->next = pool->next;
167 pool->pos = (guint8*)np + sizeof (MonoMemPool);
168 np->pos = (guint8*)np + sizeof (MonoMemPool);
169 np->size = MONO_MEMPOOL_PAGESIZE;
171 pool->end = pool->pos + MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
172 pool->d.allocated += MONO_MEMPOOL_PAGESIZE;
183 * mono_mempool_alloc0:
185 * same as mono_mempool_alloc, but fills memory with zero.
188 mono_mempool_alloc0 (MonoMemPool *pool, guint size)
192 size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
195 pool->pos = (guint8*)rval + size;
197 if (G_UNLIKELY (pool->pos >= pool->end)) {
198 rval = mono_mempool_alloc (pool, size);
201 memset (rval, 0, size);
206 * mono_mempool_contains_addr:
208 * Determines whenever ADDR is inside the memory used by the mempool.
211 mono_mempool_contains_addr (MonoMemPool *pool,
218 if (addr > (gpointer)p && addr <= (gpointer)((guint8*)p + p->size))
227 * mono_mempool_strdup:
229 * Same as strdup, but allocates memory from the mempool.
230 * Returns: a pointer to the newly allocated string data inside the mempool.
233 mono_mempool_strdup (MonoMemPool *pool,
243 res = mono_mempool_alloc (pool, l + 1);
244 memcpy (res, s, l + 1);
250 * mono_mempool_get_allocated:
252 * Return the amount of memory allocated for this mempool.
255 mono_mempool_get_allocated (MonoMemPool *pool)
257 return pool->d.allocated;