Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

TestBigXfer.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // Last modified on Sun May 22 22:50:58 EDT 2005 by ken@xorian.net         
00020 //      modified on Fri Apr 22 15:47:50 EDT 2005 by irina.furman@intel.com 
00021 //      modified on Sat Feb 12 17:42:45 PST 2000 by mann  
00022 //      modified on Fri Jun 13 11:08:14 PDT 1997 by heydon
00023 
00024 /* This program tests large data transfers using SRPC. The same program is
00025    used for both the server and client; the first command-line switch must
00026    be either "-client" or "-server". Both the client and server programs
00027    should be run on the same machine.
00028 
00029    The program sends increasingly larger buffers from the client to the server
00030    over a succession of rounds. The size of the buffers send in round "i" is
00031    "2^i". The program stops after the 20th round (when the buffer size is
00032    1MB). 
00033 
00034    Each round is a collection of iterations, where an iteration consists of
00035    sending a single buffer of the size appropraite for that round. By default,
00036    there are 10 iterations per round. However, when invoking the client, you
00037    can specify a different number of iterations per round using the "-iters"
00038    switch. The syntax of the client and server commands lines are:
00039 
00040      Client: TestBigXfer -client [ -iters n ] [ serverhost ]
00041      Server: TestBigXfer -server
00042 
00043    If an SRPC failure occurs at the client, the program prints an error
00044    message and immediately exits. When an SRPC failure occurs on the server,
00045    an error message is printed, but the server continues listening for new
00046    requests. */
00047 
00048 #include <Basics.H>
00049 #include <SRPC.H>
00050 #include <MultiSRPC.H>
00051 #include <LimService.H>
00052 
00053 #include <sstream>
00054 
00055 using std::ostream;
00056 using std::istringstream;
00057 using std::endl;
00058 using std::cout;
00059 using std::cerr;
00060 
00061 // SRPC constants
00062 const Text IntfName("1234");
00063 const int  IntfVersion = 1;
00064 const int  ProcId1 = 1;
00065 
00066 // protects writing to "cout"
00067 static Basics::mutex mu;
00068 
00069 // transfer constants
00070 const unsigned FirstSize = 1U << 1;
00071 const unsigned LastSize  = 1U << 20;
00072 const int NumIterations  = 8;
00073 
00074 void SyntaxError(const char *msg) throw ()
00075 {
00076     cerr << "Error: " << msg << '\n';
00077     cerr << "SYNTAX: TestBigXfer [ -client | -server ] [ -iters n ]\n";
00078     exit(1);
00079 }
00080 
00081 ostream& operator << (ostream &os, const SRPC::failure &f) throw ()
00082 {
00083     mu.lock();
00084     int i;
00085     for (i = 0; i < 70; i++) os << '*'; os << '\n';
00086     os << "SRPC failure (" << f.r << ") :\n";
00087     os << "  " << f.msg << '\n';
00088     for (i = 0; i < 70; i++) os << '*'; os << "\n\n";
00089     os.flush();
00090     mu.unlock();
00091     return os;
00092 }
00093 
00094 void ClientCall(SRPC *srpc, int numIterations, unsigned len)
00095   throw (SRPC::failure)
00096 {
00097     mu.lock();
00098     cout << "Calling Proc1\n";
00099     cout << "  len = " << len << '\n';
00100     cout << "  buffs = " << numIterations << '\n';
00101     cout << "  total = " << numIterations * len << '\n';
00102     (cout << '\n').flush();
00103     mu.unlock();
00104 
00105     char* buff = NEW_PTRFREE_ARRAY(char, len);
00106     srpc->start_call(ProcId1, IntfVersion);
00107     srpc->send_int(numIterations);
00108     for (int i = 0; i < numIterations; i++) {
00109         srpc->send_bytes(buff, len);
00110     }
00111     srpc->send_end();
00112     unsigned res = srpc->recv_int();
00113     assert(res == (len * numIterations));
00114     srpc->recv_end();
00115     delete buff;
00116 
00117     mu.lock();
00118     cout << "Returned Proc1\n";
00119     (cout << '\n').flush();
00120     mu.unlock();
00121 }
00122 
00123 void Client(int numIterations, const char *server) throw ()
00124 {
00125     MultiSRPC multi(IntfName);
00126     try {
00127         for (unsigned len = FirstSize; len <= LastSize; len <<= 1) {
00128             // establish SRPC connection
00129             SRPC *srpc;
00130             MultiSRPC::ConnId connId;
00131             connId = multi.Start(server, /*OUT*/ srpc);
00132 
00133             // client call
00134             ClientCall(srpc, numIterations, len);
00135 
00136             // close connection
00137             multi.End(connId);
00138         }
00139     } catch (SRPC::failure f) {
00140         cout << f;
00141     }
00142 }
00143 
00144 void ServerFailureCallback(SRPC *srpc, const SRPC::failure &f, void *arg)
00145   throw ()
00146 {
00147     cout << f;
00148 }
00149 
00150 void Proc1(SRPC *srpc) throw (SRPC::failure)
00151 {
00152     int len, total = 0;
00153     char *buff;
00154 
00155     int numIterations = srpc->recv_int();
00156     for (int i = 0; i < numIterations; i++) {
00157         buff = srpc->recv_bytes(/*OUT*/ len);
00158         delete buff;
00159         total += len;
00160     }
00161     srpc->recv_end();
00162 
00163     mu.lock();
00164     cout << "Called Proc1\n";
00165     cout << "  len = " << len << '\n';
00166     cout << "  buffs = " << numIterations << '\n';
00167     cout << "  total = " << total << '\n';
00168     (cout << '\n').flush();
00169     mu.unlock();
00170 
00171     srpc->send_int(total);
00172     srpc->send_end();
00173 
00174     mu.lock();
00175     cout << "Returned Proc1\n";
00176     (cout << '\n').flush();
00177     mu.unlock();
00178 }
00179 
00180 void ServerCallback(SRPC *srpc, int procId, void *arg)
00181   throw (SRPC::failure)
00182 {
00183     switch (procId) {
00184       case ProcId1: Proc1(srpc); break;
00185       default: assert(false);
00186     }
00187 }
00188 
00189 void Server() throw ()
00190 {
00191     // start server
00192     const int MaxRunning = 10, MaxBlocked = 10;
00193     LimService ls(IntfName, IntfVersion, MaxRunning, MaxBlocked,
00194       ServerCallback, ServerFailureCallback);
00195     Basics::thread th = ls.Forked_Run();
00196 
00197     // print ready msg
00198     mu.lock();
00199     (cout << "Server ready...\n\n").flush();
00200     mu.unlock();
00201 
00202     // wait on forked thread
00203     (void) th.join();
00204 }
00205 
00206 int main(int argc, char *argv[]) 
00207 {
00208     enum Kind { NoKind, ClientKind, ServerKind };
00209     Kind kind = NoKind;
00210     int arg = 1;
00211     int numIterations = NumIterations;
00212     const char *server = 0;
00213 
00214     while (arg < argc) {
00215         if (strcmp(argv[arg], "-client") == 0) {
00216             kind = ClientKind;
00217         } else if (strcmp(argv[arg], "-server") == 0) {
00218             kind = ServerKind;
00219         } else if (strcmp(argv[arg], "-iters") == 0) {
00220             if (++arg >= argc) SyntaxError("no argument for '-iters' switch");
00221             istringstream istr(argv[arg]);
00222             istr >> numIterations;
00223         } else if (!server && (kind == ClientKind)) {
00224           server = argv[arg];
00225         } else {
00226           Text msg = "unrecognized switch: \"";
00227           msg += argv[arg];
00228           msg += "\"";
00229           SyntaxError(msg.cchars());
00230         }
00231         arg++;
00232     }
00233     if(!server)
00234       {
00235         server = "localhost";
00236       }
00237     switch (kind) {
00238       case ClientKind: Client(numIterations, server); break;
00239       case ServerKind: Server(); break;
00240       default:
00241         SyntaxError("you must specify '-client' or '-server'");
00242         break;
00243     }
00244     return 0;
00245 }

Generated on Mon May 8 00:48:57 2006 for Vesta by  doxygen 1.4.2