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

📄 selectors.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.  * *//******************************************************************* * Tcl interface to selectors *******************************************************************/#include <stdio.h>#include <stdlib.h>#include "tcl_init.h"#include "simtypes.h"#include "simutil.h"#include "statrecord.h"#include "sim_error.h"#include "syslimits.h"#include "string.h"#define CHECK_SEL(sel, selName)    \   selName = argv[2];              \   sel = SelLookup(selName);       \   if (sel == NULL) {              \      Tcl_AppendResult(interp, "no selector named \"", selName, "\"", NULL);   \      return TCL_ERROR;            \   }                         typedef struct SelCmd SelCmd;typedef struct Selector Selector;struct Selector {   char *name;   Tcl_HashTable buckets;   StatRecordSwitch *simosSwitch;};   static void SelSetBucket(Selector *sel, int cpuNum, char *bucketName);static Selector *SelLookup(char *name);static int cmdCreate(Tcl_Interp *interp, int argc, char *argv[]);static int cmdSet(Tcl_Interp *interp, int argc, char *argv[]);static int cmdDisable(Tcl_Interp *interp, int argc, char *argv[]);/* Got rid of dump--done through tcl manipulation of primitives *//*static int cmdDump(Tcl_Interp *interp, int argc, char *argv[]); */static int cmdGetData(Tcl_Interp *interp, int argc, char *argv[]);static int cmdForEach(Tcl_Interp *interp, int argc, char *argv[]);static int cmdGetFields(Tcl_Interp *interp, int argc, char *argv[]);static tclcmd selCmds[] = {{  "create",      3, cmdCreate,      " create selName"}, {   "set",         5, cmdSet,         " set selName cpuNum bucketName"},/*{ "dump",       -1, cmdDump,        " dump selName ?(filename|log)?"}, */{   "getData",    -1, cmdGetData,     " getdata selName bucketName ?fieldList?"},{   "foreach",     5, cmdForEach,     " foreach selName {bname} {script}"},{   "getFields",   3, cmdGetFields,   " getfields selName"},{   "disable",     3, cmdDisable,     " disable cpuNum"},{   NULL,          0, NULL,           NULL}};static Tcl_HashTable selectors;void SelectorInit(Tcl_Interp *interp) {   Tcl_InitHashTable(&selectors, TCL_STRING_KEYS);   Tcl_CreateCommand(interp, "selector", DispatchCmd, (ClientData) selCmds, NULL);}   int cmdCreate(Tcl_Interp *interp, int argc, char *argv[]) {   Selector *sel;   char *selName;   int i;   Tcl_HashEntry *entry;   int new;   selName = argv[2];   entry = Tcl_CreateHashEntry(&selectors, selName, &new);   if (!new) {      Tcl_AppendResult(interp, "selector name already taken \"", selName, "\"", NULL);      return TCL_ERROR;   }   sel = (Selector *) ZMALLOC(sizeof(Selector), "selectorcmdCreate");   /* Each selector keeps track of its buckets. */   sel->name = Tcl_GetHashKey(&selectors, entry);   Tcl_InitHashTable(&(sel->buckets), TCL_STRING_KEYS);   /* Now create the selector (switch in statrecord land) */   sel->simosSwitch = StatRecordNewSwitch(selName);   /* Initialize the selector to point to trash for all cpus.*/   for (i = 0; i < SIM_MAXCPUS; i++) {      SelSetBucket(sel, i, "trash");   }   Tcl_SetHashValue(entry, sel);   return TCL_OK;}int cmdSet(Tcl_Interp *interp, int argc, char *argv[]) {      Selector *sel;   char *selName;   int cpuNum;   CHECK_SEL(sel,selName);   if (Tcl_GetInt(interp, argv[3], &cpuNum) != TCL_OK) {      Tcl_AppendResult(interp, "bad cpunum \"", argv[3], "\"", NULL);      return TCL_ERROR;   }       SelSetBucket(sel, cpuNum, argv[4]);   return TCL_OK;}/* Return list of fields & values for the given bucket.  If no field list   argument is given, returns a list of all fields. <<What was supposed to happen   for an empty list?>>.   Lists are in this form:   {fieldName fieldValue fieldName fieldValue .....}*/int cmdGetData(Tcl_Interp *interp, int argc, char *argv[]) {   Selector *sel;   char *selName;   StatRecordBucket *bucket;   Tcl_HashEntry *entry;   CHECK_SEL(sel, selName);   if (argc != 4 && argc != 5) {      Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], selCmds[3].usage,                       "\"", NULL);      return TCL_ERROR;   }      entry = Tcl_FindHashEntry(&sel->buckets, argv[3]);      if (entry == NULL) {      Tcl_AppendResult(interp, "no bucket named \"", argv[3], "\" in this selector", NULL);      return TCL_ERROR;   }   bucket = (StatRecordBucket*) Tcl_GetHashValue(entry);   if (argc == 5) {      /* Process field list */      int listArgc;      char **listArgv;      int i;      if (Tcl_SplitList(interp, argv[4], &listArgc, &listArgv) != TCL_OK) {         Tcl_AppendResult(interp, "can't parse field list", NULL);         return TCL_ERROR;      }      /* Create a list with the appropriate field values. For now,         we don't every display the field names.  The available field         names should be made available through some other mechanism.      */      for (i = 0; i < listArgc; i++) {         char buf[50];         PrintLLD(buf,StatRecordFieldValue(bucket, listArgv[i]));         Tcl_AppendElement(interp, buf);      }            free((char*) listArgv);   } else {      int i, j;      /* Otherwise, enumerate all fields and values */      j = StatRecordNumFields();      for (i = 0; i < j; i++) {         char buf[50];         PrintLLD(buf, StatRecordFieldValueByIndex(bucket, i));         Tcl_AppendElement(interp, buf);      }   }   return TCL_OK;}/* Iterate through all of the buckets, calling the associated script   with the given name. Scott did you ever figure out how to put   this stuff in a separate function? */int cmdForEach(Tcl_Interp *interp, int argc, char *argv[]) {   Selector *sel;   char *selName;   Tcl_HashEntry *entryPtr;   Tcl_HashSearch search;   int listArgc;   char **listArgv;   CHECK_SEL(sel, selName);   if (Tcl_SplitList(interp, argv[3], &listArgc, &listArgv) != TCL_OK ||       listArgc != 1) {      Tcl_AppendResult(interp, "can't parse arg list", NULL);      return TCL_ERROR;   }   /* Currently we don't create a new function. Scott what was the decision      here?    */   for (entryPtr = Tcl_FirstHashEntry(&sel->buckets, &search);        entryPtr != NULL;        entryPtr = Tcl_NextHashEntry(&search)) {      /* Set the current value ... */      if (Tcl_SetVar(interp, listArgv[0], Tcl_GetHashKey(&sel->buckets, entryPtr),0)           == NULL) {         Tcl_AppendResult(interp, "Error in bucket enumeration", NULL);         return TCL_ERROR;      }            /* and evaluate! */      Tcl_Eval(interp, argv[4]);   }   return TCL_OK;}/* return a list of the statrecord fields used for the givenbucket.  Currently, it's all of them.*/int cmdGetFields(Tcl_Interp *interp, int argc, char *argv[]) {   Selector *sel;   char *selName;   int i,j;   CHECK_SEL(sel, selName);   j = StatRecordNumFields();   for (i = 0; i < j; i++) {      Tcl_AppendElement(interp, StatRecordGetFieldName(i));   }   return TCL_OK;}      int cmdDisable(Tcl_Interp *interp, int argc, char *argv[]) {      int cpuNum;   if (Tcl_GetInt(interp, argv[2], &cpuNum) != TCL_OK) {      Tcl_AppendResult(interp, "bad cpunum \"", argv[3], "\"", NULL);      return TCL_ERROR;   }   StatRecordDisableCPU(cpuNum);   return TCL_OK;}/* Set the given selector to the given bucketName.   Allocate the bucket if needed.*/   void SelSetBucket(Selector *sel, int cpuNum, char *bucketName) {   StatRecordBucket *bucket;   Tcl_HashEntry *entry = Tcl_FindHashEntry(&sel->buckets, bucketName);   if (entry) {      bucket = (StatRecordBucket*) Tcl_GetHashValue(entry);      ASSERT(bucket);   } else {      int newval;      entry  = Tcl_CreateHashEntry(&sel->buckets, bucketName, &newval);      ASSERT(newval);      bucket = StatRecordNewBucket();      Tcl_SetHashValue(entry, bucket);   }   StatRecordSetSwitch(sel->simosSwitch, cpuNum, bucket);}Selector *SelLookup(char *name) {   Tcl_HashEntry *entry;   entry = Tcl_FindHashEntry(&selectors, name);         if (entry == NULL) {      return NULL;   }   return (Selector*) Tcl_GetHashValue(entry);}

⌨️ 快捷键说明

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