📄 cluster.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. * *//************************************************************************** * $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 + -