⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtest.c

📁 ICS 课程的Lab6
💻 C
📖 第 1 页 / 共 2 页
字号:
	    trace->ops[op_index].type = ALLOC;	    trace->ops[op_index].index = index;	    trace->ops[op_index].size = size;	    max_index = (index > max_index) ? index : max_index;	    break;	case 'r':	    fscanf(tracefile, "%u %u", &index, &size);	    trace->ops[op_index].type = REALLOC;	    trace->ops[op_index].index = index;	    trace->ops[op_index].size = size;	    max_index = (index > max_index) ? index : max_index;	    break;	case 'f':	    fscanf(tracefile, "%ud", &index);	    trace->ops[op_index].type = FREE;	    trace->ops[op_index].index = index;	    break;	default:	    printf("Bogus type character (%c) in tracefile %s\n", 		   type[0], filename);	    exit(1);	}	op_index++;	    }    fclose(tracefile);    assert(max_index == trace->num_ids - 1);    assert(trace->num_ops == op_index);        return trace;}/* * free_trace - Free the trace record and the three arrays it points *              to, all of which were allocated in read_trace(). */void free_trace(trace_t *trace){    free(trace->ops);         /* free the three arrays... */    free(trace->blocks);          free(trace->block_sizes);    free(trace);              /* and the trace record itself... */}/********************************************************************** * The following functions evaluate the correctness, space utilization, * and throughput of the libc and mm malloc packages. **********************************************************************//* * 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;}/*  * 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){       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_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_libc_valid - We run this function to make sure that the *    libc malloc can run to completion on the set of traces. *    We'll be conservative and terminate if any libc malloc call fails. * */static int eval_libc_valid(trace_t *trace, int tracenum){    int i, newsize;    char *p, *newp, *oldp;    for (i = 0;  i < trace->num_ops;  i++) {        switch (trace->ops[i].type) {        case ALLOC: /* malloc */	    if ((p = malloc(trace->ops[i].size)) == NULL) {		malloc_error(tracenum, i, "libc malloc failed");		unix_error("System message");	    }	    trace->blocks[trace->ops[i].index] = p;	    break;	case REALLOC: /* realloc */            newsize = trace->ops[i].size;	    oldp = trace->blocks[trace->ops[i].index];	    if ((newp = realloc(oldp, newsize)) == NULL) {		malloc_error(tracenum, i, "libc realloc failed");		unix_error("System message");	    }	    trace->blocks[trace->ops[i].index] = newp;	    break;	            case FREE: /* free */	    free(trace->blocks[trace->ops[i].index]);	    break;	default:	    app_error("invalid operation type  in eval_libc_valid");	}    }    return 1;}/*  * eval_libc_speed - This is the function that is used by fcyc() to *    measure the running time of the libc malloc package on the set *    of traces. */static void eval_libc_speed(void *ptr){    int i;    int index, size, newsize;    char *p, *newp, *oldp, *block;    trace_t *trace = ((speed_t *)ptr)->trace;    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 = malloc(size)) == NULL)		unix_error("malloc failed in eval_libc_speed");	    trace->blocks[index] = p;	    break;	case REALLOC: /* realloc */	    index = trace->ops[i].index;	    newsize = trace->ops[i].size;	    oldp = trace->blocks[index];	    if ((newp = realloc(oldp, newsize)) == NULL)		unix_error("realloc failed in eval_libc_speed\n");	    	    trace->blocks[index] = newp;	    break;	            case FREE: /* free */	    index = trace->ops[i].index;	    block = trace->blocks[index];	    free(block);	    break;	}    }}/************************************* * Some miscellaneous helper routines ************************************//* * printresults - prints a performance summary for some malloc package */static void printresults(int n, stats_t *stats) {    int i;    double secs = 0;    double ops = 0;    double util = 0;    /* Print the individual results for each trace */    printf("%5s%7s %5s%8s%10s%6s\n", 	   "trace", " valid", "util", "ops", "secs", "Kops");    for (i=0; i < n; i++) {	if (stats[i].valid) {	    printf("%2d%10s%5.0f%%%8.0f%10.6f%6.0f\n", 		   i,		   "yes",		   stats[i].util*100.0,		   stats[i].ops,		   stats[i].secs,		   (stats[i].ops/1e3)/stats[i].secs);	    secs += stats[i].secs;	    ops += stats[i].ops;	    util += stats[i].util;	}	else {	    printf("%2d%10s%6s%8s%10s%6s\n", 		   i,		   "no",		   "-",		   "-",		   "-",		   "-");	}    }    /* Print the aggregate results for the set of traces */    if (errors == 0) {	printf("%12s%5.0f%%%8.0f%10.6f%6.0f\n", 	       "Total       ",	       (util/n)*100.0,	       ops, 	       secs,	       (ops/1e3)/secs);    }    else {	printf("%12s%6s%8s%10s%6s\n", 	       "Total       ",	       "-", 	       "-", 	       "-", 	       "-");    }}/*  * app_error - Report an arbitrary application error */void app_error(char *msg) {    printf("%s\n", msg);    exit(1);}/*  * unix_error - Report a Unix-style error */void unix_error(char *msg) {    printf("%s: %s\n", msg, strerror(errno));    exit(1);}/* * malloc_error - Report an error returned by the mm_malloc package */void malloc_error(int tracenum, int opnum, char *msg){    errors++;    printf("ERROR [trace %d, line %d]: %s\n", tracenum, LINENUM(opnum), msg);}/*  * usage - Explain the command line arguments */static void usage(void) {    fprintf(stderr, "Usage: mtest [-hvVal] [-f <file>]\n");    fprintf(stderr, "Options\n");    fprintf(stderr, "\t-a         Don't check the team structure.\n");    fprintf(stderr, "\t-f <file>  Use <file> as the trace file.\n");    fprintf(stderr, "\t-h         Print this message.\n");    fprintf(stderr, "\t-l         Run libc malloc as well.\n");    fprintf(stderr, "\t-v         Print per-trace performance breakdowns.\n");    fprintf(stderr, "\t-V         Print additional debug info.\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -