Back to index

nordugrid-arc-nox  1.1.0~rc6
perftest_cmd_times.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 // perftest_cmd.cpp
00006 
00007 #include <unistd.h>
00008 #include <errno.h>
00009 #include <iostream>
00010 #include <fstream>
00011 #include <string>
00012 #include <stdlib.h>
00013 #include <glibmm/thread.h>
00014 #include <glibmm/timer.h>
00015 #include <vector>
00016 #ifndef WIN32
00017 #include <sys/wait.h>
00018 #else
00019 #include <windows.h>
00020 #endif
00021 
00022 
00023 // Some global shared variables...
00024 Glib::Mutex* mutex;
00025 int finishedProcesses;
00026 unsigned long completedCommands;
00027 unsigned long failedCommands;
00028 unsigned long totalCommands;
00029 Glib::TimeVal completedTime;
00030 Glib::TimeVal failedTime;
00031 Glib::TimeVal totalTime;
00032 
00033 int numberOfProcesses;
00034 std::string cmd_str;
00035 std::vector<std::string> arglist;
00036 
00037 // Round off a double to an integer.
00038 int Round(double x){
00039   return int(x+0.5);
00040 }
00041 
00042 // Execute a command line
00043 void execCommand() {
00044   // Some variables...
00045   Glib::TimeVal tBefore;
00046   Glib::TimeVal tAfter;
00047   char **list;
00048   int pid;
00049 
00050   list = (char **)malloc (sizeof(char *) * (arglist.size() +1));
00051   for (int i = 0;i < arglist.size();i++)
00052     list[i] = (char *)arglist[i].c_str();
00053   list[arglist.size()] = NULL;
00054 
00055   for (int i=0; i<numberOfProcesses; i++) {
00056 
00057     tBefore.assign_current_time();
00058 
00059 #ifdef WIN32
00060     STARTUPINFO si = {0};
00061     si.cb = sizeof(si);
00062     PROCESS_INFORMATION pi;
00063     if(CreateProcess(cmd_str.c_str(),NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi
00064 )) {
00065       std::cout << "Create process failed: "<<GetLastError()<<std::endl;
00066       exit(1);
00067     };
00068 
00069     int status;
00070     status = WaitForSingleObject(pi.hProcess, INFINITE);
00071     CloseHandle(pi.hProcess);
00072     CloseHandle(pi.hThread);
00073 
00074     tAfter.assign_current_time();
00075 
00076     if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED) {
00077       std::cout << "ERROR: " << cmd_str << " returns code " << status
00078  << std::endl;
00079       Glib::Mutex::Lock lock(*mutex);
00080       ::failedCommands++;
00081       ::failedTime+=tAfter-tBefore;
00082       finishedProcesses++;
00083     }
00084     else {
00085       Glib::Mutex::Lock lock(*mutex);
00086       ::completedCommands++;
00087       ::completedTime+=tAfter-tBefore;
00088       finishedProcesses++;
00089     }
00090 #else
00091     pid = fork();
00092     if(pid == 0) {
00093       int e = execvp(cmd_str.c_str(), list);
00094       //If execvp returns, it must have failed.
00095       std::cout << "[child] error " << e << " errno: " << errno << std::endl;
00096       exit(1);
00097     }
00098     else if(pid == -1) {
00099       std::cout << "Fork failed. Exiting." << std::endl;
00100       exit(1);
00101     }
00102     else {
00103       int child_status, child_pid;
00104       child_pid = wait(&child_status);
00105 
00106       tAfter.assign_current_time();
00107       if(child_status != 0) {
00108         std::cout << "ERROR: " << cmd_str << " returns code " << child_status << std::endl;
00109         Glib::Mutex::Lock lock(*mutex);
00110         ::failedCommands++;
00111         ::failedTime+=tAfter-tBefore;
00112         finishedProcesses++;
00113       }
00114       else {
00115         Glib::Mutex::Lock lock(*mutex);
00116         ::completedCommands++;
00117         ::completedTime+=tAfter-tBefore;
00118         finishedProcesses++;
00119       }
00120     }
00121 #endif
00122   } 
00123 
00124   std::cout << "Number of finished processes: " << finishedProcesses << std::endl;
00125 
00126   free(list);
00127 
00128 }
00129 
00130 int main(int argc, char* argv[]){
00131   // Some variables...
00132   //int numberOfProcesses;
00133   int i;
00134  
00135   // Extract command line arguments.
00136   if (argc<3){
00137     std::cerr << "Wrong number of arguments!" << std::endl
00138              << std::endl
00139              << "Usage:" << std::endl
00140              << "perftest_cmd_times processes " << std::endl
00141              << std::endl
00142              << "Arguments:" << std::endl
00143              << "processes  The number of concurrent commands." << std::endl;
00144     exit(EXIT_FAILURE);
00145   }
00146 
00147   numberOfProcesses = atoi(argv[1]);
00148 
00149   cmd_str = std::string(argv[2]);
00150   std::cout<<"cmd_str "<<cmd_str<<std::endl;
00151 
00152   //Parse the arguments of command line
00153   for (int i = 0;i < (argc -2);i++) {
00154     arglist.push_back((char *)argv[i+2]);
00155     std::cout<<"argv: "<<arglist[i]<<std::endl;
00156   }
00157 
00158   // Start processes.
00159   finishedProcesses=0;
00160   mutex=new Glib::Mutex;
00161 
00162   execCommand();
00163 
00164   // Print the result of the test.
00165   Glib::Mutex::Lock lock(*mutex);
00166   totalCommands = completedCommands+failedCommands;
00167   totalTime = completedTime+failedTime;
00168   std::cout << "========================================" << std::endl;
00169   std::cout << "Number of processes: "
00170            << numberOfProcesses << std::endl;
00171   std::cout << "Number of commands: "
00172            << totalCommands << std::endl;
00173   std::cout << "Completed commands: "
00174            << completedCommands << " ("
00175            << Round(completedCommands*100.0/totalCommands)
00176            << "%)" << std::endl;
00177   std::cout << "Failed commands: "
00178            << failedCommands << " ("
00179            << Round(failedCommands*100.0/totalCommands)
00180            << "%)" << std::endl;
00181   std::cout << "Average response time for all commands: "
00182            << Round(1000*totalTime.as_double()/totalCommands)
00183            << " ms" << std::endl;
00184   if (completedCommands!=0)
00185     std::cout << "Average response time for completed commands: "
00186              << Round(1000*completedTime.as_double()/completedCommands)
00187              << " ms" << std::endl;
00188   if (failedCommands!=0)
00189     std::cout << "Average response time for failed commands: "
00190              << Round(1000*failedTime.as_double()/failedCommands)
00191              << " ms" << std::endl;
00192   std::cout << "========================================" << std::endl;
00193 
00194   return 0;
00195 }