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

📄 cluster.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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.  * *//************************************************************************** * $File$ *  * $Author: bosch $ * $Date: 1998/02/10 00:36:55 $ *************************************************************************/#include <fcntl.h>#include <sys/types.h>#include <sys/mman.h>#include <sys/uio.h>#include <string.h>#ifdef sgi#include <sys/sysmp.h>#include <netinet/if_ether.h>#endif#include <unistd.h>#include <stdio.h>#include <stdlib.h>#ifndef i386#include <netinet/in.h>#endif#include <sys/types.h>#include <unistd.h>#include "cpu_interface.h" #include "eventcallback.h"#include "cluster.h"#include "ethernet.h"#include "sim_error.h"#include "simrecord.h"#include "simutil.h"#include "arch_specifics.h"#if 0 #if defined(SIM_MIPS32) || defined(SIM_MIPS64)# include "../../cpus/mipsy/mipsy_simos.h"# include "../../cpus/simos/startup.h"# include "../../cpus/simos/simmisc.h"   #endif#endif#if defined(SIM_X86)# include "../../cpus-x86/simos/startup.h"# include "../../cpus-x86/simos/simmisc.h"   #endif#include "params.h"#include "machine_params.h"#define CLUSTER_MAX_MSGS 128typedef int MessageId; typedef struct Message {   MessageId msgId;     MessageId next;    int len;    int source, dest,if_num;    int id;    SimTime sendTime, deliverTime;    char data[SIMETHER_MAX_TRANSFER_SIZE];} Message;/* ********************************************************* * ClusterArea * shared between the different hosts in the cluster simulation * !!!! can be mapped at different addresses in the different * processes. Do not have pointers in the structure. That * is why we use indices throughout the code (unfortunately). * *********************************************************/typedef struct ClusterArea {   char    barrierArea[256];   char    commonLock[256];   int     numInit;   int     numParticipants;   MessageId freeList;   int     numMsgsUsed;   int     msgCounter;   int   barrierSync;   struct HostArea{      struct {          char etheraddr[6];         char padding[2];      } etherAddr[ETHER_MAX_CONTROLLERS];      char privateLock[128];      SimTime currentBarrier;      SimTime nextBarrier;      SimTime close;      SimTime cycleCount;      SimTime barrierInterval;      int cpuClock;       int pid;      int hostCPU;      MessageId head;      int     doCheckpoint;   } simul[32];   Message msgPool[CLUSTER_MAX_MSGS];} ClusterArea;ClusterArea *clusterArea = 0;struct HostArea *myArea;static EventCallbackHdr barrierCallback;static EventCallbackHdr receiveMsgCallback;static int barrierMyNum;static char *filename = NULL;static int barrierP = 1;static int barrierNumSimul = 0;static int barrierInterval = 40000;static int clusterLatency = 100;static int slaveCheckpoint = 0;#ifdef notdef#define LOCK_CLUSTER()   (Simcp0Lock  ((int*)clusterArea->commonLock))#define UNLOCK_CLUSTER() (Simcp0Unlock((int*)clusterArea->commonLock))#define LOCK_HOST(_id)   (Simcp0Lock  ((int*)clusterArea->simul[_id].privateLock))#define UNLOCK_HOST(_id) (Simcp0Unlock((int*)clusterArea->simul[_id].privateLock))#else#define LOCK_CLUSTER()   #define UNLOCK_CLUSTER() #define LOCK_HOST(_id)   #define UNLOCK_HOST(_id) #endifstatic void     ClusterFreeMsg(Message *msg);static Message* GetMsg(SimTime now) ;#ifdef sgistatic void     SendMsg(int cpuNum,Message *msg, int receiver);static Message *ClusterAllocMsg(void);#endifvoid DeliverMsgCallback(int cpuNum,EventCallbackHdr *hdr,void *arg){   Message *msg = (Message *) arg;      LogEntry("CLUSTER-RCV",cpuNum,"sender=%i id=%i latency=%10lld len=%i\n",            msg->source,msg->id,(uint64)CPUVec.CycleCount(cpuNum)-msg->sendTime,            msg->len);   ASSERT( PTR_TO_UINT64(msg) <            PTR_TO_UINT64(&clusterArea->msgPool[clusterArea->numMsgsUsed]));      SimetherReceivePacket(msg->if_num, msg->data,msg->len);   ClusterFreeMsg(msg);   msg = GetMsg( CPUVec.CycleCount(cpuNum));   if (msg) {       if (msg->deliverTime <  CPUVec.CycleCount(cpuNum)           && (clusterLatency  > myArea->barrierInterval)) {          CPUWarning("Cluster: delivering msg at %lld when received at %lld  lat=%lld\n",                    (uint64)CPUVec.CycleCount(cpuNum), msg->deliverTime,                    (uint64) CPUVec.CycleCount(cpuNum) - msg->deliverTime);         EventDoCallback(cpuNum,DeliverMsgCallback,&receiveMsgCallback,                         (void*)msg, 0);      } else {          EventDoCallback(cpuNum,DeliverMsgCallback,&receiveMsgCallback,                         (void*)msg,                         msg->deliverTime -  CPUVec.CycleCount(cpuNum));      }   }}    /* This is called at regular intervalls. The simulation completes when * one simulator sets syncArea->close to its nextBarrier field. * At this time, the requesting process is already draining its remaining * events. All other ones are still in their normal processing.  */void BarrierCallback(int cpuNum,EventCallbackHdr *hdr,void *arg){   ASSERT( hdr ==  &barrierCallback );   ASSERT( cpuNum == 0 );   ASSERT( myArea->nextBarrier <= CPUVec.CycleCount(cpuNum) );   if( myArea->close && myArea->close < myArea->nextBarrier ) {      /* someone else has already requested the last barrier. Time       * to leave       */      CPUWarning("%lld Passed final barrier already! close=%lld\n",               (uint64)CPUVec.CycleCount(cpuNum),               (uint64)myArea->close);      return;    }   if( myArea->close )       CPUPrint("Barrier synching at %lld close=%lld\n",               (uint64)CPUVec.CycleCount(cpuNum),               (uint64)myArea->close);#ifdef notdef   /*    * Barrier     */   if( clusterArea->barrierSync ) {       Simcp0Asm_Barrier((int *)&clusterArea->barrierArea[0],barrierNumSimul);   }#endif   myArea->currentBarrier = myArea->nextBarrier;    myArea->nextBarrier  +=  myArea->barrierInterval;   myArea->cycleCount =  CPUVec.CycleCount(cpuNum);#ifdef notdef   /* 2nd barrier: needed or danger of a race condition */   if( clusterArea->barrierSync ) {       Simcp0Asm_Barrier((int *)&clusterArea->barrierArea[0],barrierNumSimul);   }#endif   if( myArea->close  ) {      CPUPrint("Cluster: Final barrier passed at %lld close=%lld\n",               (uint64)CPUVec.CycleCount(cpuNum),               (uint64)myArea->close);             /*       * go back to base mode, simulate a /bdoor/cpuEnter b       */      CPUVec.ExitSimulator(sim_misc.enterThisCPU);      return;   }        /*     * debug cycleCount differences      */    if (barrierMyNum && clusterArea->barrierSync ) {       int diff = myArea->cycleCount - clusterArea->simul[0].cycleCount;      int diff2 = CPUVec.CycleCount(cpuNum) - clusterArea->simul[0].cycleCount;      if (diff < 0)  diff = -diff;      if (diff2 < 0) diff2 = -diff2;      if (diff  > 2*myArea->barrierInterval ||           diff2 > 2*myArea->barrierInterval ) {        CPUWarning("%10lld Cycle count diff=%i diff2=%i  when interval is %i \n",                   (uint64)myArea->cycleCount,diff,diff2,                   myArea->barrierInterval);      }    }         /*     * Get received messages     */   if( !receiveMsgCallback.active ) {       Message *msg = GetMsg( CPUVec.CycleCount(cpuNum));       if( msg ) {            if( msg->deliverTime <  CPUVec.CycleCount(cpuNum) &&                clusterLatency > myArea->barrierInterval ) {                CPUWarning("Cluster: delivering msg at %lld when received at %lld\n",                          (uint64)CPUVec.CycleCount(cpuNum),                           msg->deliverTime);               EventDoCallback(cpuNum,DeliverMsgCallback,                               &receiveMsgCallback,(void*)msg, 0);           } else {                EventDoCallback(cpuNum,DeliverMsgCallback,                               &receiveMsgCallback,(void*)msg,                                msg->deliverTime -                                 CPUVec.CycleCount(cpuNum));           }       }   }   /*     * checkpoint ?     */   if (myArea->doCheckpoint ) {     slaveCheckpoint = 1;     if( sim_misc.myCPUType == EMBRA_PAGE ||          sim_misc.myCPUType == EMBRA_CACHE ) {         ASSERT( CPUVec.DoCheckpoint );        CPUVec.DoCheckpoint(0);        myArea->doCheckpoint = 0;     }      slaveCheckpoint = 0;   }    /*     * reinstall event     */   if( myArea->cycleCount < myArea->nextBarrier ) {      EventDoCallback(cpuNum,BarrierCallback,&barrierCallback,(void*)0,                     myArea->nextBarrier - myArea->cycleCount );   } else {      EventDoCallback(cpuNum,BarrierCallback,&barrierCallback,(void*)0,0);   }}void ClusterTclInit(Tcl_Interp *interp){   filename = NULL;   ParamRegister("PARAM(CLUSTER.File)", (char *)&filename, PARAM_STRING);      ParamRegister("PARAM(CLUSTER.Interval)",               (char *)&barrierInterval, PARAM_INT);      ParamRegister("PARAM(CLUSTER.NumSimul)",               (char *)&barrierNumSimul, PARAM_INT);      ParamRegister("PARAM(CLUSTER.Latency)",               (char *)&clusterLatency, PARAM_INT);      ParamRegister("PARAM(CLUSTER.Barrier)",               (char *)&barrierP, PARAM_BOOLEAN);}void ClusterInit(void){   int fd,i;   int pid = getpid();   int pagesize = getpagesize();   int size = (sizeof(ClusterArea) + pagesize-1) & ~(pagesize-1);   int myHostCPU;   unsigned long addr;   if( clusterArea ) {       CPUWarning("CLUSTER: already initialized\n");       return;   }   if( !strcmp(filename,"") )      return;      fd = open(filename,O_RDWR,0);   if( fd < 0 )      CPUError("Could not open file '%s' read-write\n",filename);   lseek(fd,size,SEEK_CUR);  /* grow the file */   write(fd,"xxxx",4);

⌨️ 快捷键说明

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