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

kernel.cc

Aller à la documentation de ce fichier.
00001 // kernel.cc 
00002 //      Initialization and cleanup routines for the Nachos kernel.
00003 //
00004 // Copyright (c) 1992-1996 The Regents of the University of California.
00005 // All rights reserved.  See copyright.h for copyright notice and limitation 
00006 // of liability and disclaimer of warranty provisions.
00007 
00008 #include "copyright.h"
00009 #include "debug.h"
00010 #include "main.h"
00011 #include "kernel.h"
00012 #include "sysdep.h"
00013 #include "synch.h"
00014 #include "synchlist.h"
00015 #include "libtest.h"
00016 #include "string.h"
00017 #include "synchconsole.h"
00018 #include "synchdisk.h"
00019 #include "post.h"
00020 
00021 //----------------------------------------------------------------------
00022 // Kernel::Kernel
00023 //      Interpret command line arguments in order to determine flags 
00024 //      for the initialization (see also comments in main.cc)  
00025 //----------------------------------------------------------------------
00026 
00027 Kernel::Kernel(int argc, char **argv)
00028 {
00029     randomSlice = FALSE; 
00030     debugUserProg = FALSE;
00031     consoleIn = NULL;          // default is stdin
00032     consoleOut = NULL;         // default is stdout
00033 #ifndef FILESYS_STUB
00034     formatFlag = FALSE;
00035 #endif
00036     reliability = 1;            // network reliability, default is 1.0
00037     hostName = 0;               // machine id, also UNIX socket name
00038                                 // 0 is the default machine id
00039     for (int i = 1; i < argc; i++) {
00040         if (strcmp(argv[i], "-rs") == 0) {
00041             ASSERT(i + 1 < argc);
00042             RandomInit(atoi(argv[i + 1]));// initialize pseudo-random
00043                                         // number generator
00044             randomSlice = TRUE;
00045             i++;
00046         } else if (strcmp(argv[i], "-s") == 0) {
00047             debugUserProg = TRUE;
00048         } else if (strcmp(argv[i], "-ci") == 0) {
00049             ASSERT(i + 1 < argc);
00050             consoleIn = argv[i + 1];
00051             i++;
00052         } else if (strcmp(argv[i], "-co") == 0) {
00053             ASSERT(i + 1 < argc);
00054             consoleOut = argv[i + 1];
00055             i++;
00056 #ifndef FILESYS_STUB
00057         } else if (strcmp(argv[i], "-f") == 0) {
00058             formatFlag = TRUE;
00059 #endif
00060         } else if (strcmp(argv[i], "-n") == 0) {
00061             ASSERT(i + 1 < argc);   // next argument is float
00062             reliability = atof(argv[i + 1]);
00063             i++;
00064         } else if (strcmp(argv[i], "-m") == 0) {
00065             ASSERT(i + 1 < argc);   // next argument is int
00066             hostName = atoi(argv[i + 1]);
00067             i++;
00068         } else if (strcmp(argv[i], "-u") == 0) {
00069             cout << "Partial usage: nachos [-rs randomSeed]\n";
00070             cout << "Partial usage: nachos [-s]\n";
00071             cout << "Partial usage: nachos [-ci consoleIn] [-co consoleOut]\n";
00072 #ifndef FILESYS_STUB
00073             cout << "Partial usage: nachos [-nf]\n";
00074 #endif
00075             cout << "Partial usage: nachos [-n #] [-m #]\n";
00076         }
00077     }
00078 }
00079 
00080 //----------------------------------------------------------------------
00081 // Kernel::Initialize
00082 //      Initialize Nachos global data structures.  Separate from the 
00083 //      constructor because some of these refer to earlier initialized
00084 //      data via the "kernel" global variable.
00085 //----------------------------------------------------------------------
00086 
00087 void
00088 Kernel::Initialize()
00089 {
00090     // We didn't explicitly allocate the current thread we are running in.
00091     // But if it ever tries to give up the CPU, we better have a Thread
00092     // object to save its state. 
00093     currentThread = new Thread("main");         
00094     currentThread->setStatus(RUNNING);
00095 
00096     stats = new Statistics();           // collect statistics
00097     interrupt = new Interrupt;          // start up interrupt handling
00098     scheduler = new Scheduler();        // initialize the ready queue
00099     alarm = new Alarm(randomSlice);     // start up time slicing
00100     machine = new Machine(debugUserProg);
00101     synchConsoleIn = new SynchConsoleInput(consoleIn); // input from stdin
00102     synchConsoleOut = new SynchConsoleOutput(consoleOut); // output to stdout
00103     synchDisk = new SynchDisk();    //
00104 #ifdef FILESYS_STUB
00105     fileSystem = new FileSystem();
00106 #else
00107     fileSystem = new FileSystem(formatFlag);
00108 #endif // FILESYS_STUB
00109     postOfficeIn = new PostOfficeInput(10);
00110     postOfficeOut = new PostOfficeOutput(reliability);
00111 
00112     interrupt->Enable();
00113 }
00114 
00115 //----------------------------------------------------------------------
00116 // Kernel::~Kernel
00117 //      Nachos is halting.  De-allocate global data structures.
00118 //----------------------------------------------------------------------
00119 
00120 Kernel::~Kernel()
00121 {
00122     delete stats;
00123     delete interrupt;
00124     delete scheduler;
00125     delete alarm;
00126     delete machine;
00127     delete synchConsoleIn;
00128     delete synchConsoleOut;
00129     delete synchDisk;
00130     delete fileSystem;
00131     delete postOfficeIn;
00132     delete postOfficeOut;
00133     
00134     Exit(0);
00135 }
00136 
00137 //----------------------------------------------------------------------
00138 // Kernel::ThreadSelfTest
00139 //      Test threads, semaphores, synchlists
00140 //----------------------------------------------------------------------
00141 
00142 void
00143 Kernel::ThreadSelfTest() {
00144    Semaphore *semaphore;
00145    SynchList<int> *synchList;
00146    
00147    LibSelfTest();               // test library routines
00148    
00149    currentThread->SelfTest();   // test thread switching
00150    
00151                                 // test semaphore operation
00152    semaphore = new Semaphore("test", 0);
00153    semaphore->SelfTest();
00154    delete semaphore;
00155    
00156                                 // test locks, condition variables
00157                                 // using synchronized lists
00158    synchList = new SynchList<int>;
00159    synchList->SelfTest(9);
00160    delete synchList;
00161 
00162 }
00163 
00164 //----------------------------------------------------------------------
00165 // Kernel::ConsoleTest
00166 //      Test the synchconsole
00167 //----------------------------------------------------------------------
00168 
00169 void
00170 Kernel::ConsoleTest() {
00171     char ch;
00172 
00173     cout << "Testing the console device.\n" 
00174         << "Typed characters will be echoed, until ^D is typed.\n"
00175         << "Note newlines are needed to flush input through UNIX.\n";
00176     cout.flush();
00177 
00178     do {
00179         ch = synchConsoleIn->GetChar();
00180         if(ch != EOF) synchConsoleOut->PutChar(ch);   // echo it!
00181     } while (ch != EOF);
00182 
00183     cout << "\n";
00184 
00185 }
00186 
00187 //----------------------------------------------------------------------
00188 // Kernel::NetworkTest
00189 //      Test whether the post office is working. On machines #0 and #1, do:
00190 //
00191 //      1. send a message to the other machine at mail box #0
00192 //      2. wait for the other machine's message to arrive (in our mailbox #0)
00193 //      3. send an acknowledgment for the other machine's message
00194 //      4. wait for an acknowledgement from the other machine to our 
00195 //          original message
00196 //
00197 //  This test works best if each Nachos machine has its own window
00198 //----------------------------------------------------------------------
00199 
00200 void
00201 Kernel::NetworkTest() {
00202 
00203     if (hostName == 0 || hostName == 1) {
00204         // if we're machine 1, send to 0 and vice versa
00205         int farHost = (hostName == 0 ? 1 : 0); 
00206         PacketHeader outPktHdr, inPktHdr;
00207         MailHeader outMailHdr, inMailHdr;
00208         char *data = "Hello there!";
00209         char *ack = "Got it!";
00210         char buffer[MaxMailSize];
00211 
00212         // construct packet, mail header for original message
00213         // To: destination machine, mailbox 0
00214         // From: our machine, reply to: mailbox 1
00215         outPktHdr.to = farHost;         
00216         outMailHdr.to = 0;
00217         outMailHdr.from = 1;
00218         outMailHdr.length = strlen(data) + 1;
00219 
00220         // Send the first message
00221         postOfficeOut->Send(outPktHdr, outMailHdr, data); 
00222 
00223         // Wait for the first message from the other machine
00224         postOfficeIn->Receive(0, &inPktHdr, &inMailHdr, buffer);
00225         cout << "Got: " << buffer << " : from " << inPktHdr.from << ", box " 
00226                                                 << inMailHdr.from << "\n";
00227         cout.flush();
00228 
00229         // Send acknowledgement to the other machine (using "reply to" mailbox
00230         // in the message that just arrived
00231         outPktHdr.to = inPktHdr.from;
00232         outMailHdr.to = inMailHdr.from;
00233         outMailHdr.length = strlen(ack) + 1;
00234         postOfficeOut->Send(outPktHdr, outMailHdr, ack); 
00235 
00236         // Wait for the ack from the other machine to the first message we sent
00237         postOfficeIn->Receive(1, &inPktHdr, &inMailHdr, buffer);
00238         cout << "Got: " << buffer << " : from " << inPktHdr.from << ", box " 
00239                                                 << inMailHdr.from << "\n";
00240         cout.flush();
00241     }
00242 
00243     // Then we're done!
00244 }
00245 

Généré le Sun Jan 15 00:45:45 2006 pour Système NachOS : par  doxygen 1.4.4