38ddae614246b85d6de566f78bb63ad347ef1292
[mono.git] / mono / metadata / mempool.c
1 /*
2  * mempool.c: efficient memory allocation
3  *
4  * MonoMemPool is for fast allocation of memory. We free
5  * all memory when the pool is destroyed.
6  *
7  * Author:
8  *   Dietmar Maurer (dietmar@ximian.com)
9  *
10  * (C) 2001 Ximian, Inc.
11  */
12
13 #include <config.h>
14 #include <glib.h>
15 #include <string.h>
16
17 #include "mempool.h"
18
19 /*
20  * MonoMemPool is for fast allocation of memory. We free
21  * all memory when the pool is destroyed.
22  */
23
24 #define MEM_ALIGN 8
25
26 #define MONO_MEMPOOL_PAGESIZE 8192
27
28 struct _MonoMemPool {
29         MonoMemPool *next;
30         gint rest;
31         gpointer pos;
32         double pad; /* to assure proper alignment */
33 };
34
35 /**
36  * mono_mempool_new:
37  *
38  * Returns: a new memory pool.
39  */
40 MonoMemPool *
41 mono_mempool_new ()
42 {
43         MonoMemPool *pool = g_malloc (MONO_MEMPOOL_PAGESIZE);
44
45         pool->next = NULL;
46         pool->pos = (char *)pool + sizeof (MonoMemPool);
47         pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
48         return pool;
49 }
50
51 /**
52  * mono_mempool_destroy:
53  * @pool: the momory pool to destroy
54  *
55  * Free all memory associated with this pool.
56  */
57 void
58 mono_mempool_destroy (MonoMemPool *pool)
59 {
60         MonoMemPool *p, *n;
61
62         p = pool;
63         while (p) {
64                 n = p->next;
65                 g_free (p);
66                 p = n;
67         }
68 }
69
70 /**
71  * mono_mempool_alloc:
72  * @pool: the momory pool to destroy
73  * @size: size of the momory block
74  *
75  * Allocates a new block of memory in @pool. @size must 
76  * be smaller than 256.
77  *
78  * Returns: the address of a newly allocated memory block.
79  */
80 gpointer
81 mono_mempool_alloc (MonoMemPool *pool, guint size)
82 {
83         gpointer rval;
84         
85         g_assert (pool != NULL);
86
87         if (size >= 4096) {
88                 MonoMemPool *np = g_malloc (sizeof (MonoMemPool) + size);
89                 np->next = pool->next;
90                 pool->next = np;
91                 return (char *)np + sizeof (MonoMemPool);
92         }
93
94         size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
95
96         if (pool->rest < size) {
97                 MonoMemPool *np = g_malloc (MONO_MEMPOOL_PAGESIZE);
98                 np->next = pool->next;
99                 pool->next = np;
100                 pool->pos = (char *)np + sizeof (MonoMemPool);
101                 pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
102         }
103
104         rval = pool->pos;
105         pool->rest -= size;
106         pool->pos = (char *)pool->pos + size;
107
108         return rval;
109 }
110
111 /**
112  * mono_mempool_alloc0:
113  *
114  * same as mono_mempool_alloc, but fills memory with zero.
115  */
116 gpointer
117 mono_mempool_alloc0 (MonoMemPool *pool, guint size)
118 {
119         gpointer rval = mono_mempool_alloc (pool, size);
120         memset (rval, 0, size);
121         return rval;
122 }
123