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 rewind(stream);
63 fscanf(stream, "%lu %lu", &vmSizePages, &rssPages);
64 return std::make_pair(vmSizePages * pageSizeKb, rssPages * pageSizeKb);
65 }
66}
67
68namespace Belle2::Utils {
69
70 double getClock()
71 {
72 timespec ts;
73 clock_gettime(CLOCK_REALTIME, &ts);
74 return (ts.tv_sec * Unit::s) + (ts.tv_nsec * Unit::ns);
75 }
76 double getCPUClock()
77 {
78 timespec ts;
79 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
80 return (ts.tv_sec * Unit::s) + (ts.tv_nsec * Unit::ns);
81 }
82
83 unsigned long getVirtualMemoryKB()
84 {
85 return getStatmSize().first;
86 }
87
88 unsigned long getRssMemoryKB()
89 {
90 return getStatmSize().second;
91 }
92
93 Timer::Timer(std::string text):
95 m_text(std::move(text))
96 { }
97
98 Timer::~Timer()
99 {
100 double elapsed = (getClock() - m_startTime) / Unit::ms;
101 B2INFO(m_text << " " << std::fixed << std::setprecision(3) << elapsed << " ms");
102 }
103
104 std::string getCommandOutput(const std::string& command, const std::vector<std::string>& arguments,
105 bool searchPath)
106 {
107 namespace bp = boost::process::v1;
108 auto cmd = searchPath ? bp::search_path(command) : boost::filesystem::path(command);
109 bp::ipstream cmdOut;
110 bp::child child(cmd, bp::args(arguments), bp::std_in.close(), bp::std_out > cmdOut);
111 char buffer[4096];
112 std::string result;
113 while (child.running() && cmdOut.read(buffer, sizeof(buffer))) {
114 result.append(buffer, sizeof(buffer));
115 }
116 if (cmdOut.gcount()) result.append(buffer, cmdOut.gcount());
117 return result;
118 }
119}
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:93
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:104
double getCPUClock()
Return current value of the per-thread CPU clock.
Definition Utils.cc:76
double getClock()
Return current value of the real-time clock.
Definition Utils.cc:70
unsigned long getRssMemoryKB()
Returns the amount of memory the process actually occupies in the physical RAM of the machine.
Definition Utils.cc:88
unsigned long getVirtualMemoryKB()
Returns currently used virtual memory in KB, includes swapped and not occupied memory pages and memor...
Definition Utils.cc:83
Abstract base class for different kinds of events.
STL namespace.