Belle II Software  release-08-01-10
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 #include <filesystem>
28 
29 using namespace Belle2;
30 
31 namespace {
41  std::pair<unsigned long, unsigned long> getStatmSize()
42  {
44  const static long pageSizeKb = sysconf(_SC_PAGESIZE) / 1024;
45  static FILE* stream = nullptr;
46  static int pid = 0;
47  int currentPid = getpid();
48  if (currentPid != pid) {
49  pid = currentPid;
50  std::string statm = "/proc/" + std::to_string(pid) + "/statm";
51  stream = fopen(statm.c_str(), "r");
52  // If we use buffering we might get the same value each time we read so
53  // disable buffering
54  setvbuf(stream, nullptr, _IONBF, 0);
55  }
56  unsigned long vmSizePages{0};
57  unsigned long rssPages{0};
58  rewind(stream);
59  fscanf(stream, "%lu %lu", &vmSizePages, &rssPages);
60  return std::make_pair(vmSizePages * pageSizeKb, rssPages * pageSizeKb);
61  }
62 }
63 
64 namespace Belle2::Utils {
65 
66  double getClock()
67  {
68  timespec ts;
69  clock_gettime(CLOCK_REALTIME, &ts);
70  return (ts.tv_sec * Unit::s) + (ts.tv_nsec * Unit::ns);
71  }
72  double getCPUClock()
73  {
74  timespec ts;
75  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
76  return (ts.tv_sec * Unit::s) + (ts.tv_nsec * Unit::ns);
77  }
78 
79  unsigned long getVirtualMemoryKB()
80  {
81  return getStatmSize().first;
82  }
83 
84  unsigned long getRssMemoryKB()
85  {
86  return getStatmSize().second;
87  }
88 
89  Timer::Timer(std::string text):
90  m_startTime(getClock()),
91  m_text(std::move(text))
92  { }
93 
94  Timer::~Timer()
95  {
96  double elapsed = (getClock() - m_startTime) / Unit::ms;
97  B2INFO(m_text << " " << std::fixed << std::setprecision(3) << elapsed << " ms");
98  }
99 
100  std::string getCommandOutput(const std::string& command, const std::vector<std::string>& arguments,
101  bool searchPath)
102  {
103  namespace bp = boost::process;
104  auto cmd = searchPath ? bp::search_path(command) : boost::filesystem::path(command);
105  bp::ipstream cmdOut;
106  bp::child child(cmd, bp::args(arguments), bp::std_in.close(), bp::std_out > cmdOut);
107  char buffer[4096];
108  std::string result;
109  while (child.running() && cmdOut.read(buffer, sizeof(buffer))) {
110  result.append(buffer, sizeof(buffer));
111  }
112  if (cmdOut.gcount()) result.append(buffer, cmdOut.gcount());
113  return result;
114  }
115 }
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:89
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:100
double getCPUClock()
Return current value of the per-thread CPU clock.
Definition: Utils.cc:72
double getClock()
Return current value of the real-time clock.
Definition: Utils.cc:66
unsigned long getRssMemoryKB()
Returns the amount of memory the process actually occupies in the physical RAM of the machine.
Definition: Utils.cc:84
unsigned long getVirtualMemoryKB()
Returns currently used virtual memory in KB, includes swapped and not occupied memory pages and memor...
Definition: Utils.cc:79
Abstract base class for different kinds of events.