/* Record manager routines */ #include "memint.h" #define ALLOC_SIZE NICE_BLOCK_SIZE /* #define DEBUG_MEM */ #define MAGIC_COOKIE 0x34f21ab3l #define MAGIC_COOKIE1 0x432fa13bl struct list_ { struct list_ *next; }; typedef struct list_ *list; struct rec_mgr_ { int size; int recs_per_block; list free; list blocks; }; /* mem_new_rec(mgr) allocates a record from the specified record */ /* manager. */ pointer #if defined(__STDC__) mem_new_rec(rec_mgr mgr) #else mem_new_rec(mgr) rec_mgr mgr; #endif { int i; pointer p; list new_; if (!mgr->free) { /* Allocate a new block. */ new_=(list)mem_get_block(ALLOC_SIZE); new_->next=mgr->blocks; mgr->blocks=new_; mgr->free=(list)((INT_PTR)new_+ROUNDUP(sizeof(struct list_))); p=(pointer)(mgr->free); /* Carve the block into pieces. */ for (i=1; i < mgr->recs_per_block; ++i) { ((list)p)->next=(list)((INT_PTR)p+mgr->size); #if defined(DEBUG_MEM) if (mgr->size >= sizeof(long)+sizeof(struct list_)) *(long *)(sizeof(struct list_)+(INT_PTR)p)=MAGIC_COOKIE; #endif p=(pointer)((INT_PTR)p+mgr->size); } ((list)p)->next=0; #if defined(DEBUG_MEM) if (mgr->size >= sizeof(long)+sizeof(struct list_)) *(long *)(sizeof(struct list_)+(INT_PTR)p)=MAGIC_COOKIE; #endif } new_=mgr->free; #if defined(DEBUG_MEM) if (mgr->size >= sizeof(long)+sizeof(struct list_)) if (*(long *)(sizeof(struct list_)+(INT_PTR)new_) != MAGIC_COOKIE) fprintf(stderr, "record at 0x%lx may be in use\n", (INT_PTR)new_); else *(long *)(sizeof(struct list_)+(INT_PTR)new_)=MAGIC_COOKIE1; #endif mgr->free=mgr->free->next; return ((pointer)new_); } /* mem_free_rec(mgr, rec) frees a record managed by the indicated */ /* record manager. */ void #if defined(__STDC__) mem_free_rec(rec_mgr mgr, pointer rec) #else mem_free_rec(mgr, rec) rec_mgr mgr; pointer rec; #endif { #if defined(DEBUG_MEM) if (mgr->size >= sizeof(long)+sizeof(struct list_)) if (*(long *)(sizeof(struct list_)+(INT_PTR)rec) == MAGIC_COOKIE) fprintf(stderr, "record at 0x%lx may already be freed\n", (INT_PTR)rec); #endif ((list)rec)->next=mgr->free; #if defined(DEBUG_MEM) if (mgr->size >= sizeof(long)+sizeof(struct list_)) *(long *)(sizeof(struct list_)+(INT_PTR)rec)=MAGIC_COOKIE; #endif mgr->free=(list)rec; } /* mem_new_rec_mgr(size) creates a new record manager with the given */ /* record size. */ rec_mgr #if defined(__STDC__) mem_new_rec_mgr(int size) #else mem_new_rec_mgr(size) int size; #endif { rec_mgr mgr; if (size < sizeof(struct list_)) size=sizeof(struct list_); size=ROUNDUP(size); if (size > ALLOC_SIZE-ROUNDUP(sizeof(struct list_))) mem_fatal("mem_new_rec_mgr: record size too large"); mgr=(rec_mgr)mem_get_block((SIZE_T)sizeof(struct rec_mgr_)); mgr->size=size; mgr->recs_per_block=(ALLOC_SIZE-ROUNDUP(sizeof(struct list_)))/size; mgr->free=0; mgr->blocks=0; return (mgr); } /* mem_free_rec_mgr(mgr) frees all the storage associated with the */ /* specified record manager. */ void #if defined(__STDC__) mem_free_rec_mgr(rec_mgr mgr) #else mem_free_rec_mgr(mgr) rec_mgr mgr; #endif { list p, q; for (p=mgr->blocks; p; p=q) { q=p->next; mem_free_block((pointer)p); } mem_free_block((pointer)mgr); }