Belle II Software  release-06-02-00
Utils.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 // weird bug in intel compiler and or boost::process: If we include boost
9 // process intel compile fails. It seems that including sys/wait.h after
10 // other c++ std:: headers triggers a weird behavior failing two static
11 // asserts. We work around that by including it right away
12 #include <sys/wait.h>
13 
14 #include <framework/utilities/Utils.h>
15 
16 #include <framework/gearbox/Unit.h>
17 #include <framework/logging/Logger.h>
18 
19 #include <boost/process.hpp>
20 
21 #include <sys/time.h>
22 #include <unistd.h>
23 
24 #include <cstdio>
25 #include <iomanip>
26 #include <utility>
27 
28 using namespace Belle2;
29 
30 namespace {
40  std::pair<unsigned long, unsigned long> getStatmSize()
41  {
43  const static long pageSizeKb = sysconf(_SC_PAGESIZE) / 1024;
44  static FILE* stream = nullptr;
45  static int pid = 0;
46  int currentPid = getpid();
47  if (currentPid != pid) {
48  pid = currentPid;
49  std::string statm = "/proc/" + std::to_string(pid) + "/statm";
50  stream = fopen(statm.c_str(), "r");
51  // If we use buffering we might get the same value each time we read so
52  // disable buffering
53  setvbuf(stream, nullptr, _IONBF, 0);
54  }
55  unsigned long vmSizePages{0};
56  unsigned long rssPages{0};
57  rewind(stream);
58  fscanf(stream, "%lu %lu", &vmSizePages, &rssPages);
59  return std::make_pair(vmSizePages * pageSizeKb, rssPages * pageSizeKb);
60  }
61 }
62 
63 namespace Belle2::Utils {
64 
65  double getClock()
66  {
67  timespec ts;
68  clock_gettime(CLOCK_REALTIME, &ts);
69  return (ts.tv_sec * Unit::s) + (ts.tv_nsec * Unit::ns);
70  }
71  double getCPUClock()
72  {
73  timespec ts;
74  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
75  return (ts.tv_sec * Unit::s) + (ts.tv_nsec * Unit::ns);
76  }
77 
78  unsigned long getVirtualMemoryKB()
79  {
80  return getStatmSize().first;
81  }
82 
83  unsigned long getRssMemoryKB()
84  {
85  return getStatmSize().second;
86  }
87 
88  Timer::Timer(std::string text):
89  m_startTime(getClock()),
90  m_text(std::move(text))
91  { }
92 
93  Timer::~Timer()
94  {
95  double elapsed = (getClock() - m_startTime) / Unit::ms;
96  B2INFO(m_text << " " << std::fixed << std::setprecision(3) << elapsed << " ms");
97  }
98 
99  std::string getCommandOutput(const std::string& command, const std::vector<std::string>& arguments,
100  bool searchPath)
101  {
102  namespace bp = boost::process;
103  auto cmd = searchPath ? bp::search_path(command) : boost::filesystem::path(command);
104  bp::ipstream cmdOut;
105  bp::child child(cmd, bp::args(arguments), bp::std_in.close(), bp::std_out > cmdOut);
106  char buffer[4096];
107  std::string result;
108  while (child.running() && cmdOut.read(buffer, sizeof(buffer))) {
109  result.append(buffer, sizeof(buffer));
110  }
111  if (cmdOut.gcount()) result.append(buffer, cmdOut.gcount());
112  return result;
113  }
114 }
static const double ms
[millisecond]
Definition: Unit.h:96
static const double ns
Standard of [time].
Definition: Unit.h:48
static const double s
[second]
Definition: Unit.h:95
double m_startTime
time at start (in ns).
Definition: Utils.h:85
std::string m_text
identifying text (printed at end).
Definition: Utils.h:86
Timer(std::string text="")
Constructor, with some identifying text.
Definition: Utils.cc:88
General utility functions.
Definition: Utils.h:22
std::string getCommandOutput(const std::string &command, const std::vector< std::string > &arguments={}, bool searchPath=true)
Execute a shell command and return its output.
Definition: Utils.cc:99
double getCPUClock()
Return current value of the per-thread CPU clock.
Definition: Utils.cc:71
double getClock()
Return current value of the real-time clock.
Definition: Utils.cc:65
unsigned long getRssMemoryKB()
Returns the amount of memory the process actually occupies in the physical RAM of the machine.
Definition: Utils.cc:83
unsigned long getVirtualMemoryKB()
Returns currently used virtual memory in KB, includes swapped and not occupied memory pages and memor...
Definition: Utils.cc:78
Abstract base class for different kinds of events.