lemon-project-template-glpk

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