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

📄 visual.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.  * *//* *********************************************************** * visual.c  * TCP/IP connection to let SimOS talk to an outside  * visualization process * ***********************************************************//*  Statistics report and control module for simos. *   Creates an independent process (the "control process") that *   responds to requests over a socket asynchronously from the *    simulation itself. * *   The control process also communicates with the simos process. *   Currently this is used to do real-time statisitics reporting. *   This could be easily adapting to adding a control interface *   to simos to, for example, change cpu simulators during a *   simulation. */#include <sys/types.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <netdb.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/types.h>#include <sys/time.h>#include "visual.h"#include "sim_error.h"#include "eventcallback.h"#include "cpu_interface.h"#include "gdb_interface.h"#include "simutil.h"#include "tcl_init.h"#include "machine_params.h"extern int getdtablesize(void);#define VISUAL_MAXCONN 4#define VISUAL_MAXSTREAM 8#define MINBUFFER_SIZE (16 * 1024)typedef struct {   char name[64];   int sd; /* socket */} VisualStream;static struct VisualState {   int maxId;   int listenSD;   EventCallbackHdr eventCB;   int context;   struct Connection {       char *host;      int port;      int sd;     /* socket */      VisualStream stream[VISUAL_MAXSTREAM];      int id;      int bufSize;      char *buf;      int pos;   } conn[ VISUAL_MAXCONN];} visualState;static void VisualCallback( int cpuNum, EventCallbackHdr *hdr, void *arg);static bool VisualControl (void) ;static int PushString(int sd,char *string);int VisualPort = 0;int VisualSamplePeriod = 50000; /* PZ */int pauseSimulation = FALSE;static struct Connection *VisualGetConnection(void);static int VisualOpenStream(char *name, char *hostname, int portnumber);static int VisualCloseStream(char *name);int VisualOpenCmd(Tcl_Interp *interp, int argc, char *argv[]);int VisualPutsCmd(Tcl_Interp *interp, int argc, char *argv[]);int VisualCloseCmd(Tcl_Interp *interp, int argc, char *argv[]);static tclcmd visualCmds[] = {   {   "open",        5, VisualOpenCmd,      " open name host port"},   {   "close",       3, VisualCloseCmd,     " close name"},   {   "puts",        4, VisualPutsCmd,      " puts name string"}};/* * VisualInitComm -- To initialize this module, three separate calls *   must be made.  This routine should be called before the control *   process is forked.  After the fork, the simos process should call *   SimCntrl_InitSimComm, and the control process SimCntrl_InitCntrlComm. * *   These calls setup a communication mechanism between the simos and *   control processes, and create a socket to listen for incoming  *   control connections.  The socket address is the first available *   socket with number SIMOS_CNTRL_PORT or greater. * * Return value -- -1 on error, 0 otherwise. */void Visual_Init(void) {     int                isError = 0;   struct sockaddr_in name;   int                portToTry;   bool               foundPort;   visualState.maxId = 1;   visualState.context =  -1;  if (!VisualPort) {     /* CPUWarning("SIMOS: VisualPort not set: -- visual output not enabled  \n"); */     return;  }  if( !isError ) {    visualState.listenSD = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );    if (visualState.listenSD < 0 ) {        perror( "opening request socket" );    }  }  if( !isError ) {    bzero((char *)&name, sizeof(struct sockaddr_in));    name.sin_family      = AF_INET;    name.sin_addr.s_addr = INADDR_ANY;    portToTry            = VisualPort;    foundPort            = FALSE;    ASSERT (portToTry);    do {      name.sin_port = htons( portToTry );      isError = bind(visualState.listenSD , (void*)&name, sizeof(name) );      if( !isError ) {	foundPort = TRUE;	CPUWarning( "SIMOS: visual port: %d\n", portToTry );      } else {	switch( errno ) {          case EADDRNOTAVAIL:          case EADDRINUSE:	    portToTry++;	  break;	  default:	    foundPort = TRUE;	    perror( "bind request socket" );	  break;	}      }    } while( !foundPort );  }  if( !isError ) {    isError = listen( visualState.listenSD, 1 );    if( isError ) {      perror( "listen" );    }  }  /* pauseSimulation -- if true, SimOS stays in VisualControl,     suspending the simulation and accepting Tcl commands from the front end */  Tcl_LinkVar(TCLInterp, "PauseSimulation", (char *) &pauseSimulation,               TCL_LINK_BOOLEAN);  Tcl_CreateCommand(TCLInterp, "visual", DispatchCmd,                    (ClientData)visualCmds, (Tcl_CmdDeleteProc*)NULL);  VisualCallback(0,&visualState.eventCB,0);}static void VisualCallback(int cpuNum, EventCallbackHdr *hdr, void *arg){   bool poll = TRUE;   /* Keep calling VisualControl until it performs no actions --       this allows multiple requests on the same socket to be serviced */   while (poll || pauseSimulation) {      poll = VisualControl();   }   EventDoCallback(cpuNum,VisualCallback,hdr,arg,VisualSamplePeriod);}/* * accept the new connection  */void VisualAccept(int listenPort){   int con;   int in,fromAddrLen;   struct sockaddr_in  fromAddr;   struct hostent     *fromHost;   for(con=0;con<VISUAL_MAXCONN && visualState.conn[con].sd ; con++)       continue;   fromAddrLen  = sizeof( fromAddr );   if (con == VISUAL_MAXCONN ) {       CPUWarning("\nSIMOS: ALREADY HAVE %d visualization connections. Drop this one \n",                   VISUAL_MAXCONN);      return;   }   in = accept( listenPort, (struct sockaddr *)&fromAddr, &fromAddrLen );   if (in < 0 ) {       perror("accepting connection");   }   visualState.conn[con].sd = in;   fromHost = gethostbyaddr(                             (void*)&fromAddr.sin_addr,                             sizeof(fromAddr.sin_addr),                             fromAddr.sin_family    );    if( fromHost == NULL ) {      perror( "resolving connecting hostname" );      visualState.conn[con].host = SaveString( "<unavailable>" );   } else {      visualState.conn[con].host = SaveString(fromHost->h_name);   }   visualState.conn[con].port = fromAddr.sin_port;   visualState.conn[con].id = visualState.maxId++;   CPUWarning("Control: connect from %s:%d for connId=%d socket=%d\n",               visualState.conn[con].host,              visualState.conn[con].port,              visualState.conn[con].id,              visualState.conn[con].sd);} static void VisualConnect(struct Connection *conn, char *buf){   struct hostent     *dest_host;   struct sockaddr_in  dest_socket;   char hostname[32];   int portnumber;   if (sscanf(buf,"VISUALstream %s %d",hostname,&portnumber) !=2 ) {       CPUError("expecting <stream host port> got <%s>\n",buf);   }   if (VisualGetStream("log")) {      VisualCloseStream("log");   }   if (VisualOpenStream("log", hostname, portnumber) == 0) {      CPUWarning("Error opening VISUALstream %s %d\n", hostname, portnumber);   }}static char * VisualRPC(struct Connection *conn, char *buf){   int code;   int ok = 0;   int context = VisualSetContext(conn->id, &ok);   SIM_DEBUG(('v', "VISUALrpc: (%2d)%s",conn->id,buf));   /*     * Special case stream. I am too lazy to write the Tcl command for now    */   if (!strncmp(buf,"VISUALstream",strlen("VISUALstream"))) {      VisualConnect(conn,buf);      return "OK";   }   code = Tcl_Eval(TCLInterp, buf);   VisualSetContext(context, &ok);   if (code==TCL_OK || *TCLInterp->result) {      return TCLInterp->result;   } else {       return "ERR";   }      }                    /* ***************************************************************************** * VisualCmd(Connection *) * ****************************************************************************/static void VisualCmd(struct Connection *conn) {   int i,j;   char *result;   char readBuffer = 'x'; /*   *for now, screw the non-blocking stuff.   * Block until script has been received  */   if (!conn->buf) {      conn->buf = malloc(MINBUFFER_SIZE);      conn->bufSize = MINBUFFER_SIZE;   }   conn->pos = 0;        for(;;) {       if (conn->pos >= MINBUFFER_SIZE-2) {         char *str;          conn->bufSize *= 2;         str = malloc(conn->bufSize);         strcpy(str,conn->buf);         free(conn->buf);         conn->buf = str;      }                                       i = read(conn->sd,&readBuffer,1);      if (i < 0 ) {          perror("VisualCmd (read)");         return; /* notreached */      }       if (i==0) {         /* 

⌨️ 快捷键说明

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