Page principale | Hiérarchie des classes | Liste des classes | Répertoires | Liste des fichiers | Membres de classe | Membres de fichier

network.cc

Aller à la documentation de ce fichier.
00001 // network.cc 
00002 //      Routines to simulate a network interface, using UNIX sockets
00003 //      to deliver packets between multiple invocations of nachos.
00004 //
00005 //  DO NOT CHANGE -- part of the machine emulation
00006 //
00007 // Copyright (c) 1992-1996 The Regents of the University of California.
00008 // All rights reserved.  See copyright.h for copyright notice and limitation 
00009 // of liability and disclaimer of warranty provisions.
00010 
00011 #include "copyright.h"
00012 #include "network.h"
00013 #include "main.h"
00014 
00015 //-----------------------------------------------------------------------
00016 // NetworkInput::NetworkInput
00017 //      Initialize the simulation for the network input
00018 //
00019 //      "toCall" is the interrupt handler to call when packet arrives
00020 //-----------------------------------------------------------------------
00021 
00022 NetworkInput::NetworkInput(CallBackObj *toCall)
00023 {
00024     // set up the stuff to emulate asynchronous interrupts
00025     callWhenAvail = toCall;
00026     packetAvail = FALSE;
00027     inHdr.length = 0;
00028     
00029     sock = OpenSocket();
00030     sprintf(sockName, "SOCKET_%d", kernel->hostName);
00031     AssignNameToSocket(sockName, sock);          // Bind socket to a filename 
00032                                                  // in the current directory.
00033 
00034     // start polling for incoming packets
00035     kernel->interrupt->Schedule(this, NetworkTime, NetworkRecvInt);
00036 }
00037 
00038 //-----------------------------------------------------------------------
00039 // NetworkInput::NetworkInput
00040 //      Deallocate the simulation for the network input
00041 //              (basically, deallocate the input mailbox)
00042 //-----------------------------------------------------------------------
00043 
00044 NetworkInput::~NetworkInput()
00045 {
00046     CloseSocket(sock);
00047     DeAssignNameToSocket(sockName);
00048 }
00049 
00050 //-----------------------------------------------------------------------
00051 // NetworkInput::CallBack
00052 //      Simulator calls this when a packet may be available to
00053 //      be read in from the simulated network.
00054 //
00055 //      First check to make sure packet is available & there's space to
00056 //      pull it in.  Then invoke the "callBack" registered by whoever 
00057 //      wants the packet.
00058 //-----------------------------------------------------------------------
00059 
00060 void
00061 NetworkInput::CallBack()
00062 {
00063     // schedule the next time to poll for a packet
00064     kernel->interrupt->Schedule(this, NetworkTime, NetworkRecvInt);
00065 
00066     if (inHdr.length != 0)      // do nothing if packet is already buffered
00067         return;         
00068     if (!PollSocket(sock))      // do nothing if no packet to be read
00069         return;
00070 
00071     // otherwise, read packet in
00072     char *buffer = new char[MaxWireSize];
00073     ReadFromSocket(sock, buffer, MaxWireSize);
00074 
00075     // divide packet into header and data
00076     inHdr = *(PacketHeader *)buffer;
00077     ASSERT((inHdr.to == kernel->hostName) && (inHdr.length <= MaxPacketSize));
00078     bcopy(buffer + sizeof(PacketHeader), inbox, inHdr.length);
00079     delete [] buffer ;
00080 
00081     DEBUG(dbgNet, "Network received packet from " << inHdr.from << ", length " << inHdr.length);
00082     kernel->stats->numPacketsRecvd++;
00083 
00084     // tell post office that the packet has arrived
00085     callWhenAvail->CallBack();
00086 }
00087 
00088 //-----------------------------------------------------------------------
00089 // NetworkInput::Receive
00090 //      Read a packet, if one is buffered
00091 //-----------------------------------------------------------------------
00092 
00093 PacketHeader
00094 NetworkInput::Receive(char* data)
00095 {
00096     PacketHeader hdr = inHdr;
00097 
00098     inHdr.length = 0;
00099     if (hdr.length != 0) {
00100         bcopy(inbox, data, hdr.length);
00101     }
00102     return hdr;
00103 }
00104 
00105 //-----------------------------------------------------------------------
00106 // NetworkOutput::NetworkOutput
00107 //      Initialize the simulation for sending network packets
00108 //
00109 //      "reliability" says whether we drop packets to emulate unreliable links
00110 //      "toCall" is the interrupt handler to call when next packet can be sent
00111 //-----------------------------------------------------------------------
00112 
00113 NetworkOutput::NetworkOutput(double reliability, CallBackObj *toCall)
00114 {
00115     if (reliability < 0) chanceToWork = 0;
00116     else if (reliability > 1) chanceToWork = 1;
00117     else chanceToWork = reliability;
00118 
00119     // set up the stuff to emulate asynchronous interrupts
00120     callWhenDone = toCall;
00121     sendBusy = FALSE;
00122     sock = OpenSocket();
00123 }
00124 
00125 //-----------------------------------------------------------------------
00126 // NetworkOutput::~NetworkOutput
00127 //      Deallocate the simulation for sending network packets
00128 //-----------------------------------------------------------------------
00129 
00130 NetworkOutput::~NetworkOutput()
00131 {
00132     CloseSocket(sock);
00133 }
00134 
00135 //-----------------------------------------------------------------------
00136 // NetworkOutput::CallBack
00137 //      Called by simulator when another packet can be sent.
00138 //-----------------------------------------------------------------------
00139 
00140 void
00141 NetworkOutput::CallBack()
00142 {
00143     sendBusy = FALSE;
00144     kernel->stats->numPacketsSent++;
00145     callWhenDone->CallBack();
00146 }
00147 
00148 //-----------------------------------------------------------------------
00149 // NetworkOutput::Send
00150 //      Send a packet into the simulated network, to the destination in hdr.
00151 //      Concatenate hdr and data, and schedule an interrupt to tell the user 
00152 //      when the next packet can be sent 
00153 //
00154 //      Note we always pad out a packet to MaxWireSize before putting it into
00155 //      the socket, because it's simpler at the receive end.
00156 //-----------------------------------------------------------------------
00157 
00158 void
00159 NetworkOutput::Send(PacketHeader hdr, char* data)
00160 {
00161     char toName[32];
00162 
00163     sprintf(toName, "SOCKET_%d", (int)hdr.to);
00164     
00165     ASSERT((sendBusy == FALSE) && (hdr.length > 0) && 
00166         (hdr.length <= MaxPacketSize) && (hdr.from == kernel->hostName));
00167     DEBUG(dbgNet, "Sending to addr " << hdr.to << ", length " << hdr.length);
00168 
00169     kernel->interrupt->Schedule(this, NetworkTime, NetworkSendInt);
00170 
00171     if (RandomNumber() % 100 >= chanceToWork * 100) { // emulate a lost packet
00172         DEBUG(dbgNet, "oops, lost it!");
00173         return;
00174     }
00175 
00176     // concatenate hdr and data into a single buffer, and send it out
00177     char *buffer = new char[MaxWireSize];
00178     *(PacketHeader *)buffer = hdr;
00179     bcopy(data, buffer + sizeof(PacketHeader), hdr.length);
00180     SendToSocket(sock, buffer, MaxWireSize, toName);
00181     delete [] buffer;
00182 }

Généré le Sun Jan 15 00:44:24 2006 pour Architecture Cible de NachOS : par  doxygen 1.4.4