📄 stats.c
字号:
/* * stats.c - statistical package routines * * This file is an adaptation of the software in the SimpleScalar tool suite * originally written by Todd M. Austin for the Multiscalar Research Project * at the University of Wisconsin-Madison. * * The modifications were made by Naraig Manjikian at Queen's University, * Kingston, Ontario, Canada. * * The remainder of this header comment is unchanged from the original text. * *.......................................................................... * * Copyright (C) 1994, 1995, 1996, 1997 by Todd M. Austin * * This source file is distributed "as is" in the hope that it will be * useful. The tool set comes with no warranty, and no author or * distributor accepts any responsibility for the consequences of its * use. * * Everyone is granted permission to copy, modify and redistribute * this tool set under the following conditions: * * This source code is distributed for non-commercial use only. * Please contact the maintainer for restrictions applying to * commercial use. * * Permission is granted to anyone to make or distribute copies * of this source code, either as received or modified, in any * medium, provided that all copyright notices, permission and * nonwarranty notices are preserved, and that the distributor * grants the recipient permission for further redistribution as * permitted by this document. * * Permission is granted to distribute this file in compiled * or executable form under the same conditions that apply for * source code, provided that either: * * A. it is accompanied by the corresponding machine-readable * source code, * B. it is accompanied by a written offer, with no time limit, * to give anyone a machine-readable copy of the corresponding * source code in return for reimbursement of the cost of * distribution. This written offer must permit verbatim * duplication by anyone, or * C. it is distributed by someone who received only the * executable form, and is accompanied by a copy of the * written offer of source code that they received concurrently. * * In other words, you are welcome to use, share and improve this * source file. You are forbidden to forbid anyone else to use, share * and improve what you give them. * * INTERNET: dburger@cs.wisc.edu * US Mail: 1210 W. Dayton Street, Madison, WI 53706 * * $Id: stats.c,v 1.1 1997/03/11 01:34:15 taustin Exp taustin $ * * $Log: stats.c,v $ * Revision 1.1 1997/03/11 01:34:15 taustin * Initial revision * * */#include <stdio.h>#include <stdlib.h>#include <limits.h>#include <math.h>#include "misc.h"#include "eval.h"#include "stats.h"/* evaluate a stat as an expression */struct eval_value_tstat_eval_ident(struct eval_state_t *es)/* an expression evaluator */{ struct stat_sdb_t *sdb = es->user_ptr; struct stat_stat_t *stat; static struct eval_value_t err_value = { et_int, { 0 } }; struct eval_value_t val; /* locate the stat variable */ for (stat = sdb->stats; stat != NULL; stat = stat->next) { if (!strcmp(stat->name, es->tok_buf)) { /* found it! */ break; } } if (!stat) { /* could not find stat variable */ eval_error = ERR_UNDEFVAR; return err_value; } /* else, return the value of stat */ /* convert the stat variable value to a typed expression value */ switch (stat->sc) { case sc_int: val.type = et_int; val.value.as_int = *stat->variant.for_int.var; break; case sc_uint: val.type = et_uint; val.value.as_uint = *stat->variant.for_uint.var; break; case sc_uintarray: /* FIXME: just use first element of array in expression */ val.type = et_uint; val.value.as_uint = stat->variant.for_uintarray.var[0]; break;#ifdef __GNUC__ case sc_llong: /* FIXME: cast to double, eval package doesn't support long long's */ val.type = et_double; val.value.as_double = (double)*stat->variant.for_llong.var; break;#endif /* __GNUC__ */ case sc_float: val.type = et_float; val.value.as_float = *stat->variant.for_float.var; break; case sc_double: val.type = et_double; val.value.as_double = *stat->variant.for_double.var; break; case sc_dist: case sc_sdist: fatal("stat distributions not allowed in formula expressions"); break; case sc_formula: { /* instantiate a new evaluator to avoid recursion problems */ struct eval_state_t *es = eval_new(stat_eval_ident, sdb); char *endp; val = eval_expr(es, stat->variant.for_formula.formula, &endp); if (eval_error != ERR_NOERR || *endp != '\0') { /* pass through eval_error */ val = err_value; } /* else, use value returned */ eval_delete(es); } break; default: panic("bogus stat class"); } return val;}/* create a new stats database */struct stat_sdb_t *stat_new(void){ struct stat_sdb_t *sdb; sdb = (struct stat_sdb_t *)calloc(1, sizeof(struct stat_sdb_t)); if (!sdb) fatal("out of virtual memory"); sdb->stats = NULL; sdb->evaluator = eval_new(stat_eval_ident, sdb); return sdb;}/* delete a stats database */voidstat_delete(struct stat_sdb_t *sdb) /* stats database */{ int i; struct stat_stat_t *stat, *stat_next; struct bucket_t *bucket, *bucket_next; /* free all individual stat variables */ for (stat = sdb->stats; stat != NULL; stat = stat_next) { stat_next = stat->next; stat->next = NULL; /* free stat */ switch (stat->sc) { case sc_int: case sc_uint: case sc_uintarray:#ifdef __GNUC__ case sc_llong:#endif /* __GNUC__ */ case sc_float: case sc_double: case sc_formula: /* no other storage to deallocate */ break; case sc_dist: /* free distribution array */ free(stat->variant.for_dist.arr); stat->variant.for_dist.arr = NULL; break; case sc_sdist: /* free all hash table buckets */ for (i=0; i<HTAB_SZ; i++) { for (bucket = stat->variant.for_sdist.sarr[i]; bucket != NULL; bucket = bucket_next) { bucket_next = bucket->next; bucket->next = NULL; free(bucket); } stat->variant.for_sdist.sarr[i] = NULL; } /* free hash table array */ free(stat->variant.for_sdist.sarr); stat->variant.for_sdist.sarr = NULL; break; default: panic("bogus stat class"); } /* free stat variable record */ free(stat); } sdb->stats = NULL; eval_delete(sdb->evaluator); sdb->evaluator = NULL; free(sdb);}/* add stat variable STAT to stat database SDB */static voidadd_stat(struct stat_sdb_t *sdb, /* stat database */ struct stat_stat_t *stat) /* stat variable */{ struct stat_stat_t *elt, *prev; /* append at end of stat database list */ for (prev=NULL, elt=sdb->stats; elt != NULL; prev=elt, elt=elt->next) /* nada */; /* append stat to stats chain */ if (prev != NULL) prev->next = stat; else /* prev == NULL */ sdb->stats = stat; stat->next = NULL;}/* register an integer statistical variable */struct stat_stat_t *stat_reg_int(struct stat_sdb_t *sdb, /* stat database */ char *name, /* stat variable name */ char *desc, /* stat variable description */ int *var, /* stat variable */ int init_val, /* stat variable initial value */ char *format) /* optional variable output format */{ struct stat_stat_t *stat; stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t)); if (!stat) fatal("out of virtual memory"); stat->name = mystrdup(name); stat->desc = mystrdup(desc); stat->format = format ? format : "%12d"; stat->sc = sc_int; stat->variant.for_int.var = var; stat->variant.for_int.init_val = init_val; /* link onto SDB chain */ add_stat(sdb, stat); /* initialize stat */ *var = init_val; return stat;}/* register an unsigned integer statistical variable */struct stat_stat_t *stat_reg_uint(struct stat_sdb_t *sdb, /* stat database */ char *name, /* stat variable name */ char *desc, /* stat variable description */ unsigned int *var, /* stat variable */ unsigned int init_val, /* stat variable initial value */ char *format) /* optional variable output format */{ struct stat_stat_t *stat; stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t)); if (!stat) fatal("out of virtual memory"); stat->name = mystrdup(name); stat->desc = mystrdup(desc); stat->format = format ? format : "%12u"; stat->sc = sc_uint; stat->variant.for_uint.var = var; stat->variant.for_uint.init_val = init_val; /* link onto SDB chain */ add_stat(sdb, stat); /* initialize stat */ *var = init_val; return stat;}/* register an unsigned integer array statistical variable */struct stat_stat_t *stat_reg_uintarray(struct stat_sdb_t *sdb, /* stat database */ char *name, /* stat variable name */ char *desc, /* stat variable description */ unsigned int *var, /* stat variable */ int num_elements, /* number of elements in the array */ int *num_used_ptr, /* pointer to actual number used */ unsigned int init_val, /* stat variable initial value */ char *format) /* optional variable output format */{ struct stat_stat_t *stat; int i; stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t)); if (!stat) fatal("out of virtual memory"); stat->name = mystrdup(name); stat->desc = mystrdup(desc); stat->format = format ? format : "%12u"; stat->sc = sc_uintarray; stat->variant.for_uintarray.var = var; stat->variant.for_uintarray.num_elements = num_elements; stat->variant.for_uintarray.num_used_ptr = num_used_ptr; stat->variant.for_uintarray.init_val = init_val; /* link onto SDB chain */ add_stat(sdb, stat); /* initialize stat by setting all elements of the array to init value */ for (i = 0; i < num_elements; i++) var[i] = init_val; return stat;}#ifdef __GNUC__/* register a long long integer statistical variable */struct stat_stat_t *stat_reg_llong(struct stat_sdb_t *sdb, /* stat database */ char *name, /* stat variable name */ char *desc, /* stat variable description */ long long *var, /* stat variable */ long long init_val, /* stat variable initial value */ char *format) /* optional variable output format */{ struct stat_stat_t *stat; stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t)); if (!stat) fatal("out of virtual memory"); stat->name = mystrdup(name); stat->desc = mystrdup(desc); stat->format = format ? format : "%12.0f"; stat->sc = sc_llong; stat->variant.for_llong.var = var; stat->variant.for_llong.init_val = init_val; /* link onto SDB chain */ add_stat(sdb, stat); /* initialize stat */ *var = init_val; return stat;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -