lemon-project-template-glpk
view deps/glpk/src/glpdmp.c @ 9:33de93886c88
Import GLPK 4.47
author | Alpar Juttner <alpar@cs.elte.hu> |
---|---|
date | Sun, 06 Nov 2011 20:59:10 +0100 |
parents | |
children |
line source
1 /* glpdmp.c (dynamic memory pool) */
3 /***********************************************************************
4 * This code is part of GLPK (GNU Linear Programming Kit).
5 *
6 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
7 * 2009, 2010, 2011 Andrew Makhorin, Department for Applied Informatics,
8 * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
9 * E-mail: <mao@gnu.org>.
10 *
11 * GLPK is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * GLPK is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19 * License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
23 ***********************************************************************/
25 #include "glpdmp.h"
27 #if 1 /* 29/VIII-2008 */
28 /* some processors need data to be properly aligned; the macro
29 align_datasize enlarges the specified size of a data item to provide
30 a proper alignment of immediately following data */
32 #define align_datasize(size) ((((size) + 7) / 8) * 8)
33 /* 8 bytes is sufficient in both 32- and 64-bit environments */
34 #endif
36 #ifdef GLP_DEBUG
37 struct info
38 { DMP *pool;
39 int size;
40 };
41 #endif
43 /***********************************************************************
44 * NAME
45 *
46 * dmp_create_pool - create dynamic memory pool
47 *
48 * SYNOPSIS
49 *
50 * #include "glpdmp.h"
51 * DMP *dmp_create_pool(void);
52 *
53 * DESCRIPTION
54 *
55 * The routine dmp_create_pool creates a dynamic memory pool.
56 *
57 * RETURNS
58 *
59 * The routine returns a pointer to the memory pool created. */
61 DMP *dmp_create_pool(void)
62 { DMP *pool;
63 int k;
64 #ifdef GLP_DEBUG
65 xprintf("dmp_create_pool: warning: debug mode enabled\n");
66 #endif
67 pool = xmalloc(sizeof(DMP));
68 #if 0
69 pool->size = 0;
70 #endif
71 for (k = 0; k <= 31; k++) pool->avail[k] = NULL;
72 pool->block = NULL;
73 pool->used = DMP_BLK_SIZE;
74 pool->count.lo = pool->count.hi = 0;
75 return pool;
76 }
78 /***********************************************************************
79 * NAME
80 *
81 * dmp_get_atom - get free atom from dynamic memory pool
82 *
83 * SYNOPSIS
84 *
85 * #include "glpdmp.h"
86 * void *dmp_get_atom(DMP *pool, int size);
87 *
88 * DESCRIPTION
89 *
90 * The routine dmp_get_atom obtains a free atom (memory block) from the
91 * specified memory pool.
92 *
93 * The parameter size is the atom size, in bytes, 1 <= size <= 256.
94 *
95 * Note that the free atom contains arbitrary data, not binary zeros.
96 *
97 * RETURNS
98 *
99 * The routine returns a pointer to the free atom obtained. */
101 void *dmp_get_atom(DMP *pool, int size)
102 { void *atom;
103 int k;
104 #ifdef GLP_DEBUG
105 int orig_size = size;
106 #endif
107 if (!(1 <= size && size <= 256))
108 xerror("dmp_get_atom: size = %d; invalid atom size\n", size);
109 #if 0
110 if (!(pool->size == 0 || pool->size == size))
111 xerror("dmp_get_atom: size = %d; wrong atom size\n", size);
112 #endif
113 /* adjust the size to provide the proper data alignment */
114 size = align_datasize(size);
115 #ifdef GLP_DEBUG
116 size += align_datasize(sizeof(struct info));
117 #endif
118 /* adjust the size to make it multiple of 8 bytes, if needed */
119 size = ((size + 7) / 8) * 8;
120 /* determine the corresponding list of free cells */
121 k = size / 8 - 1;
122 xassert(0 <= k && k <= 31);
123 /* obtain a free atom */
124 if (pool->avail[k] == NULL)
125 { /* the list of free cells is empty */
126 if (pool->used + size > DMP_BLK_SIZE)
127 { /* allocate a new memory block */
128 void *block = xmalloc(DMP_BLK_SIZE);
129 *(void **)block = pool->block;
130 pool->block = block;
131 pool->used = align_datasize(sizeof(void *));
132 }
133 /* place the atom in the current memory block */
134 atom = (char *)pool->block + pool->used;
135 pool->used += size;
136 }
137 else
138 { /* obtain the atom from the list of free cells */
139 atom = pool->avail[k];
140 pool->avail[k] = *(void **)atom;
141 }
142 memset(atom, '?', size);
143 /* increase the number of atoms which are currently in use */
144 pool->count.lo++;
145 if (pool->count.lo == 0) pool->count.hi++;
146 #ifdef GLP_DEBUG
147 ((struct info *)atom)->pool = pool;
148 ((struct info *)atom)->size = orig_size;
149 atom = (char *)atom + align_datasize(sizeof(struct info));
150 #endif
151 return atom;
152 }
154 /***********************************************************************
155 * NAME
156 *
157 * dmp_free_atom - return atom to dynamic memory pool
158 *
159 * SYNOPSIS
160 *
161 * #include "glpdmp.h"
162 * void dmp_free_atom(DMP *pool, void *atom, int size);
163 *
164 * DESCRIPTION
165 *
166 * The routine dmp_free_atom returns the specified atom (memory block)
167 * to the specified memory pool, making it free.
168 *
169 * The parameter size is the atom size, in bytes, 1 <= size <= 256.
170 *
171 * Note that the atom can be returned only to the pool, from which it
172 * was obtained, and its size must be exactly the same as on obtaining
173 * it from the pool. */
175 void dmp_free_atom(DMP *pool, void *atom, int size)
176 { int k;
177 if (!(1 <= size && size <= 256))
178 xerror("dmp_free_atom: size = %d; invalid atom size\n", size);
179 #if 0
180 if (!(pool->size == 0 || pool->size == size))
181 xerror("dmp_free_atom: size = %d; wrong atom size\n", size);
182 #endif
183 if (pool->count.lo == 0 && pool->count.hi == 0)
184 xerror("dmp_free_atom: pool allocation error\n");
185 #ifdef GLP_DEBUG
186 atom = (char *)atom - align_datasize(sizeof(struct info));
187 xassert(((struct info *)atom)->pool == pool);
188 xassert(((struct info *)atom)->size == size);
189 #endif
190 /* adjust the size to provide the proper data alignment */
191 size = align_datasize(size);
192 #ifdef GLP_DEBUG
193 size += align_datasize(sizeof(struct info));
194 #endif
195 /* adjust the size to make it multiple of 8 bytes, if needed */
196 size = ((size + 7) / 8) * 8;
197 /* determine the corresponding list of free cells */
198 k = size / 8 - 1;
199 xassert(0 <= k && k <= 31);
200 /* return the atom to the list of free cells */
201 *(void **)atom = pool->avail[k];
202 pool->avail[k] = atom;
203 /* decrease the number of atoms which are currently in use */
204 pool->count.lo--;
205 if (pool->count.lo == 0xFFFFFFFF) pool->count.hi--;
206 return;
207 }
209 /***********************************************************************
210 * NAME
211 *
212 * dmp_in_use - determine how many atoms are still in use
213 *
214 * SYNOPSIS
215 *
216 * #include "glpdmp.h"
217 * glp_long dmp_in_use(DMP *pool);
218 *
219 * DESCRIPTION
220 *
221 * The routine dmp_in_use determines how many atoms allocated from the
222 * specified memory pool with the routine dmp_get_atom are still in use,
223 * i.e. not returned to the pool with the routine dmp_free_atom.
224 *
225 * RETURNS
226 *
227 * The routine returns the number of atoms which are still in use. */
229 glp_long dmp_in_use(DMP *pool)
230 { return
231 pool->count;
232 }
234 /***********************************************************************
235 * NAME
236 *
237 * dmp_delete_pool - delete dynamic memory pool
238 *
239 * SYNOPSIS
240 *
241 * #include "glpdmp.h"
242 * void dmp_delete_pool(DMP *pool);
243 *
244 * DESCRIPTION
245 *
246 * The routine dmp_delete_pool deletes the specified dynamic memory
247 * pool and frees all the memory allocated to this object. */
249 void dmp_delete_pool(DMP *pool)
250 { while (pool->block != NULL)
251 { void *block = pool->block;
252 pool->block = *(void **)block;
253 xfree(block);
254 }
255 xfree(pool);
256 return;
257 }
259 /* eof */