lemon-project-template-glpk
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/deps/glpk/src/glpdmp.c Sun Nov 06 20:59:10 2011 +0100 1.3 @@ -0,0 +1,259 @@ 1.4 +/* glpdmp.c (dynamic memory pool) */ 1.5 + 1.6 +/*********************************************************************** 1.7 +* This code is part of GLPK (GNU Linear Programming Kit). 1.8 +* 1.9 +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 1.10 +* 2009, 2010, 2011 Andrew Makhorin, Department for Applied Informatics, 1.11 +* Moscow Aviation Institute, Moscow, Russia. All rights reserved. 1.12 +* E-mail: <mao@gnu.org>. 1.13 +* 1.14 +* GLPK is free software: you can redistribute it and/or modify it 1.15 +* under the terms of the GNU General Public License as published by 1.16 +* the Free Software Foundation, either version 3 of the License, or 1.17 +* (at your option) any later version. 1.18 +* 1.19 +* GLPK is distributed in the hope that it will be useful, but WITHOUT 1.20 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1.21 +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 1.22 +* License for more details. 1.23 +* 1.24 +* You should have received a copy of the GNU General Public License 1.25 +* along with GLPK. If not, see <http://www.gnu.org/licenses/>. 1.26 +***********************************************************************/ 1.27 + 1.28 +#include "glpdmp.h" 1.29 + 1.30 +#if 1 /* 29/VIII-2008 */ 1.31 +/* some processors need data to be properly aligned; the macro 1.32 + align_datasize enlarges the specified size of a data item to provide 1.33 + a proper alignment of immediately following data */ 1.34 + 1.35 +#define align_datasize(size) ((((size) + 7) / 8) * 8) 1.36 +/* 8 bytes is sufficient in both 32- and 64-bit environments */ 1.37 +#endif 1.38 + 1.39 +#ifdef GLP_DEBUG 1.40 +struct info 1.41 +{ DMP *pool; 1.42 + int size; 1.43 +}; 1.44 +#endif 1.45 + 1.46 +/*********************************************************************** 1.47 +* NAME 1.48 +* 1.49 +* dmp_create_pool - create dynamic memory pool 1.50 +* 1.51 +* SYNOPSIS 1.52 +* 1.53 +* #include "glpdmp.h" 1.54 +* DMP *dmp_create_pool(void); 1.55 +* 1.56 +* DESCRIPTION 1.57 +* 1.58 +* The routine dmp_create_pool creates a dynamic memory pool. 1.59 +* 1.60 +* RETURNS 1.61 +* 1.62 +* The routine returns a pointer to the memory pool created. */ 1.63 + 1.64 +DMP *dmp_create_pool(void) 1.65 +{ DMP *pool; 1.66 + int k; 1.67 +#ifdef GLP_DEBUG 1.68 + xprintf("dmp_create_pool: warning: debug mode enabled\n"); 1.69 +#endif 1.70 + pool = xmalloc(sizeof(DMP)); 1.71 +#if 0 1.72 + pool->size = 0; 1.73 +#endif 1.74 + for (k = 0; k <= 31; k++) pool->avail[k] = NULL; 1.75 + pool->block = NULL; 1.76 + pool->used = DMP_BLK_SIZE; 1.77 + pool->count.lo = pool->count.hi = 0; 1.78 + return pool; 1.79 +} 1.80 + 1.81 +/*********************************************************************** 1.82 +* NAME 1.83 +* 1.84 +* dmp_get_atom - get free atom from dynamic memory pool 1.85 +* 1.86 +* SYNOPSIS 1.87 +* 1.88 +* #include "glpdmp.h" 1.89 +* void *dmp_get_atom(DMP *pool, int size); 1.90 +* 1.91 +* DESCRIPTION 1.92 +* 1.93 +* The routine dmp_get_atom obtains a free atom (memory block) from the 1.94 +* specified memory pool. 1.95 +* 1.96 +* The parameter size is the atom size, in bytes, 1 <= size <= 256. 1.97 +* 1.98 +* Note that the free atom contains arbitrary data, not binary zeros. 1.99 +* 1.100 +* RETURNS 1.101 +* 1.102 +* The routine returns a pointer to the free atom obtained. */ 1.103 + 1.104 +void *dmp_get_atom(DMP *pool, int size) 1.105 +{ void *atom; 1.106 + int k; 1.107 +#ifdef GLP_DEBUG 1.108 + int orig_size = size; 1.109 +#endif 1.110 + if (!(1 <= size && size <= 256)) 1.111 + xerror("dmp_get_atom: size = %d; invalid atom size\n", size); 1.112 +#if 0 1.113 + if (!(pool->size == 0 || pool->size == size)) 1.114 + xerror("dmp_get_atom: size = %d; wrong atom size\n", size); 1.115 +#endif 1.116 + /* adjust the size to provide the proper data alignment */ 1.117 + size = align_datasize(size); 1.118 +#ifdef GLP_DEBUG 1.119 + size += align_datasize(sizeof(struct info)); 1.120 +#endif 1.121 + /* adjust the size to make it multiple of 8 bytes, if needed */ 1.122 + size = ((size + 7) / 8) * 8; 1.123 + /* determine the corresponding list of free cells */ 1.124 + k = size / 8 - 1; 1.125 + xassert(0 <= k && k <= 31); 1.126 + /* obtain a free atom */ 1.127 + if (pool->avail[k] == NULL) 1.128 + { /* the list of free cells is empty */ 1.129 + if (pool->used + size > DMP_BLK_SIZE) 1.130 + { /* allocate a new memory block */ 1.131 + void *block = xmalloc(DMP_BLK_SIZE); 1.132 + *(void **)block = pool->block; 1.133 + pool->block = block; 1.134 + pool->used = align_datasize(sizeof(void *)); 1.135 + } 1.136 + /* place the atom in the current memory block */ 1.137 + atom = (char *)pool->block + pool->used; 1.138 + pool->used += size; 1.139 + } 1.140 + else 1.141 + { /* obtain the atom from the list of free cells */ 1.142 + atom = pool->avail[k]; 1.143 + pool->avail[k] = *(void **)atom; 1.144 + } 1.145 + memset(atom, '?', size); 1.146 + /* increase the number of atoms which are currently in use */ 1.147 + pool->count.lo++; 1.148 + if (pool->count.lo == 0) pool->count.hi++; 1.149 +#ifdef GLP_DEBUG 1.150 + ((struct info *)atom)->pool = pool; 1.151 + ((struct info *)atom)->size = orig_size; 1.152 + atom = (char *)atom + align_datasize(sizeof(struct info)); 1.153 +#endif 1.154 + return atom; 1.155 +} 1.156 + 1.157 +/*********************************************************************** 1.158 +* NAME 1.159 +* 1.160 +* dmp_free_atom - return atom to dynamic memory pool 1.161 +* 1.162 +* SYNOPSIS 1.163 +* 1.164 +* #include "glpdmp.h" 1.165 +* void dmp_free_atom(DMP *pool, void *atom, int size); 1.166 +* 1.167 +* DESCRIPTION 1.168 +* 1.169 +* The routine dmp_free_atom returns the specified atom (memory block) 1.170 +* to the specified memory pool, making it free. 1.171 +* 1.172 +* The parameter size is the atom size, in bytes, 1 <= size <= 256. 1.173 +* 1.174 +* Note that the atom can be returned only to the pool, from which it 1.175 +* was obtained, and its size must be exactly the same as on obtaining 1.176 +* it from the pool. */ 1.177 + 1.178 +void dmp_free_atom(DMP *pool, void *atom, int size) 1.179 +{ int k; 1.180 + if (!(1 <= size && size <= 256)) 1.181 + xerror("dmp_free_atom: size = %d; invalid atom size\n", size); 1.182 +#if 0 1.183 + if (!(pool->size == 0 || pool->size == size)) 1.184 + xerror("dmp_free_atom: size = %d; wrong atom size\n", size); 1.185 +#endif 1.186 + if (pool->count.lo == 0 && pool->count.hi == 0) 1.187 + xerror("dmp_free_atom: pool allocation error\n"); 1.188 +#ifdef GLP_DEBUG 1.189 + atom = (char *)atom - align_datasize(sizeof(struct info)); 1.190 + xassert(((struct info *)atom)->pool == pool); 1.191 + xassert(((struct info *)atom)->size == size); 1.192 +#endif 1.193 + /* adjust the size to provide the proper data alignment */ 1.194 + size = align_datasize(size); 1.195 +#ifdef GLP_DEBUG 1.196 + size += align_datasize(sizeof(struct info)); 1.197 +#endif 1.198 + /* adjust the size to make it multiple of 8 bytes, if needed */ 1.199 + size = ((size + 7) / 8) * 8; 1.200 + /* determine the corresponding list of free cells */ 1.201 + k = size / 8 - 1; 1.202 + xassert(0 <= k && k <= 31); 1.203 + /* return the atom to the list of free cells */ 1.204 + *(void **)atom = pool->avail[k]; 1.205 + pool->avail[k] = atom; 1.206 + /* decrease the number of atoms which are currently in use */ 1.207 + pool->count.lo--; 1.208 + if (pool->count.lo == 0xFFFFFFFF) pool->count.hi--; 1.209 + return; 1.210 +} 1.211 + 1.212 +/*********************************************************************** 1.213 +* NAME 1.214 +* 1.215 +* dmp_in_use - determine how many atoms are still in use 1.216 +* 1.217 +* SYNOPSIS 1.218 +* 1.219 +* #include "glpdmp.h" 1.220 +* glp_long dmp_in_use(DMP *pool); 1.221 +* 1.222 +* DESCRIPTION 1.223 +* 1.224 +* The routine dmp_in_use determines how many atoms allocated from the 1.225 +* specified memory pool with the routine dmp_get_atom are still in use, 1.226 +* i.e. not returned to the pool with the routine dmp_free_atom. 1.227 +* 1.228 +* RETURNS 1.229 +* 1.230 +* The routine returns the number of atoms which are still in use. */ 1.231 + 1.232 +glp_long dmp_in_use(DMP *pool) 1.233 +{ return 1.234 + pool->count; 1.235 +} 1.236 + 1.237 +/*********************************************************************** 1.238 +* NAME 1.239 +* 1.240 +* dmp_delete_pool - delete dynamic memory pool 1.241 +* 1.242 +* SYNOPSIS 1.243 +* 1.244 +* #include "glpdmp.h" 1.245 +* void dmp_delete_pool(DMP *pool); 1.246 +* 1.247 +* DESCRIPTION 1.248 +* 1.249 +* The routine dmp_delete_pool deletes the specified dynamic memory 1.250 +* pool and frees all the memory allocated to this object. */ 1.251 + 1.252 +void dmp_delete_pool(DMP *pool) 1.253 +{ while (pool->block != NULL) 1.254 + { void *block = pool->block; 1.255 + pool->block = *(void **)block; 1.256 + xfree(block); 1.257 + } 1.258 + xfree(pool); 1.259 + return; 1.260 +} 1.261 + 1.262 +/* eof */