feat add profiling

This commit is contained in:
tqcq
2024-03-16 22:56:10 +08:00
parent e05c1f4894
commit 719fecd4bc
30 changed files with 4673 additions and 1 deletions

View File

@@ -0,0 +1,100 @@
// Software Name : cppuprofile
// SPDX-FileCopyrightText: Copyright (c) 2022 Orange
// SPDX-License-Identifier: BSD-3-Clause
//
// This software is distributed under the BSD License;
// see the LICENSE file for more details.
//
// Author: Cédric CHEDALEUX <cedric.chedaleux@orange.com> et al.
#include "cpumonitor.h"
#include <fstream>
#include <sstream>
using namespace std;
uprofile::CpuMonitor::CpuMonitor() :
m_nbCpus(getNumberOfCPUCores())
{
m_lastIdleTimes.resize(m_nbCpus, 0);
m_lastTotalTimes.resize(m_nbCpus, 0);
}
uprofile::CpuMonitor::~CpuMonitor()
{
}
size_t uprofile::CpuMonitor::getNumberOfCPUCores()
{
size_t nbCores = 0;
#if defined(__linux__)
ifstream meminfo("/proc/cpuinfo");
string str;
while (getline(meminfo, str)) {
if (str.rfind("processor", 0) == 0) {
nbCores++;
}
}
#endif
return nbCores;
}
void uprofile::CpuMonitor::extractCpuTimes(const string& cpuInfo, size_t& idleTime, size_t& totalTime)
{
// Remove 'cpu<index' word and
// extract the idle time and sum all other times
size_t spacePos = cpuInfo.find(' ');
if (spacePos == string::npos) {
return;
}
stringstream times(cpuInfo.substr(spacePos + 1));
int index = 0;
for (size_t time; times >> time; ++index) {
if (index == 3) { // idle time i s the 4th param
idleTime = time;
}
totalTime += time;
}
}
vector<float> uprofile::CpuMonitor::getUsage()
{
vector<float> usages;
#if defined(__linux__)
ifstream procStat("/proc/stat");
// /proc/stat dumps the following info:
// user nice system idle iowait irq softirq
// cpu 2255 34 2290 22625563 6290 127 456
// cpu0 1132 34 1441 11311718 3675 127 438
// cpu1 1123 0 849 11313845 2614 0 18
// ...
// Each numbers represents the amount of time the CPU has spent performing
// different kind of work
for (size_t cpuIndex = 0; cpuIndex < m_nbCpus; ++cpuIndex) {
string cpuName("cpu");
cpuName += to_string(cpuIndex);
// Look in /proc/stack the CPU info
string line;
while (getline(procStat, line)) {
if (line.find(cpuName) != std::string::npos) {
size_t idleTime = 0, totalTime = 0;
extractCpuTimes(line, idleTime, totalTime);
// To compute CPU load, we compute the time the CPU has been idle since the last read.
float cpuLoad = 100.0 * (1.0 - (float)(idleTime - m_lastIdleTimes[cpuIndex]) / (totalTime - m_lastTotalTimes[cpuIndex]));
usages.push_back(cpuLoad);
// Save the times value for the next read
m_lastIdleTimes[cpuIndex] = idleTime;
m_lastTotalTimes[cpuIndex] = totalTime;
break;
}
}
}
#endif
return usages;
}

View File

@@ -0,0 +1,41 @@
// Software Name : cppuprofile
// SPDX-FileCopyrightText: Copyright (c) 2022 Orange
// SPDX-License-Identifier: BSD-3-Clause
//
// This software is distributed under the BSD License;
// see the LICENSE file for more details.
//
// Author: Cédric CHEDALEUX <cedric.chedaleux@orange.com> et al.
#ifndef CPUMONITOR_H_
#define CPUMONITOR_H_
#include <string>
#include <vector>
using namespace std;
namespace uprofile
{
class CpuMonitor
{
public:
explicit CpuMonitor();
virtual ~CpuMonitor();
vector<float> getUsage();
private:
static size_t getNumberOfCPUCores();
static void extractCpuTimes(const string& cpuInfo, size_t& idleTime, size_t& totalTime);
// Store the last idle and total time for each CPU
vector<size_t> m_lastIdleTimes;
vector<size_t> m_lastTotalTimes;
size_t m_nbCpus;
};
}
#endif /* CPUMONITOR_H_ */

View File

@@ -0,0 +1,64 @@
// Software Name : cppuprofile
// SPDX-FileCopyrightText: Copyright (c) 2022 Orange
// SPDX-License-Identifier: BSD-3-Clause
//
// This software is distributed under the BSD License;
// see the LICENSE file for more details.
//
// Author: Cédric CHEDALEUX <cedric.chedaleux@orange.com> et al.
#include "timer.h"
Timer::Timer(int interval) :
m_th(NULL),
m_interval(interval)
{
}
Timer::~Timer()
{
stop();
}
void Timer::setInterval(int interval)
{
m_interval = interval;
}
void Timer::setTimeout(const std::function<void(void)>& timeout)
{
m_timeout = timeout;
}
bool Timer::isRunning()
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_running;
}
void Timer::start()
{
if (m_interval > 0 && m_th == NULL) {
m_running = true;
m_th = new thread([=]() {
while (isRunning()) {
this_thread::sleep_for(chrono::milliseconds(m_interval));
if (m_timeout) {
m_timeout();
}
}
});
}
}
void Timer::stop()
{
m_mutex.lock();
m_running = false;
m_mutex.unlock();
if (m_th) {
m_th->join();
delete m_th;
m_th = NULL;
}
}

View File

@@ -0,0 +1,41 @@
// Software Name : cppuprofile
// SPDX-FileCopyrightText: Copyright (c) 2022 Orange
// SPDX-License-Identifier: BSD-3-Clause
//
// This software is distributed under the BSD License;
// see the LICENSE file for more details.
//
// Author: Cédric CHEDALEUX <cedric.chedaleux@orange.com> et al.
#ifndef TIMER_H_
#define TIMER_H_
#include <chrono>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
class Timer
{
public:
explicit Timer(int interval /* ms */ = 0);
virtual ~Timer();
void setTimeout(const function<void(void)>& timeout);
void setInterval(int interval);
void start();
void stop();
bool isRunning();
private:
thread* m_th;
bool m_running;
int m_interval;
std::mutex m_mutex;
std::function<void(void)> m_timeout;
};
#endif // TIMER_H_