1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
|
/**************************************************************/
/* ********************************************************** */
/* * * */
/* * DYNAMIC MEMORY MANAGEMENT MODULE * */
/* * * */
/* * $Module: MEMORY * */
/* * * */
/* * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 * */
/* * MPI fuer Informatik * */
/* * * */
/* * This program is free software; you can redistribute * */
/* * it and/or modify it under the terms of the FreeBSD * */
/* * Licence. * */
/* * * */
/* * This program is distributed in the hope that it will * */
/* * be useful, but WITHOUT ANY WARRANTY; without even * */
/* * the implied warranty of MERCHANTABILITY or FITNESS * */
/* * FOR A PARTICULAR PURPOSE. See the LICENCE file * */
/* * for more details. * */
/* * * */
/* * * */
/* $Revision: 1.2 $ * */
/* $State: Exp $ * */
/* $Date: 2010-02-22 14:09:58 $ * */
/* $Author: weidenb $ * */
/* * * */
/* * Contact: * */
/* * Christoph Weidenbach * */
/* * MPI fuer Informatik * */
/* * Stuhlsatzenhausweg 85 * */
/* * 66123 Saarbruecken * */
/* * Email: spass@mpi-inf.mpg.de * */
/* * Germany * */
/* * * */
/* ********************************************************** */
/**************************************************************/
/* $RCSfile: memory.h,v $ */
#ifndef _MEMORY_
#define _MEMORY_
/**************************************************************/
/* Includes */
/**************************************************************/
#include "misc.h"
/**************************************************************/
/* Data structures and constants */
/**************************************************************/
#ifndef memory__DYNMAXSIZE
#define memory__DYNMAXSIZE 1024 /* At most blocks of size memory__DYNMAXSIZE
bytes are administrated by the
module, larger requests are
directly mapped to system calls */
#endif
#ifndef memory__SHAREDPAGES
#define memory__SHAREDPAGES 1 /* Number of block sizes sharing an allocated
page. By setting memory__SHAREDPAGES to 4,
the module would administrate requests
for 1, 2, 3 and 4 bytes on the same set of
pages, requests for 5, 6, 7 and 8 on another
one, etc. By default every block size has
its own set of pages */
#endif
#ifndef memory__FREESHREDDER
#define memory__FREESHREDDER 'S' /* The decimal number 83, which can also be
read as 53 hexadecimal, or the character
'S' in ASCII code */
#endif
#define memory__KILOBYTE 1024
#ifndef memory__DEFAULTPAGESIZE
#define memory__DEFAULTPAGESIZE (8 * memory__KILOBYTE)
/* Used to set the default size of a page.
If the default page size is too small to
contain two objects of size memory__DYNMAXSIZE
the default page size is automatically
increased by the function memory_Init */
#endif
#ifndef memory__UNLIMITED
#define memory__UNLIMITED (-1)
/* Used to set the maximal amount of memory
available for the memory module to
"unlimited" when calling memory_Init. */
#endif
typedef struct MEMORY_RESOURCEHELP {
POINTER free; /* pointer to the next free block in list */
POINTER next; /* pointer to the next fresh block */
POINTER page; /* pointer to head of page list */
POINTER end_of_page; /* pointer to the end of current page */
int total_size; /* total block size inc. debug marks */
int aligned_size; /* block size without debug marks */
int offset; /* offset of last usable block on page */
} MEMORY_RESOURCE;
extern MEMORY_RESOURCE * memory_ARRAY[];
#if defined(CHECK)
typedef struct MEMORY_INFOHELP {
const char * mallocInFile; /* origin of allocation request: file */
const char * freeInFile; /* origin of deallocation request: file */
unsigned short int mallocAtLine; /* origin of allocation request: line */
unsigned short int freeAtLine; /* origin of deallocation request: line */
} MEMORY_INFONODE, * MEMORY_INFO;
#endif
typedef struct MEMORY_BIGBLOCKHEADERHELP {
struct MEMORY_BIGBLOCKHEADERHELP * previous, * next;
} MEMORY_BIGBLOCKHEADERNODE, * MEMORY_BIGBLOCKHEADER;
extern long memory_MAXMEM;
extern unsigned long memory_NEWBYTES;
extern unsigned long memory_FREEDBYTES;
extern const unsigned int memory_MAGICMALLOC;
extern const unsigned int memory_MAGICFREE;
extern const unsigned int memory_ALIGN;
extern MEMORY_BIGBLOCKHEADER memory_BIGBLOCKS;
/**************************************************************/
/* Debug Information */
/**************************************************************/
extern unsigned int memory_MARKSIZE;
extern unsigned int memory_OFFSET;
/**************************************************************/
/* Check Functions */
/**************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CHECK
void memory_CheckFree(POINTER Freepointer, unsigned int Size, unsigned int RealBlockSize, const char * File, unsigned short int Line);
#endif /* CHECK */
#ifdef __cplusplus
}
#endif
/**************************************************************/
/* Inline Functions */
/**************************************************************/
static __inline__ unsigned int memory_CalculateRealBlockSize(unsigned int
BlockSize)
/**********************************************************
INPUT : Size of a block of memory.
RETURNS: its real size.
SUMMARY: Calculates the size of a memory block,
including padding due to memory alignment and
page sharing
**********************************************************/
{
unsigned int RealSize;
RealSize = BlockSize;
if (RealSize % memory__SHAREDPAGES) {
RealSize += memory__SHAREDPAGES - (RealSize % memory__SHAREDPAGES);
}
if (RealSize % memory_ALIGN) {
RealSize += memory_ALIGN - (RealSize % memory_ALIGN);
}
return RealSize;
}
static __inline__ unsigned int memory_LookupRealBlockSize(unsigned int
BlockSize)
/**********************************************************
INPUT : Size of a block of memory.
RETURNS: its real size.
SUMMARY: Returns the size of a memory block,
including padding due to memory alignment and
page sharing.
**********************************************************/
{
unsigned int RealSize;
if (BlockSize < memory__DYNMAXSIZE) {
RealSize = memory_ARRAY[BlockSize]->aligned_size;
}
else {
RealSize = memory_CalculateRealBlockSize(BlockSize);
}
return RealSize;
}
#ifdef CHECK
static __inline__ void memory_SetBlockStatusAndSize(POINTER Mem,
unsigned int Status,
unsigned int Size)
/**********************************************************
INPUT : a pointer to a block of memory, its status
(memory_MAGICMALLOC or memory_MAGICFREE), and
size.
RETURNS: None.
SUMMARY: Sets a status flag (memory_MAGICMALLOC or
memory_MAGICFREE) and block size.
**********************************************************/
{
*((int *)Mem - 1) = Size;
*((int *)((char *)Mem + memory_LookupRealBlockSize(Size))) = Status;
}
static __inline__ unsigned int memory_GetBlockSize(POINTER Mem)
/**********************************************************
INPUT : A pointer to a block of memory.
RETURNS: its size.
SUMMARY: Returns the size of a memory block.
**********************************************************/
{
return *((int *)Mem - 1);
}
static __inline__ unsigned int memory_GetRealBlockSize(POINTER Mem)
/**********************************************************
INPUT : A pointer to a block of memory.
RETURNS: its real size.
SUMMARY: Returns the real size of a memory block,
including padding bytes.
**********************************************************/
{
return memory_LookupRealBlockSize(memory_GetBlockSize(Mem));
}
static __inline__ unsigned int memory_GetBlockStatus(POINTER Mem)
/**********************************************************
INPUT : A pointer to a block of memory.
RETURNS: its status.
SUMMARY: Returns the status of a memory block.
**********************************************************/
{
unsigned int Size;
Size = memory_GetBlockSize(Mem);
return *((int *)((char *)Mem + memory_LookupRealBlockSize(Size)));
}
static __inline__ void memory_SetInfo(MEMORY_INFO Info,
const char * MallocInFile,
unsigned short int MallocAtLine,
const char * FreeInFile,
unsigned short int FreeAtLine)
/**********************************************************
INPUT : a memory info structure, strings for files where
the block was allocated and freed, and short
integers for the corresponding lines.
RETURNS: None.
SUMMARY: Sets the debugging information for a memory block
**********************************************************/
{
if (!Info) {
misc_StartErrorReport();
misc_ErrorReport("\n In memory_SetInfo:");
misc_ErrorReport("\n Memory Error. Info is a NULL pointer.\n");
misc_FinishErrorReport();
}
Info->mallocAtLine = MallocAtLine;
Info->mallocInFile = MallocInFile;
Info->freeAtLine = FreeAtLine;
Info->freeInFile = FreeInFile;
}
#endif
static __inline__ unsigned long memory_DemandedBytes(void)
/**********************************************************
INPUT : Nothing.
RETURNS: Maximum number of bytes allocated at the same
time by the module.
SUMMARY: Returns maximum number of allocated bytes at the
same time.
**********************************************************/
{
return memory_NEWBYTES;
}
static __inline__ unsigned long memory_UsedBytes(void)
/**********************************************************
INPUT : Nothing.
RETURNS: Number of bytes currently in use by your program.
SUMMARY: Returns number of bytes currently allocated.
**********************************************************/
{
return memory_NEWBYTES-memory_FREEDBYTES;
}
/**************************************************************/
/* Functions */
/**************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
void memory_Init(long);
void memory_Restrict(long);
void memory_Print(void);
void memory_FPrint(FILE*);
void memory_PrintLeaks(void);
void memory_PrintDetailed(void);
void memory_PrintAllocatedBlocks(unsigned int Size);
void memory_PrintFreedBlocks(unsigned int Size);
void memory_PrintAllocatedBigBlocks(void);
void memory_FreeAllMem(void);
#ifdef __cplusplus
}
#endif
#if defined(CHECK) && !defined(NO_MEMORY_MANAGEMENT)
/* declare drop-in debug versions memory functions */
#ifdef __cplusplus
extern "C" {
#endif
POINTER memory_MallocIntern(unsigned int, const char *, unsigned short int);
void memory_FreeIntern(POINTER Freepointer,
unsigned int Size,
const char * File,
unsigned short int Line);
POINTER memory_CallocIntern(unsigned int,
unsigned int,
const char *,
unsigned short int);
#ifdef __cplusplus
}
#endif
#define memory_Malloc(Size) memory_MallocIntern((Size), __FILE__, __LINE__)
#define memory_Calloc(Elements, Size) \
memory_CallocIntern((Elements), (Size), __FILE__, __LINE__)
#define memory_Free(Pointer, Size) \
memory_FreeIntern((Pointer), (Size), __FILE__, __LINE__)
#else
#ifdef __cplusplus
extern "C" {
#endif
POINTER memory_Malloc(unsigned int);
void memory_Free(POINTER Freepointer, unsigned int Size);
POINTER memory_Calloc(unsigned int, unsigned int);
#ifdef __cplusplus
}
#endif
#endif
#endif
|