1#ifdef DEBUG 2static void print_region_list(void); 3static int check_block_list(queue_entry * block_list, malloc_block * new_block); 4#endif /* DEBUG */ 5 6 7void print_region_list(void) { 8 unsigned int i; 9 malloc_region * cur_region; 10 11 cur_region = (malloc_region *)&malloc_region_list; 12 printf("First region:\n"); 13 printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", 14 (unsigned int)cur_region, 15 (unsigned int)(cur_region->links.prev), 16 (unsigned int)(cur_region->links.next)); 17 18 printf("Region list contents:\n"); 19 20 i = 0; 21 queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { 22 if (i > num_regions) { 23 break; 24 } 25 printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", 26 (unsigned int)cur_region, 27 (unsigned int)(cur_region->links.prev), 28 (unsigned int)(cur_region->links.next)); 29 i++; 30 } 31 return; 32} 33 34void print_block_list(queue_entry * block_list) { 35 malloc_block * cur_block; 36 37 queue_iterate(block_list, cur_block, malloc_block *, links) { 38 printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", 39 (unsigned int)cur_block, 40 (unsigned int)(cur_block->links.prev), 41 (unsigned int)(cur_block->links.next)); 42 } 43 return; 44} 45 46int break_here(void) { 47 return 0; 48} 49 50 51int check_block_list(queue_entry * block_list, malloc_block * new_block) { 52 void * end_of_new_block; 53 malloc_block * cur_block; 54 unsigned int i = 0; 55 56 end_of_new_block = new_block + sizeof(malloc_block); 57 58 queue_iterate(block_list, cur_block, malloc_block *, links) { 59 malloc_region * cur_region; 60 void * end_of_region; 61 void * scratch_block; 62 void * end_of_block; 63 64 cur_region = cur_block->region; 65 end_of_region = cur_region + cur_region->region_size; 66 scratch_block = cur_block; 67 end_of_block = scratch_block + sizeof(malloc_block); 68 69 if ( ((void *)new_block >= scratch_block && (void *)new_block <= end_of_block) || 70 (end_of_new_block >= scratch_block && end_of_new_block <= end_of_block) || 71 (scratch_block >= (void *)new_block && scratch_block <= end_of_new_block) || 72 (end_of_block >= (void *)new_block && end_of_block <= end_of_new_block) ) { 73 74 printf("New block %p overlaps existing block %p.\n", 75 new_block, scratch_block); 76 break_here(); 77 exit(1); 78 return 1; 79 80 } 81 82 if (scratch_block < (void *)cur_region || 83 end_of_block >= end_of_region) { 84 85 printf("Found invalid block link at block %d.\n", i); 86 printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", 87 (unsigned int)cur_block, 88 (unsigned int)(cur_block->links.prev), 89 (unsigned int)(cur_block->links.next)); 90 break_here(); 91 exit(1); 92 return 1; 93 } 94 95 scratch_block = (malloc_block *)cur_block->links.prev; 96 end_of_block = scratch_block + sizeof(malloc_block); 97 98 if (scratch_block < (void *)cur_region || 99 end_of_block >= end_of_region) { 100 101 printf("Found invalid block link at block %d.\n", i); 102 printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", 103 (unsigned int)cur_block, 104 (unsigned int)(cur_block->links.prev), 105 (unsigned int)(cur_block->links.next)); 106 break_here(); 107 exit(1); 108 return 1; 109 } 110 111 scratch_block = (malloc_block *)cur_block->links.next; 112 end_of_block = scratch_block + sizeof(malloc_block); 113 114 if (scratch_block < (void *)cur_region || 115 end_of_block >= end_of_region) { 116 printf("Found invalid block link at block %d.\n", i); 117 118 printf("curr: 0x%8x prev: 0x%8x next: 0x%8x\n", 119 (unsigned int)cur_block, 120 (unsigned int)(cur_block->links.prev), 121 (unsigned int)(cur_block->links.next)); 122 break_here(); 123 exit(1); 124 return 1; 125 } 126 127 i++; 128 } 129 return 0; 130} 131 132 133int malloc_sanity_check(void) { 134 unsigned int i; 135 malloc_region * cur_region; 136 137 i = 0; 138 queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { 139 if (i > num_regions) { 140 return 0; 141 } 142 if (cur_region->links.next != &malloc_region_list && 143 cur_region->links.next < (queue_entry *)cur_region) { 144 printf("inconsistency detected\n"); 145 return 0; 146 } 147 i++; 148 } 149 return 1; 150} 151 152 153/********************************************************************* 154* malloc_hiwat() 155* 156* Returns the maximum amount of memory ever reserved by this package. 157*********************************************************************/ 158size_t malloc_hiwat() { 159 return malloc_hiwater_mark; 160} 161 162void malloc_clear_hiwat(void) { 163 malloc_hiwater_mark = 0; 164 return; 165} 166 167size_t malloc_current_usage(void) 168{ 169 return current_block_total; 170} 171 172size_t malloc_region_usage(void) { 173 size_t total = 0; 174 malloc_region * cur_region; 175 176 queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { 177 total += cur_region->region_size - sizeof(malloc_region); 178 179 } 180 return total; 181} 182 183 184double malloc_peak_usage(void) 185{ 186 return peak_usage; 187} 188 189double malloc_min_usage(void) 190{ 191 return min_usage; 192} 193 194size_t malloc_unused(void) { 195 size_t total = 0; 196 malloc_region * cur_region; 197 malloc_block * cur_block; 198 199 queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { 200 total += cur_region->free_size; 201 202 } 203 queue_iterate(&sorted_free_block_list, cur_block, malloc_block *, links) { 204 total += cur_block->block_size; 205 } 206 207 return total; 208} 209 210double malloc_current_efficiency(void) 211{ 212 double efficiency = 0.0; 213 double total_block_size = 0; 214 double total_request_size = 0; 215 unsigned long total_block_sizeL = 0; 216 unsigned long total_request_sizeL = 0; 217 size_t discrepancy; 218 size_t max_discrepancy = 0; 219 malloc_region * cur_region; 220 malloc_block * cur_block; 221 222 queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { 223 queue_iterate(&cur_region->block_list, cur_block, malloc_block *, links) { 224 size_t cur_block_size = cur_block->block_size - sizeof(malloc_block); 225 total_block_sizeL += cur_block_size; 226 total_request_sizeL += cur_block->request_size; 227 total_block_size += (double)cur_block_size; 228 total_request_size += (double)cur_block->request_size; 229 discrepancy = cur_block_size - cur_block->request_size; 230 if (discrepancy > max_discrepancy) { 231 max_discrepancy = discrepancy; 232 } 233 } 234 } 235 236 if (total_block_size > 0) { 237 efficiency = (double)total_request_size / (double)total_block_size; 238 } else { 239 efficiency = 1.0; 240 } 241 242 printf("requested %.2f, actual %.2f\n", total_request_size, total_block_size); 243 printf("requested %ld, actual %ld\n", total_request_sizeL, total_block_sizeL); 244 printf("max discrepancy %ld\n", max_discrepancy); 245 246 return efficiency; 247} 248 249 250/********************************************************************* 251* malloc_report() 252* 253* Print stats on allocated regions and blocks. 254*********************************************************************/ 255void malloc_report(void) { 256 malloc_region * cur_region; 257 malloc_block * cur_block; 258 size_t total_block_size; 259 260 queue_iterate(&malloc_region_list, cur_region, malloc_region *, links) { 261 262 printf("VM Region, size, free: "); 263 printf("%p, %d, %d\n", cur_region, 264 cur_region->region_size, 265 cur_region->free_size); 266 267 total_block_size = 0; 268 269 queue_iterate(&cur_region->block_list, cur_block, malloc_block *, links) { 270 271 total_block_size += cur_block->block_size; 272 printf(" Block address, size: %p, %ld (%ld)\n", 273 cur_block->buffer, cur_block->block_size, 274 cur_block->block_size - sizeof(malloc_block)); 275 printf(" Block content: %s\n", 276 (char *)cur_block->buffer); 277 } 278 printf(" Total blocks size: %ld\n", total_block_size); 279#if 0 280 queue_iterate(&cur_region->free_list, cur_block, malloc_block *, links) { 281 282 total_block_size += cur_block->block_size; 283 printf(" Free block address, size: %p, %ld (%ld)\n", 284 cur_block->buffer, cur_block->block_size, 285 cur_block->block_size - sizeof(malloc_block)); 286 } 287#endif /* 0 */ 288 } 289 290 printf("High water mark: %ld\n", malloc_hiwater_mark); 291 292 return; 293} /* malloc_report() */ 294 295

