static int eval_mm_check(Type *impl, trace_t *trace, int tracenum) { int i, index, size, newsize; char *p, *newp, *oldp, *block; /* Reset the heap and initialize the mm package */ mem_reset_brk(); if (impl->init() < 0) { malloc_error(tracenum, 0, "impl init failed."); } /* Interpret each trace request */ for (i = 0; i < trace->num_ops; i++) { switch (trace->ops[i].type) { case ALLOC: /* malloc */ index = trace->ops[i].index; size = trace->ops[i].size; if ((p = (char *) impl->malloc(size)) == NULL) { malloc_error(tracenum, i, "impl malloc failed."); return 0; } trace->blocks[index] = p; break; case REALLOC: /* realloc */ index = trace->ops[i].index; newsize = trace->ops[i].size; oldp = trace->blocks[index]; if ((newp = (char *) impl->realloc(oldp,newsize)) == NULL) { malloc_error(tracenum, i, "impl realloc failed."); return 0; } trace->blocks[index] = newp; break; case FREE: /* free */ index = trace->ops[i].index; block = trace->blocks[index]; impl->free(block); break; default: app_error("Nonexistent request type in eval_mm_speed"); } if (impl->check() < 0) { malloc_error(tracenum, i, "impl check failed."); return 0; } } return 1; }
/* * eval_mm_speed - This is the function that is used by fcyc() * to measure the running time of the mm malloc package. */ static void eval_mm_speed(void *ptr) { int i, index, size, newsize; char *p, *newp, *oldp, *block; trace_t *trace = ((speed_t *)ptr)->trace; /* Reset the heap and initialize the mm package */ mem_reset_brk(); if (mm_init() < 0) app_error("mm_init failed in eval_mm_speed"); /* Interpret each trace request */ for (i = 0; i < trace->num_ops; i++) switch (trace->ops[i].type) { case ALLOC: /* mm_malloc */ index = trace->ops[i].index; size = trace->ops[i].size; if ((p = mm_malloc(size)) == NULL) app_error("mm_malloc error in eval_mm_speed"); trace->blocks[index] = p; break; case REALLOC: /* mm_realloc */ index = trace->ops[i].index; newsize = trace->ops[i].size; oldp = trace->blocks[index]; if ((newp = mm_realloc(oldp,newsize)) == NULL) app_error("mm_realloc error in eval_mm_speed"); trace->blocks[index] = newp; break; case FREE: /* mm_free */ index = trace->ops[i].index; block = trace->blocks[index]; mm_free(block); break; default: app_error("Nonexistent request type in eval_mm_valid"); } }
/* * eval_mm_util - Evaluate the space utilization of the student's package * The idea is to remember the high water mark "hwm" of the heap for * an optimal allocator, i.e., no gaps and no internal fragmentation. * Utilization is the ratio hwm/heapsize, where heapsize is the * size of the heap in bytes after running the student's malloc * package on the trace. Note that our implementation of mem_sbrk() * doesn't allow the students to decrement the brk pointer, so brk * is always the high water mark of the heap. * */ static double eval_mm_util(trace_t *trace, int tracenum, range_t **ranges) { assert((int)tracenum || 1); assert((int)ranges || 1); int i; int index; int size, newsize, oldsize; int max_total_size = 0; int total_size = 0; char *p; char *newp, *oldp; /* initialize the heap and the mm malloc package */ mem_reset_brk(); if (mm_init() < 0) app_error("mm_init failed in eval_mm_util"); for (i = 0; i < trace->num_ops; i++) { switch (trace->ops[i].type) { case ALLOC: /* mm_alloc */ index = trace->ops[i].index; size = trace->ops[i].size; if ((p = mm_malloc(size)) == NULL) app_error("mm_malloc failed in eval_mm_util"); /* Remember region and size */ trace->blocks[index] = p; trace->block_sizes[index] = size; /* Keep track of current total size * of all allocated blocks */ total_size += size; /* Update statistics */ max_total_size = (total_size > max_total_size) ? total_size : max_total_size; break; case REALLOC: /* mm_realloc */ index = trace->ops[i].index; newsize = trace->ops[i].size; oldsize = trace->block_sizes[index]; oldp = trace->blocks[index]; if ((newp = mm_realloc(oldp,newsize)) == NULL) app_error("mm_realloc failed in eval_mm_util"); /* Remember region and size */ trace->blocks[index] = newp; trace->block_sizes[index] = newsize; /* Keep track of current total size * of all allocated blocks */ total_size += (newsize - oldsize); /* Update statistics */ max_total_size = (total_size > max_total_size) ? total_size : max_total_size; break; case FREE: /* mm_free */ index = trace->ops[i].index; size = trace->block_sizes[index]; p = trace->blocks[index]; mm_free(p); /* Keep track of current total size * of all allocated blocks */ total_size -= size; break; default: app_error("Nonexistent request type in eval_mm_util"); } } return ((double)max_total_size / (double)mem_heapsize()); }
/* * eval_mm_valid - Check the mm malloc package for correctness */ static int eval_mm_valid(trace_t *trace, int tracenum, range_t **ranges) { int i, j; int index; int size; int oldsize; char *newp; char *oldp; char *p; /* Reset the heap and free any records in the range list */ mem_reset_brk(); clear_ranges(ranges); /* Call the mm package's init function */ if (mm_init() < 0) { malloc_error(tracenum, 0, "mm_init failed."); return 0; } /* Interpret each operation in the trace in order */ for (i = 0; i < trace->num_ops; i++) { index = trace->ops[i].index; size = trace->ops[i].size; switch (trace->ops[i].type) { case ALLOC: /* mm_malloc */ /* Call the student's malloc */ if ((p = mm_malloc(size)) == NULL) { malloc_error(tracenum, i, "mm_malloc failed."); return 0; } /* * Test the range of the new block for correctness and add it * to the range list if OK. The block must be be aligned properly, * and must not overlap any currently allocated block. */ if (add_range(ranges, p, size, tracenum, i) == 0) return 0; /* ADDED: cgw * fill range with low byte of index. This will be used later * if we realloc the block and wish to make sure that the old * data was copied to the new block */ memset(p, index & 0xFF, size); /* Remember region */ trace->blocks[index] = p; trace->block_sizes[index] = size; break; case REALLOC: /* mm_realloc */ /* Call the student's realloc */ oldp = trace->blocks[index]; if ((newp = mm_realloc(oldp, size)) == NULL) { malloc_error(tracenum, i, "mm_realloc failed."); return 0; } /* Remove the old region from the range list */ remove_range(ranges, oldp); /* Check new block for correctness and add it to range list */ if (add_range(ranges, newp, size, tracenum, i) == 0) return 0; /* ADDED: cgw * Make sure that the new block contains the data from the old * block and then fill in the new block with the low order byte * of the new index */ oldsize = trace->block_sizes[index]; if (size < oldsize) oldsize = size; for (j = 0; j < oldsize; j++) { if (newp[j] != (index & 0xFF)) { malloc_error(tracenum, i, "mm_realloc did not preserve the " "data from old block"); return 0; } } memset(newp, index & 0xFF, size); /* Remember region */ trace->blocks[index] = newp; trace->block_sizes[index] = size; break; case FREE: /* mm_free */ /* Remove region from list and call student's free function */ p = trace->blocks[index]; remove_range(ranges, p); mm_free(p); break; default: app_error("Nonexistent request type in eval_mm_valid"); } } /* As far as we know, this is a valid malloc package */ return 1; }
// call mem_reset_brk. void allocator::reset_brk() { mem_reset_brk(); }
/* call mem_reset_brk. */ void bad_allocator::reset_brk() { mem_reset_brk() ; }
/* * eval_mm_util - Evaluate the space utilization of the student's package * The idea is to remember the high water mark "hwm" of the heap for * an optimal allocator, i.e., no gaps and no internal fragmentation. * Utilization is the ratio hwm/heapsize, where heapsize is the * size of the heap in bytes after running the student's malloc * package on the trace. * */ static double eval_mm_util(trace_t *trace, int tracenum) { int i; int index; int size, newsize, oldsize; int max_total_size = 0; int total_size = 0; size_t heap_size = 0 ; char *p; char *newp, *oldp; /* initialize the heap and the mm malloc package */ mem_reset_brk(); if (my_impl.init() < 0) { app_error("init failed in eval_mm_util"); } for (i = 0; i < trace->num_ops; i++) { switch (trace->ops[i].type) { case ALLOC: /* alloc */ index = trace->ops[i].index; size = trace->ops[i].size; if ((p = (char *) my_impl.malloc(size)) == NULL) { app_error("malloc failed in eval_mm_util"); } /* Remember region and size */ trace->blocks[index] = p; trace->block_sizes[index] = size; /* Keep track of current total size * of all allocated blocks */ total_size += size; /* Update statistics */ max_total_size = (total_size > max_total_size) ? total_size : max_total_size; break; case REALLOC: /* realloc */ index = trace->ops[i].index; newsize = trace->ops[i].size; oldsize = trace->block_sizes[index]; oldp = trace->blocks[index]; if ((newp = (char *) my_impl.realloc(oldp,newsize)) == NULL) app_error("realloc failed in eval_mm_util"); /* Remember region and size */ trace->blocks[index] = newp; trace->block_sizes[index] = newsize; /* Keep track of current total size * of all allocated blocks */ total_size += (newsize - oldsize); /* Update statistics */ max_total_size = (total_size > max_total_size) ? total_size : max_total_size; break; case FREE: /* free */ index = trace->ops[i].index; size = trace->block_sizes[index]; p = trace->blocks[index]; my_impl.free(p); /* Keep track of current total size * of all allocated blocks */ total_size -= size; break; default: app_error("Nonexistent request type in eval_mm_util"); } } max_total_size = (max_total_size > MEM_ALLOWANCE) ? max_total_size : MEM_ALLOWANCE ; heap_size = mem_heapsize() ; heap_size = (heap_size > MEM_ALLOWANCE) ? heap_size : MEM_ALLOWANCE ; return ((double)max_total_size / (double)heap_size); }