ompl/tools/benchmark/src/MachineSpecs.cpp
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2010, Rice University
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Rice University nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 /* Author: The Internet */
00036 
00037 #include "ompl/tools/benchmark/MachineSpecs.h"
00038 #include "ompl/util/Console.h"
00039 #include <sstream>
00040 
00042 
00043 #if defined _WIN32
00044 
00045 // Windows 2000 or newer
00046 #include <winsock2.h>
00047 #include <windows.h>
00048 #include <stdio.h>
00049 #include <psapi.h>
00050 
00051 ompl::machine::MemUsage_t getProcessMemoryUsageAux()
00052 {
00053     HANDLE hProcess;
00054     PROCESS_MEMORY_COUNTERS pmc;
00055 
00056     hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
00057                              PROCESS_VM_READ,
00058                              false,
00059                              GetCurrentProcessId() );
00060 
00061     ompl::machine::MemUsage_t result = 0;
00062 
00063     if (NULL != hProcess)
00064     {
00065         if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
00066             result = pmc.WorkingSetSize;
00067         CloseHandle( hProcess );
00068     }
00069 
00070     return result;
00071 }
00072 
00073 std::string getCPUInfoAux()
00074 {
00075     static const int BUF_SIZE = 256;
00076     char buffer[BUF_SIZE];
00077     std::stringstream result;
00078     FILE *cmdPipe = _popen("wmic cpu list full", "rt");
00079     if (cmdPipe != NULL)
00080     {
00081         while (fgets(buffer, BUF_SIZE, cmdPipe))
00082             result << buffer;
00083         if (feof(cmdPipe))
00084             _pclose(cmdPipe);
00085     }
00086     return result.str();
00087 }
00088 
00089 
00090 #else
00091 #if defined __APPLE__
00092 
00093 // Mac OS 10.2 or newer
00094 #include <mach/mach_init.h>
00095 #include <mach/task.h>
00096 #include <sys/time.h>
00097 #include <sys/resource.h>
00098 #include <stdint.h>
00099 #include <cstring>
00100 #include <unistd.h>
00101 
00102 ompl::machine::MemUsage_t getProcessMemoryUsageAux()
00103 {
00104 
00105     task_basic_info         info;
00106     kern_return_t           rval = 0;
00107     mach_port_t             task = mach_task_self();
00108     mach_msg_type_number_t  tcnt = TASK_BASIC_INFO_COUNT;
00109     task_info_t             tptr = (task_info_t) &info;
00110 
00111     memset(&info, 0, sizeof(info));
00112 
00113     rval = task_info(task, TASK_BASIC_INFO, tptr, &tcnt);
00114     if (!(rval == KERN_SUCCESS)) return 0;
00115     return info.resident_size;
00116 }
00117 
00118 std::string getCPUInfoAux()
00119 {
00120     static const int BUF_SIZE = 256;
00121     char buffer[BUF_SIZE];
00122     std::stringstream result;
00123     FILE *cmdPipe = popen("sysctl hw", "r");
00124     if (cmdPipe != NULL)
00125     {
00126         while (fgets(buffer, BUF_SIZE, cmdPipe))
00127             result << buffer;
00128         if (feof(cmdPipe))
00129             pclose(cmdPipe);
00130     }
00131     return result.str();
00132 }
00133 
00134 #else
00135 #if defined _POSIX_VERSION || defined _POSIX2_VERSION || defined __linux__
00136 // we need a posix compliant os that exposes /proc/self/stat
00137 
00138 #include <unistd.h>
00139 #include <ios>
00140 #include <iostream>
00141 #include <fstream>
00142 
00143 ompl::machine::MemUsage_t getProcessMemoryUsageAux()
00144 {
00145    using std::ios_base;
00146    using std::ifstream;
00147    using std::string;
00148 
00149    // 'file' stat seems to give the most reliable results
00150    //
00151    ifstream stat_stream("/proc/self/stat",ios_base::in);
00152 
00153    if (stat_stream.good() && !stat_stream.eof())
00154    {
00155        // dummy vars for leading entries in stat that we don't care about
00156        //
00157        string pid, comm, state, ppid, pgrp, session, tty_nr;
00158        string tpgid, flags, minflt, cminflt, majflt, cmajflt;
00159        string utime, stime, cutime, cstime, priority, nice;
00160        string O, itrealvalue, starttime;
00161 
00162 
00163        // the two fields we want
00164        //
00165        unsigned long vsize;
00166        long rss;
00167 
00168        stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
00169                    >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
00170                    >> utime >> stime >> cutime >> cstime >> priority >> nice
00171                    >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
00172 
00173        ompl::machine::MemUsage_t page_size = sysconf(_SC_PAGE_SIZE);
00174        return rss * page_size;
00175    }
00176    return 0;
00177 }
00178 
00179 std::string getCPUInfoAux()
00180 {
00181     static const int BUF_SIZE = 4096;
00182     char buffer[BUF_SIZE];
00183     std::stringstream result;
00184     FILE *cmdPipe = popen("lscpu", "r");
00185     if (cmdPipe != NULL)
00186     {
00187         while (fgets(buffer, BUF_SIZE, cmdPipe))
00188             result << buffer;
00189         if (feof(cmdPipe))
00190             pclose(cmdPipe);
00191     }
00192     return result.str();
00193 }
00194 
00195 #else
00196 // if we have no idea what to do, we return 0
00197 ompl::machine::MemUsage_t getProcessMemoryUsageAux()
00198 {
00199     return 0;
00200 }
00201 // if we have no idea what to do, we return an empty string
00202 std::string getCPUInfoAux()
00203 {
00204     return std::string();
00205 }
00206 
00207 #endif // posix
00208 #endif // apple
00209 #endif // windows
00210 
00211 ompl::machine::MemUsage_t ompl::machine::getProcessMemoryUsage()
00212 {
00213     MemUsage_t result = getProcessMemoryUsageAux();
00214     if (result == 0)
00215     {
00216         OMPL_WARN("Unable to get memory usage");
00217     }
00218     return result;
00219 }
00220 
00221 std::string ompl::machine::getCPUInfo()
00222 {
00223     std::string result = getCPUInfoAux();
00224     if (result.size() == 0)
00225     {
00226         OMPL_WARN("Unable to get CPU information");
00227     }
00228     return result;
00229 }
00230 
00231 std::string ompl::machine::getHostname()
00232 {
00233     static const int BUF_SIZE = 1024;
00234     char buffer[BUF_SIZE];
00235     int len = gethostname(buffer, sizeof(buffer));
00236     if (len != 0)
00237         return std::string();
00238     else
00239     {
00240         buffer[BUF_SIZE - 1] = '\0';
00241         return std::string(buffer);
00242     }
00243 }
00244 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines