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

📄 statistics.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * */#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <math.h>#include <float.h>#include "simtypes.h"#include "sim_error.h"#include "simutil.h" #include "annotations.h"#include "cpu_interface.h"#include "statistics.h"#include "tcl_init.h"#define MIN(_x, _y)  (((_x) < (_y)) ? (_x) : (_y))#define MAX(_x, _y)  (((_x) > (_y)) ? (_x) : (_y))#define MAX_STATS_STRLEN 64static Tcl_HashTable names;static int cmdCreate(Tcl_Interp *interp, int argc, char *argv[]);static int cmdEntry(Tcl_Interp *interp, int argc, char *argv[]);static int cmdList(Tcl_Interp *interp, int argc, char *argv[]);static int cmdReset(Tcl_Interp *interp, int argc, char *argv[]);static void StatsReset(Stats *stat);static tclcmd statCmds[] = {{   "create",      -1, cmdCreate,      " create name ?numbuckets minval incr?"},{   "entry",       -1, cmdEntry,       " entry name x ?y?"},{   "list",        -1, cmdList,        " list ?name?"},{   "reset",       -1, cmdReset,       " reset name"},{   NULL,           0, NULL,           NULL}};void StatisticsInit(Tcl_Interp *interp){   Tcl_InitHashTable(&names, TCL_STRING_KEYS);   Tcl_CreateCommand(interp, "statistics", DispatchCmd, (ClientData)statCmds, NULL);   }int cmdCreate(Tcl_Interp *interp, int argc, char *argv[]){   Stats *stat;   char *name;   Tcl_HashEntry *entry;   int new = 0;   int code;   int numb;   double minval, incr;      if (argc == 3) {      numb = 0;      minval = 0.0;      incr = 0.0;   } else if (argc == 6) {      if ((code = Tcl_GetInt(interp, argv[3], &numb)) != TCL_OK) {         return code;      }      if ((code = Tcl_GetDouble(interp, argv[4], &minval)) != TCL_OK) {         Tcl_AppendResult(interp, "bad arg 3: should be int", NULL);         return code;      }       if ((code = Tcl_GetDouble(interp, argv[5], &incr)) != TCL_OK) {         Tcl_AppendResult(interp, "bad arg 3: should be int", NULL);         return code;      }    } else {      Tcl_AppendResult(interp, "wrong # args: should be \"",                       argv[0], statCmds[0].usage, "\"", NULL);      return TCL_ERROR;   }   name = argv[2];   entry = Tcl_CreateHashEntry(&names, name, &new);      if (!new) {      Tcl_AppendResult(interp, "stat name already taken \"",                       name, "\"", NULL);      return TCL_ERROR;   }   stat = StatsCreate(numb, minval, incr);   Tcl_SetHashValue(entry, stat);      return TCL_OK;}int cmdEntry(Tcl_Interp *interp, int argc, char *argv[]){   Stats *stat;   char *name;   Tcl_HashEntry *entry;   double x, y = 1.0;   int new = 0;      if ((argc != 4) && (argc != 5)) {      Tcl_AppendResult(interp, "wrong # args: should be \"",                       argv[0], statCmds[1].usage, "\"", NULL);      return TCL_ERROR;   }      name = argv[2];   entry = Tcl_FindHashEntry(&names, name);      if (!entry) {      entry = Tcl_CreateHashEntry(&names, name, &new);      stat = StatsCreate(0, 0, 0);      Tcl_SetHashValue(entry, stat);   }   if (Tcl_GetDouble(interp, argv[3], &x) != TCL_OK) {      Tcl_AppendResult(interp, "expected a double: \"", argv[3], "\"", NULL);      return TCL_ERROR;   }   if ((argc == 5)       && (Tcl_GetDouble(interp, argv[4], &y) != TCL_OK)) {      Tcl_AppendResult(interp, "expected a double: \"", argv[4], "\"", NULL);      return TCL_ERROR;   }      stat = (Stats *)Tcl_GetHashValue(entry);   StatsEntry(stat, x, y);      return TCL_OK;}int cmdReset(Tcl_Interp *interp, int argc, char *argv[]){   Stats *stat;   char *name;   Tcl_HashEntry *entry;   int new = 0;      if (argc != 3) {      Tcl_AppendResult(interp, "wrong # args: should be \"",                       argv[0], statCmds[3].usage, "\"", NULL);      return TCL_ERROR;   }      name = argv[2];   entry = Tcl_FindHashEntry(&names, name);      if (!entry) {      entry = Tcl_CreateHashEntry(&names, name, &new);      stat = StatsCreate(0, 0, 0);      Tcl_SetHashValue(entry, stat);   }   stat = (Stats *)Tcl_GetHashValue(entry);   StatsReset(stat);      return TCL_OK;}static voidStatsPrintTcl(Tcl_Interp *interp, Stats *stat){   char buf[MAX_STATS_STRLEN];   int i;      sprintf(buf, "n %d ", stat->num);   Tcl_AppendResult(interp, buf, NULL);   sprintf(buf, "sumX %.3f ", stat->sumX);   Tcl_AppendResult(interp, buf, NULL);   sprintf(buf, "sumY %.3f ", stat->sumY);   Tcl_AppendResult(interp, buf, NULL);   sprintf(buf, "sumXX %.3f ", stat->sumXsq);   Tcl_AppendResult(interp, buf, NULL);   sprintf(buf, "sumYY %.3f ", stat->sumYsq);   Tcl_AppendResult(interp, buf, NULL);   sprintf(buf, "sumXY %.3f ", stat->sumXY);   Tcl_AppendResult(interp, buf, NULL);   if (stat->minX == DBL_MAX) {      Tcl_AppendResult(interp, "minX NA ", NULL);   } else {      sprintf(buf, "minX %.3f ", stat->minX);      Tcl_AppendResult(interp, buf, NULL);   }      if (stat->maxX == -DBL_MAX) {      Tcl_AppendResult(interp, "maxX NA ", NULL);   } else {      sprintf(buf, "maxX %.3f ", stat->maxX);      Tcl_AppendResult(interp, buf, NULL);   }   if (stat->minY == DBL_MAX) {      Tcl_AppendResult(interp, "minY NA ", NULL);   } else {      sprintf(buf, "minY %.3f ", stat->minY);      Tcl_AppendResult(interp, buf, NULL);   }   if (stat->maxY == -DBL_MAX) {      Tcl_AppendResult(interp, "maxY NA ", NULL);   } else {      sprintf(buf, "maxY %.3f ", stat->maxY);      Tcl_AppendResult(interp, buf, NULL);   }   if (stat->numBuckets) {      sprintf(buf, "numbucket %d ", stat->numBuckets);      Tcl_AppendResult(interp, buf, NULL);      sprintf(buf, "minval %.3f ", stat->minVal);      Tcl_AppendResult(interp, buf, NULL);      sprintf(buf, "incr %.3f ", stat->increment);      Tcl_AppendResult(interp, buf, "buckets", NULL);      for (i=0; i<(stat->numBuckets+2); i++) {         sprintf(buf, "%.3f ", stat->buckets[i]);         Tcl_AppendResult(interp, buf, NULL);      }   }}   int cmdList(Tcl_Interp *interp, int argc, char *argv[]){   Stats *stat;   char *name;   Tcl_HashEntry *entry;   if (argc < 2 && argc > 3) {      Tcl_AppendResult(interp, "wrong # args: should be \"",                       argv[0], statCmds[2].usage, "\"", NULL);      return TCL_ERROR;   }      if (argc == 2) {      Tcl_HashSearch search;      for (entry = Tcl_FirstHashEntry(&names,&search);           entry != NULL;           entry = Tcl_NextHashEntry(&search)) {         char *name = Tcl_GetHashKey(&names,entry);         Stats *stat = (Stats *)Tcl_GetHashValue(entry);         Tcl_AppendResult(interp, "STATS: ", name, " ", NULL);         StatsPrintTcl(interp,stat);         Tcl_AppendResult(interp, "\n", NULL);      }   } else {      name = argv[2];      entry = Tcl_FindHashEntry(&names, name);            if (!entry) {         Tcl_AppendResult(interp, "statistics \"",                          name, " is not defined\"", NULL);         return TCL_ERROR;      }            stat = (Stats *)Tcl_GetHashValue(entry);      StatsPrintTcl(interp,stat);   }   return TCL_OK;}Stats *StatsCreate(int numBuckets, double minValue, double increment){   Stats *stat = (Stats*)ZMALLOC(sizeof(Stats),"StatsCreate");   ASSERT(stat);   stat->numBuckets = numBuckets;   stat->minVal = minValue;   stat->increment = increment;   if (numBuckets) {      stat->buckets = (double*)ZMALLOC(sizeof(double) * (numBuckets+2),                                       "statsBucket");   } else {      stat->buckets = NULL;   }   StatsReset(stat);   return stat;}static void StatsReset(Stats *stat){   stat->num = 0;   stat->sumX = 0;   stat->sumY = 0;   stat->sumXsq = 0;   stat->sumYsq = 0;   stat->sumXY = 0;   stat->minX = DBL_MAX;   stat->maxX = -DBL_MAX;   stat->minY = DBL_MAX;   stat->maxY = -DBL_MAX;      if (stat->numBuckets) {      int i;      for (i=0; i<stat->numBuckets+2; i++) {         stat->buckets[i] = 0;      }   }}void StatsDestroy(Stats *stat){   ASSERT(stat);   if (stat->numBuckets) {      ASSERT(stat->buckets);      free(stat->buckets);   }   free(stat);}void StatsEntry(Stats *stat, double x, double y){   stat->num++;   stat->sumX += x;   stat->sumY += y;   stat->sumXsq += x*x;   stat->sumYsq += y*y;   stat->sumXY += x*y;   stat->minX = MIN(stat->minX, x);   stat->maxX = MAX(stat->maxX, x);   stat->minY = MIN(stat->minY, y);   stat->maxY = MAX(stat->maxY, y);   if (stat->numBuckets) {      int bnum;            ASSERT(stat->buckets);      if (x < stat->minVal) {         bnum = 0;      } else if (x >= (stat->minVal + (stat->numBuckets * stat->increment))) {         bnum = stat->numBuckets + 1;      } else {         bnum = ((x - stat->minVal) / stat->increment) + 1;      }      ASSERT((bnum >= 0) && (bnum <= (stat->numBuckets+1)));      stat->buckets[bnum] += y;   }}void StatsTransfer(Stats *src, Stats *dest){   int i;      dest->num += src->num;   dest->sumX += src->sumX;   dest->sumY += src->sumY;   dest->sumXsq += src->sumXsq;   dest->sumYsq += src->sumYsq;   dest->minX = MIN(dest->minX, src->minX);   dest->maxX = MAX(dest->maxX, src->maxX);   dest->minY = MIN(dest->minY, src->minY);   dest->maxY = MAX(dest->maxY, src->maxY);   ASSERT(src->numBuckets == dest->numBuckets);   if (dest->numBuckets) {      for (i=0; i<(dest->numBuckets+2); i++) {         dest->buckets[i] += src->buckets[i];      }   }}void StatsList(Stats *stat, char *leader){   int i;   char buf[MAX_STATS_STRLEN];   ASSERT(stat);   sprintf(buf, "n %d\n", stat->num);   Tcl_AppendResult(TCLInterp, buf, NULL);   if (stat->num) {      Tcl_AppendResult(TCLInterp, leader, NULL);      sprintf(buf, "sumX %.2f ", stat->sumX);      Tcl_AppendResult(TCLInterp, buf, NULL);      sprintf(buf, "sumY %.2f ", stat->sumY);      Tcl_AppendResult(TCLInterp, buf, NULL);      sprintf(buf, "sumXX %.2f ", stat->sumXsq);      Tcl_AppendResult(TCLInterp, buf, NULL);      sprintf(buf, "sumYY %.2f ", stat->sumYsq);      Tcl_AppendResult(TCLInterp, buf, NULL);      sprintf(buf, "sumXY %.2f ", stat->sumXY);      Tcl_AppendResult(TCLInterp, buf, NULL);      sprintf(buf, "minX %.2f ", stat->minX);      Tcl_AppendResult(TCLInterp, buf, NULL);      sprintf(buf, "maxX %.2f ", stat->maxX);      Tcl_AppendResult(TCLInterp, buf, NULL);      sprintf(buf, "minY %.2f ", stat->minY);      Tcl_AppendResult(TCLInterp, buf, NULL);      sprintf(buf, "maxY %.2f ", stat->maxY);      Tcl_AppendResult(TCLInterp, buf, NULL);      if (stat->numBuckets) {         sprintf(buf, "numbucket %d ", stat->numBuckets);         Tcl_AppendResult(TCLInterp, buf, NULL);         sprintf(buf, "minval %f ", stat->minVal);         Tcl_AppendResult(TCLInterp, buf, NULL);         sprintf(buf, "incr %f ", stat->increment);         Tcl_AppendResult(TCLInterp, buf, NULL);                  for (i=0; i<(stat->numBuckets+2); i++) {            sprintf(buf, "%.2f ", stat->buckets[i]);            Tcl_AppendResult(TCLInterp, buf, NULL);         }      }      Tcl_AppendResult(TCLInterp, "\n", NULL);   }}

⌨️ 快捷键说明

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