MachineSpecs.cpp
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2010, Rice University
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Rice University nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 
35 /* Author: The Internet */
36 
37 #include "ompl/tools/benchmark/MachineSpecs.h"
38 #include "ompl/util/Console.h"
39 #include <sstream>
40 
42 
43 #if defined _WIN32
44 
45 // Windows 2000 or newer
46 #include <winsock2.h>
47 #include <windows.h>
48 #include <stdio.h>
49 #include <psapi.h>
50 
51 ompl::machine::MemUsage_t getProcessMemoryUsageAux()
52 {
53  HANDLE hProcess;
54  PROCESS_MEMORY_COUNTERS pmc;
55 
56  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, GetCurrentProcessId());
57 
58  ompl::machine::MemUsage_t result = 0;
59 
60  if (nullptr != hProcess)
61  {
62  if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
63  result = pmc.WorkingSetSize;
64  CloseHandle(hProcess);
65  }
66 
67  return result;
68 }
69 
70 std::string getCPUInfoAux()
71 {
72  static const int BUF_SIZE = 256;
73  char buffer[BUF_SIZE];
74  std::stringstream result;
75  FILE *cmdPipe = _popen("wmic cpu list full", "rt");
76  if (cmdPipe != nullptr)
77  {
78  while (fgets(buffer, BUF_SIZE, cmdPipe))
79  result << buffer;
80  if (feof(cmdPipe))
81  _pclose(cmdPipe);
82  }
83  return result.str();
84 }
85 
86 #else
87 #if defined __APPLE__
88 
89 // Mac OS 10.2 or newer
90 #include <mach/mach_init.h>
91 #include <mach/task.h>
92 #include <sys/time.h>
93 #include <sys/resource.h>
94 #include <cstdint>
95 #include <cstring>
96 #include <unistd.h>
97 
98 ompl::machine::MemUsage_t getProcessMemoryUsageAux()
99 {
100  task_basic_info info;
101  kern_return_t rval = 0;
102  mach_port_t task = mach_task_self();
103  mach_msg_type_number_t tcnt = TASK_BASIC_INFO_COUNT;
104  auto tptr = (task_info_t)&info;
105 
106  memset(&info, 0, sizeof(info));
107 
108  rval = task_info(task, TASK_BASIC_INFO, tptr, &tcnt);
109  if (!(rval == KERN_SUCCESS))
110  return 0;
111  return info.resident_size;
112 }
113 
114 std::string getCPUInfoAux()
115 {
116  static const int BUF_SIZE = 256;
117  char buffer[BUF_SIZE];
118  std::stringstream result;
119  FILE *cmdPipe = popen("sysctl hw", "r");
120  if (cmdPipe != nullptr)
121  {
122  while (fgets(buffer, BUF_SIZE, cmdPipe))
123  result << buffer;
124  if (feof(cmdPipe))
125  pclose(cmdPipe);
126  }
127  return result.str();
128 }
129 
130 #else
131 #include <unistd.h>
132 #if defined _POSIX_VERSION || defined _POSIX2_VERSION || defined __linux__
133 // we need a posix compliant os that exposes /proc/self/stat
134 
135 #include <ios>
136 #include <iostream>
137 #include <fstream>
138 
139 ompl::machine::MemUsage_t getProcessMemoryUsageAux()
140 {
141  using std::ios_base;
142  using std::ifstream;
143  using std::string;
144 
145  // 'file' stat seems to give the most reliable results
146  //
147  ifstream stat_stream("/proc/self/stat", ios_base::in);
148 
149  if (stat_stream.good() && !stat_stream.eof())
150  {
151  // dummy vars for leading entries in stat that we don't care about
152  //
153  string pid, comm, state, ppid, pgrp, session, tty_nr;
154  string tpgid, flags, minflt, cminflt, majflt, cmajflt;
155  string utime, stime, cutime, cstime, priority, nice;
156  string O, itrealvalue, starttime;
157 
158  // the two fields we want
159  //
160  unsigned long vsize;
161  long rss;
162 
163  stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr >> tpgid >> flags >> minflt >>
164  cminflt >> majflt >> cmajflt >> utime >> stime >> cutime >> cstime >> priority >> nice >> O >>
165  itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
166 
167  ompl::machine::MemUsage_t page_size = sysconf(_SC_PAGE_SIZE);
168  return rss * page_size;
169  }
170  return 0;
171 }
172 
173 std::string getCPUInfoAux()
174 {
175  static const int BUF_SIZE = 4096;
176  char buffer[BUF_SIZE];
177  std::stringstream result;
178  FILE *cmdPipe = popen("lscpu", "r");
179  if (cmdPipe != nullptr)
180  {
181  while (fgets(buffer, BUF_SIZE, cmdPipe))
182  result << buffer;
183  if (feof(cmdPipe))
184  pclose(cmdPipe);
185  }
186  return result.str();
187 }
188 
189 #else
190 // if we have no idea what to do, we return 0
191 ompl::machine::MemUsage_t getProcessMemoryUsageAux()
192 {
193  return 0;
194 }
195 // if we have no idea what to do, we return an empty string
196 std::string getCPUInfoAux()
197 {
198  return std::string();
199 }
200 
201 #endif // posix
202 #endif // apple
203 #endif // windows
204 
206 {
207  MemUsage_t result = getProcessMemoryUsageAux();
208  if (result == 0)
209  {
210  OMPL_WARN("Unable to get memory usage");
211  }
212  return result;
213 }
214 
215 std::string ompl::machine::getCPUInfo()
216 {
217  std::string result = getCPUInfoAux();
218  if (result.size() == 0)
219  {
220  OMPL_WARN("Unable to get CPU information");
221  }
222  return result;
223 }
224 
225 std::string ompl::machine::getHostname()
226 {
227  static const int BUF_SIZE = 1024;
228  char buffer[BUF_SIZE];
229  int len = gethostname(buffer, sizeof(buffer));
230  if (len != 0)
231  return std::string();
232  else
233  {
234  buffer[BUF_SIZE - 1] = '\0';
235  return std::string(buffer);
236  }
237 }
238 
std::string getHostname()
Get the hostname of the machine in use.
MemUsage_t getProcessMemoryUsage()
Get the amount of memory the current process is using. This should work on major platforms (Windows,...
unsigned long long MemUsage_t
Amount of memory used, in bytes.
Definition: MachineSpecs.h:112
#define OMPL_WARN(fmt,...)
Log a formatted warning string.
Definition: Console.h:66
std::string getCPUInfo()
Get information about the CPU of the machine in use.