#include <stdio.h>
Go to the source code of this file.
Defines | |
#define | CAL_ALLOC_ALIGNMENT sizeof(void *) |
#define | Cal_Nil(obj) ((obj *)0) |
#define | USE_OS_MEMORY_MANAGEMENT |
#define | Cal_MemAlloc(type, num) ((type *) malloc(sizeof(type) * (num))) |
#define | Cal_MemRealloc(type, obj, num) |
#define | Cal_MemFree(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) |
#define | Cal_MemCopy(dest, src, size) ((void *) memcpy((void *)dest, (const void *)src, (size_t)size)); |
#define | Cal_MemZero(ptr, size) ((void)memset((void *)(ptr), 0, (Cal_Address_t)(size))) |
#define | CAL_ROUNDUP(size) ((((size)+CAL_ALLOC_ALIGNMENT-1)/CAL_ALLOC_ALIGNMENT)*CAL_ALLOC_ALIGNMENT) |
Typedefs | |
typedef struct Cal_RecMgrStruct * | Cal_RecMgr |
typedef void * | Cal_Pointer_t |
typedef size_t | Cal_Address_t |
Functions | |
EXTERN void | Cal_MemFatal (char *message) |
EXTERN Cal_Address_t | Cal_MemAllocation (void) |
EXTERN Cal_Pointer_t | Cal_MemGetBlock (Cal_Address_t size) |
EXTERN void | Cal_MemFreeBlock (Cal_Pointer_t p) |
EXTERN Cal_Pointer_t | Cal_MemResizeBlock (Cal_Pointer_t p, Cal_Address_t newSize) |
EXTERN Cal_Pointer_t | Cal_MemNewRec (Cal_RecMgr mgr) |
EXTERN void | Cal_MemFreeRec (Cal_RecMgr mgr, Cal_Pointer_t rec) |
EXTERN Cal_RecMgr | Cal_MemNewRecMgr (int size) |
EXTERN void | Cal_MemFreeRecMgr (Cal_RecMgr mgr) |
#define CAL_ALLOC_ALIGNMENT sizeof(void *) |
CHeaderFile*****************************************************************
FileName [calMem.h]
PackageName [cal]
Synopsis [Header file for memory management]
Description [ ]
SeeAlso []
Author [Rajeev K. Ranjan (rajeev@eecs.berkeley.edu). Originally written by David Long. ]
Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. All rights reserved.
Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
Revision [
]
#define Cal_MemAlloc | ( | type, | |||
num | ) | ((type *) malloc(sizeof(type) * (num))) |
#define Cal_MemFree | ( | obj | ) | ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) |
#define Cal_MemRealloc | ( | type, | |||
obj, | |||||
num | ) |
#define Cal_MemZero | ( | ptr, | |||
size | ) | ((void)memset((void *)(ptr), 0, (Cal_Address_t)(size))) |
typedef size_t Cal_Address_t |
typedef void* Cal_Pointer_t |
typedef struct Cal_RecMgrStruct* Cal_RecMgr |
EXTERN Cal_Address_t Cal_MemAllocation | ( | void | ) |
Function********************************************************************
Synopsis [Returns the memory allocated.]
Description [Returns the memory allocated.]
SideEffects [required]
SeeAlso [optional]
Definition at line 180 of file calMem.c.
00181 { 00182 return (blockAllocation); 00183 }
EXTERN void Cal_MemFatal | ( | char * | message | ) |
AutomaticStart
AutomaticEnd Function********************************************************************
Synopsis [Prints an error message and exits.]
Description [Prints an error message and exits.]
SideEffects [required]
SeeAlso [optional]
Definition at line 162 of file calMem.c.
00163 { 00164 fprintf(stderr, "Memory management library: error: %s\n", message); 00165 exit(1); 00166 }
EXTERN void Cal_MemFreeBlock | ( | Cal_Pointer_t | p | ) |
Function********************************************************************
Synopsis [Frees the block.]
Description [Frees the block.]
SideEffects [required]
SeeAlso [optional]
Definition at line 277 of file calMem.c.
00278 { 00279 Block b; 00280 00281 if (!p) return; 00282 b = (Block) ((Cal_Address_t)p-HEADER_SIZE); 00283 if (!b->used) Cal_MemFatal("Cal_MemFreeBlock: block not in use"); 00284 if (b->sizeIndex < 0 || b->sizeIndex > MAX_SIZEINDEX) Cal_MemFatal("Cal_MemFreeBlock: invalid block header"); 00285 MergeAndFree(b); 00286 }
EXTERN void Cal_MemFreeRec | ( | Cal_RecMgr | mgr, | |
Cal_Pointer_t | rec | |||
) |
Function********************************************************************
Synopsis [Frees a record managed by the indicated record manager. ]
Description [Frees a record managed by the indicated record manager. ]
SideEffects [required]
SeeAlso [optional]
Definition at line 412 of file calMem.c.
00413 { 00414 #if defined(DEBUG_MEM) 00415 if (mgr->size >= sizeof(long)+sizeof(List_t)) 00416 if (*(long *)(sizeof(List_t)+(Cal_Address_t)rec) == MAGIC_COOKIE) 00417 fprintf(stderr, "record at 0x%lx may already be freed\n", (Cal_Address_t)rec); 00418 #endif 00419 ((List)rec)->next=mgr->free; 00420 #if defined(DEBUG_MEM) 00421 if (mgr->size >= sizeof(long)+sizeof(List_t)) 00422 *(long *)(sizeof(List_t)+(Cal_Address_t)rec)=MAGIC_COOKIE; 00423 #endif 00424 mgr->free=(List)rec; 00425 }
EXTERN void Cal_MemFreeRecMgr | ( | Cal_RecMgr | mgr | ) |
Function********************************************************************
Synopsis [Frees all the storage associated with the specified record manager.]
Description [Frees all the storage associated with the specified record manager.]
SideEffects [required]
SeeAlso [optional]
Definition at line 470 of file calMem.c.
00471 { 00472 List p, q; 00473 for (p=mgr->blocks; p; p=q){ 00474 q=p->next; 00475 Cal_MemFreeBlock((Cal_Pointer_t)p); 00476 } 00477 Cal_MemFreeBlock((Cal_Pointer_t)mgr); 00478 }
EXTERN Cal_Pointer_t Cal_MemGetBlock | ( | Cal_Address_t | size | ) |
Function********************************************************************
Synopsis [Allocates a new block of the specified size.]
Description [Allocates a new block of the specified size.]
SideEffects [required]
SeeAlso [optional]
Definition at line 197 of file calMem.c.
00198 { 00199 int i; 00200 int sizeIndex; 00201 int allocSizeIndex; 00202 int newSeg; 00203 Cal_Address_t allocSize; 00204 Cal_Pointer_t sbrkRet; 00205 Block b; 00206 00207 if ((sizeIndex = BlockSizeIndex(size)) < 0) return ((Cal_Pointer_t)0); 00208 00209 /* Find smallest free block which is large enough. */ 00210 for (i = sizeIndex; i <= MAX_SIZEINDEX && !avail[i]; ++i); 00211 if (i > MAX_SIZEINDEX) { 00212 /* We must get more storage; don't allocate less than */ 00213 /* 2^MIN_ALLOC_SIZE_INDEX */ 00214 if (sizeIndex < MIN_ALLOC_SIZEINDEX) allocSizeIndex=MIN_ALLOC_SIZEINDEX; 00215 else allocSizeIndex=sizeIndex; 00216 allocSize=((Cal_Address_t)1 << allocSizeIndex); 00217 00218 /* Pad current segment to be a multiple of 2^allocSizeIndex in */ 00219 /* length. */ 00220 allocSize += ((currSeg->limit + allocSize - 1) & 00221 ~(allocSize - 1)) - currSeg->limit; 00222 if ((sbrkRet=(Cal_Pointer_t)SBRK(0)) != 00223 (Cal_Pointer_t)((Cal_Address_t)currSeg->baseAddress+currSeg->limit) || 00224 allocSize+currSeg->limit > MAX_SEG_SIZE) { 00225 00226 /* Segment is too large or someone else has moved the break. */ 00227 /* Pad to get to appropriate boundary. */ 00228 allocSize=CAL_ROUNDUP((Cal_Address_t)sbrkRet)-(Cal_Address_t)sbrkRet; 00229 00230 /* Pad allocation request with storage for new segment */ 00231 /* information and indicate that a new segment must be */ 00232 /* created. */ 00233 allocSize+=((Cal_Address_t)1 << allocSizeIndex)+CAL_ROUNDUP(sizeof(Segment_t)); 00234 newSeg=1; 00235 } 00236 else newSeg=0; 00237 sbrkRet=(Cal_Pointer_t)SBRK(allocSize); 00238 if (sbrkRet == (Cal_Pointer_t) -1) Cal_MemFatal("Cal_MemGetBlock: allocation failed"); 00239 blockAllocation += allocSize; 00240 if (newSeg){ 00241 currSeg = (Segment) CAL_ROUNDUP((Cal_Address_t)sbrkRet); 00242 currSeg->baseAddress=(Cal_Pointer_t)((Cal_Address_t)currSeg+CAL_ROUNDUP(sizeof(Segment_t))); 00243 currSeg->limit=0; 00244 /* Readjust allocation size. */ 00245 allocSize=(1l << allocSizeIndex); 00246 } 00247 /* Carve allocated space up into blocks and add to free lists. */ 00248 while (allocSize){ 00249 size = allocSize - (allocSize & (allocSize-1)); 00250 b = (Block) ((Cal_Address_t)currSeg->baseAddress+currSeg->limit); 00251 b->sizeIndex = CeilingLog2(size); 00252 b->seg = currSeg; 00253 AddToFreeList(b); 00254 currSeg->limit += size; 00255 allocSize -= size; 00256 } 00257 /* Find free block of appropriate size. */ 00258 for (i=sizeIndex; i <= MAX_SIZEINDEX && !avail[i]; ++i); 00259 } 00260 b = RemoveFromFreeList(avail[i]); 00261 TrimToSize(b, sizeIndex); 00262 return ((Cal_Pointer_t)((Cal_Address_t)b + HEADER_SIZE)); 00263 }
EXTERN Cal_Pointer_t Cal_MemNewRec | ( | Cal_RecMgr | mgr | ) |
Function********************************************************************
Synopsis [Allocates a record from the specified record manager. ]
Description [Allocates a record from the specified record manager. ]
SideEffects [required]
SeeAlso [optional]
Definition at line 355 of file calMem.c.
00356 { 00357 int i; 00358 Cal_Pointer_t p; 00359 List new_; 00360 00361 if (!mgr->free) { 00362 /* Allocate a new block. */ 00363 new_ = (List) Cal_MemGetBlock(ALLOC_SIZE); 00364 mgr->numBlocks++; 00365 new_->next=mgr->blocks; 00366 mgr->blocks=new_; 00367 mgr->free=(List)((Cal_Address_t)new_+CAL_ROUNDUP(sizeof(List_t))); 00368 p=(Cal_Pointer_t)(mgr->free); 00369 /* Carve the block into pieces. */ 00370 for (i=1; i < mgr->recsPerBlock; ++i) { 00371 ((List)p)->next=(List)((Cal_Address_t)p+mgr->size); 00372 #if defined(DEBUG_MEM) 00373 if (mgr->size >= sizeof(long)+sizeof(List_t)) 00374 *(long *)(sizeof(List_t)+(Cal_Address_t)p)=MAGIC_COOKIE; 00375 #endif 00376 p=(Cal_Pointer_t)((Cal_Address_t)p+mgr->size); 00377 } 00378 ((List)p)->next=0; 00379 #if defined(DEBUG_MEM) 00380 if (mgr->size >= sizeof(long)+sizeof(List_t)){ 00381 *(long *)(sizeof(List_t)+(Cal_Address_t)p)=MAGIC_COOKIE; 00382 } 00383 #endif 00384 } 00385 new_ = mgr->free; 00386 #if defined(DEBUG_MEM) 00387 if (mgr->size >= sizeof(long)+sizeof(List_t)){ 00388 if (*(long *)(sizeof(List_t)+(Cal_Address_t)new_) != MAGIC_COOKIE) 00389 fprintf(stderr, "record at 0x%lx may be in use\n", (Cal_Address_t)new_); 00390 else 00391 *(long *)(sizeof(struct 00392 list_)+(Cal_Address_t)new)=MAGIC_COOKIE1; 00393 } 00394 #endif 00395 mgr->free = mgr->free->next; 00396 return ((Cal_Pointer_t)new_); 00397 }
EXTERN Cal_RecMgr Cal_MemNewRecMgr | ( | int | size | ) |
Function********************************************************************
Synopsis [Creates a new record manager with the given record size.]
Description [Creates a new record manager with the given record size.]
SideEffects [required]
SeeAlso [optional]
Definition at line 441 of file calMem.c.
00442 { 00443 Cal_RecMgr mgr; 00444 00445 if (size < sizeof(List_t)) size=sizeof(List_t); 00446 size=CAL_ROUNDUP(size); 00447 if (size > ALLOC_SIZE-CAL_ROUNDUP(sizeof(List_t))) 00448 Cal_MemFatal("Cal_MemNewRecMgr: record size too large"); 00449 mgr = (Cal_RecMgr)Cal_MemGetBlock((Cal_Address_t)sizeof(Cal_RecMgr_t)); 00450 mgr->size=size; 00451 mgr->recsPerBlock=(ALLOC_SIZE-CAL_ROUNDUP(sizeof(List_t)))/size; 00452 mgr->free=0; 00453 mgr->blocks=0; 00454 mgr->numBlocks = 0; 00455 return (mgr); 00456 }
EXTERN Cal_Pointer_t Cal_MemResizeBlock | ( | Cal_Pointer_t | p, | |
Cal_Address_t | newSize | |||
) |
Function********************************************************************
Synopsis [Expands or contracts the block to a new size. We try to avoid moving the block if possible. ]
Description [Expands or contracts the block to a new size. We try to avoid moving the block if possible. ]
SideEffects [required]
SeeAlso [optional]
Definition at line 304 of file calMem.c.
00305 { 00306 int newSizeIndex; 00307 Block b; 00308 Block bb; 00309 Cal_Pointer_t q; 00310 Cal_Address_t oldSize; 00311 00312 if (!p) return (Cal_MemGetBlock(newSize)); 00313 b = (Block) ((Cal_Address_t)p - HEADER_SIZE); 00314 if (!b->used) Cal_MemFatal("Cal_MemResizeBlock: block not in use"); 00315 if (b->sizeIndex < 0 || b->sizeIndex > MAX_SIZEINDEX){ 00316 Cal_MemFatal("Cal_MemResizeBlock: invalid block header"); 00317 } 00318 if ((newSizeIndex = BlockSizeIndex(newSize)) < 0){ 00319 Cal_MemFreeBlock(p); 00320 return ((Cal_Pointer_t)0); 00321 } 00322 if (b->sizeIndex >= newSizeIndex){ 00323 /* Shrink block. */ 00324 TrimToSize(b, newSizeIndex); 00325 return (p); 00326 } 00327 oldSize=(1l << b->sizeIndex) - HEADER_SIZE; 00328 /* Try to expand by adding buddies at higher addresses. */ 00329 for (bb=Buddy(b); 00330 bb && (Cal_Address_t)b < (Cal_Address_t)bb && !bb->used && bb->sizeIndex == b->sizeIndex; 00331 bb=Buddy(b)) { 00332 RemoveFromFreeList(bb); 00333 if (++(b->sizeIndex) == newSizeIndex) return (p); 00334 } 00335 /* Couldn't expand all the way to needed size; allocate a new block */ 00336 /* and move the contents of the old one. */ 00337 q = (Cal_Pointer_t) Cal_MemGetBlock(newSize); 00338 Cal_MemCopy(q, p, oldSize); 00339 MergeAndFree(b); 00340 return (q); 00341 }