lemon-project-template-glpk
comparison deps/glpk/src/glpdmp.c @ 11:4fc6ad2fb8a6
Test GLPK in src/main.cc
author | Alpar Juttner <alpar@cs.elte.hu> |
---|---|
date | Sun, 06 Nov 2011 21:43:29 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:b544957682d1 |
---|---|
1 /* glpdmp.c (dynamic memory pool) */ | |
2 | |
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 ***********************************************************************/ | |
24 | |
25 #include "glpdmp.h" | |
26 | |
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 */ | |
31 | |
32 #define align_datasize(size) ((((size) + 7) / 8) * 8) | |
33 /* 8 bytes is sufficient in both 32- and 64-bit environments */ | |
34 #endif | |
35 | |
36 #ifdef GLP_DEBUG | |
37 struct info | |
38 { DMP *pool; | |
39 int size; | |
40 }; | |
41 #endif | |
42 | |
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. */ | |
60 | |
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 } | |
77 | |
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. */ | |
100 | |
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 } | |
153 | |
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. */ | |
174 | |
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 } | |
208 | |
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. */ | |
228 | |
229 glp_long dmp_in_use(DMP *pool) | |
230 { return | |
231 pool->count; | |
232 } | |
233 | |
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. */ | |
248 | |
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 } | |
258 | |
259 /* eof */ |