00001 /* Record manager routines */ 00002 00003 00004 #include "memint.h" 00005 00006 00007 #define ALLOC_SIZE NICE_BLOCK_SIZE 00008 00009 00010 /* #define DEBUG_MEM */ 00011 #define MAGIC_COOKIE 0x34f21ab3l 00012 #define MAGIC_COOKIE1 0x432fa13bl 00013 00014 00015 struct list_ 00016 { 00017 struct list_ *next; 00018 }; 00019 00020 typedef struct list_ *list; 00021 00022 00023 struct rec_mgr_ 00024 { 00025 int size; 00026 int recs_per_block; 00027 list free; 00028 list blocks; 00029 }; 00030 00031 00032 /* mem_new_rec(mgr) allocates a record from the specified record */ 00033 /* manager. */ 00034 00035 pointer 00036 #if defined(__STDC__) 00037 mem_new_rec(rec_mgr mgr) 00038 #else 00039 mem_new_rec(mgr) 00040 rec_mgr mgr; 00041 #endif 00042 { 00043 int i; 00044 pointer p; 00045 list new_; 00046 00047 if (!mgr->free) 00048 { 00049 /* Allocate a new block. */ 00050 new_=(list)mem_get_block(ALLOC_SIZE); 00051 new_->next=mgr->blocks; 00052 mgr->blocks=new_; 00053 mgr->free=(list)((INT_PTR)new_+ROUNDUP(sizeof(struct list_))); 00054 p=(pointer)(mgr->free); 00055 /* Carve the block into pieces. */ 00056 for (i=1; i < mgr->recs_per_block; ++i) 00057 { 00058 ((list)p)->next=(list)((INT_PTR)p+mgr->size); 00059 #if defined(DEBUG_MEM) 00060 if (mgr->size >= sizeof(long)+sizeof(struct list_)) 00061 *(long *)(sizeof(struct list_)+(INT_PTR)p)=MAGIC_COOKIE; 00062 #endif 00063 p=(pointer)((INT_PTR)p+mgr->size); 00064 } 00065 ((list)p)->next=0; 00066 #if defined(DEBUG_MEM) 00067 if (mgr->size >= sizeof(long)+sizeof(struct list_)) 00068 *(long *)(sizeof(struct list_)+(INT_PTR)p)=MAGIC_COOKIE; 00069 #endif 00070 } 00071 new_=mgr->free; 00072 #if defined(DEBUG_MEM) 00073 if (mgr->size >= sizeof(long)+sizeof(struct list_)) 00074 if (*(long *)(sizeof(struct list_)+(INT_PTR)new_) != MAGIC_COOKIE) 00075 fprintf(stderr, "record at 0x%lx may be in use\n", (INT_PTR)new_); 00076 else 00077 *(long *)(sizeof(struct list_)+(INT_PTR)new_)=MAGIC_COOKIE1; 00078 #endif 00079 mgr->free=mgr->free->next; 00080 return ((pointer)new_); 00081 } 00082 00083 00084 /* mem_free_rec(mgr, rec) frees a record managed by the indicated */ 00085 /* record manager. */ 00086 00087 void 00088 #if defined(__STDC__) 00089 mem_free_rec(rec_mgr mgr, pointer rec) 00090 #else 00091 mem_free_rec(mgr, rec) 00092 rec_mgr mgr; 00093 pointer rec; 00094 #endif 00095 { 00096 #if defined(DEBUG_MEM) 00097 if (mgr->size >= sizeof(long)+sizeof(struct list_)) 00098 if (*(long *)(sizeof(struct list_)+(INT_PTR)rec) == MAGIC_COOKIE) 00099 fprintf(stderr, "record at 0x%lx may already be freed\n", (INT_PTR)rec); 00100 #endif 00101 ((list)rec)->next=mgr->free; 00102 #if defined(DEBUG_MEM) 00103 if (mgr->size >= sizeof(long)+sizeof(struct list_)) 00104 *(long *)(sizeof(struct list_)+(INT_PTR)rec)=MAGIC_COOKIE; 00105 #endif 00106 mgr->free=(list)rec; 00107 } 00108 00109 00110 /* mem_new_rec_mgr(size) creates a new record manager with the given */ 00111 /* record size. */ 00112 00113 rec_mgr 00114 #if defined(__STDC__) 00115 mem_new_rec_mgr(int size) 00116 #else 00117 mem_new_rec_mgr(size) 00118 int size; 00119 #endif 00120 { 00121 rec_mgr mgr; 00122 00123 if (size < sizeof(struct list_)) 00124 size=sizeof(struct list_); 00125 size=ROUNDUP(size); 00126 if (size > ALLOC_SIZE-ROUNDUP(sizeof(struct list_))) 00127 mem_fatal("mem_new_rec_mgr: record size too large"); 00128 mgr=(rec_mgr)mem_get_block((SIZE_T)sizeof(struct rec_mgr_)); 00129 mgr->size=size; 00130 mgr->recs_per_block=(ALLOC_SIZE-ROUNDUP(sizeof(struct list_)))/size; 00131 mgr->free=0; 00132 mgr->blocks=0; 00133 return (mgr); 00134 } 00135 00136 00137 /* mem_free_rec_mgr(mgr) frees all the storage associated with the */ 00138 /* specified record manager. */ 00139 00140 void 00141 #if defined(__STDC__) 00142 mem_free_rec_mgr(rec_mgr mgr) 00143 #else 00144 mem_free_rec_mgr(mgr) 00145 rec_mgr mgr; 00146 #endif 00147 { 00148 list p, q; 00149 00150 for (p=mgr->blocks; p; p=q) 00151 { 00152 q=p->next; 00153 mem_free_block((pointer)p); 00154 } 00155 mem_free_block((pointer)mgr); 00156 }