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 = (char *)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 = (char *)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;
127 g_print ("Mempool %p stats:\n", pool);
128 g_print ("Total mem allocated: %d\n", pool->d.allocated);
129 g_print ("Num chunks: %d\n", count);
130 g_print ("Free memory: %d\n", still_free);
135 * mono_mempool_alloc:
136 * @pool: the momory pool to destroy
137 * @size: size of the momory block
139 * Allocates a new block of memory in @pool.
141 * Returns: the address of a newly allocated memory block.
144 mono_mempool_alloc (MonoMemPool *pool, guint size)
148 size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
151 pool->pos = (char*)rval + size;
153 if (G_UNLIKELY (pool->pos >= pool->end)) {
156 MonoMemPool *np = g_malloc (sizeof (MonoMemPool) + size);
157 np->next = pool->next;
159 np->size = sizeof (MonoMemPool) + size;
160 pool->d.allocated += sizeof (MonoMemPool) + size;
161 return (char *)np + sizeof (MonoMemPool);
163 MonoMemPool *np = g_malloc (MONO_MEMPOOL_PAGESIZE);
164 np->next = pool->next;
166 pool->pos = (char *)np + sizeof (MonoMemPool);
167 np->size = MONO_MEMPOOL_PAGESIZE;
168 pool->end = pool->pos + MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
169 pool->d.allocated += MONO_MEMPOOL_PAGESIZE;
180 * mono_mempool_alloc0:
182 * same as mono_mempool_alloc, but fills memory with zero.
185 mono_mempool_alloc0 (MonoMemPool *pool, guint size)
189 size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
192 pool->pos = (char*)rval + size;
194 if (G_UNLIKELY (pool->pos >= pool->end)) {
195 rval = mono_mempool_alloc (pool, size);
198 memset (rval, 0, size);
203 * mono_mempool_contains_addr:
205 * Determines whenever ADDR is inside the memory used by the mempool.
208 mono_mempool_contains_addr (MonoMemPool *pool,
215 if (addr > (gpointer)p && addr <= (gpointer)((guint8*)p + p->size))