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