Implementar CpuMon al completo

Signed-off-by: somebody_master <somebody_master@somebodyserver.mooo.com>
This commit is contained in:
Somebody Master 2021-05-12 01:41:06 +02:00
parent 1f07cd4a0d
commit c505350e6d
Signed by: somebody_master
GPG Key ID: 78315CFDF0B25505
6 changed files with 246 additions and 7 deletions

View File

@ -45,6 +45,7 @@ target_include_directories(config PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_include_directories(cpu_mon PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries("${PROJECT_NAME}" PRIVATE ncurses)
target_link_libraries("${PROJECT_NAME}" PRIVATE pthread)
target_link_libraries("${PROJECT_NAME}" PRIVATE ui)
target_link_libraries("${PROJECT_NAME}" PRIVATE config)
target_link_libraries("${PROJECT_NAME}" PRIVATE cpu_mon)

View File

@ -1,5 +1,7 @@
#include "ui.hpp"
#include <string>
#include <vector>
#ifdef _WIN32
#include <Windows.h>
#else
@ -8,12 +10,50 @@
#ifndef CPU_MON_HPP_
#define CPU_MON_HPP_
const int NUM_ESTADOS_CPU = 10;
enum EstadosCPU {
S_USER = 0,
S_NICE,
S_SYSTEM,
S_IDLE,
S_IOWAIT,
S_IRQ,
S_SOFTIRQ,
S_STEAL,
S_GUEST,
S_GUEST_NICE
};
typedef struct DatosCPU {
std::string cpu;
size_t times[NUM_ESTADOS_CPU];
} DatosCPU;
class CpuMon {
private:
int8_t num_hilos;
uint8_t num_hilos;
uint8_t num_sectores;
int columnas;
WINDOW *ventanaMonitorCPU;
static void esperar(int segundos);
bool enFuncionamiento;
public:
CpuMon(int8_t num_hilos);
CpuMon(uint8_t num_hilos, WINDOW *ventanaMonitorCPU);
void iniciarCPU_MON();
void pararCPU_MON();
// int getColumnas();
// uint8_t getNum_sectores();
size_t getTiempoInactivo(const DatosCPU &e);
size_t getTiempoActivo(const DatosCPU &e);
void leerEstadoCPU(std::vector<DatosCPU> &entradas);
void obtenerUsoCPU(const std::vector<DatosCPU> &entradas1,
const std::vector<DatosCPU> &entradas2);
void setEnfuncionamiento(bool enFuncionamiento);
std::string obtenerBarra(float *porcentaje, uint8_t *cpu);
void setNum_sectores(uint8_t num_sectores);
};
#endif // CPU_MON_HPP_

View File

@ -27,5 +27,11 @@ void showCenterMensaje(std::vector<std::string> *mensaje,
const uint8_t *menu_color);
void showTopTitle(const std::vector<std::string> *titulo);
void mostrarVentana(WINDOW *ventana, std::vector<std::string> *texto,
int *ancho, uint8_t *sectores);
void borrarVentana(WINDOW *ventana);
} // namespace ui
#endif // __UI_HPP_

View File

@ -1,12 +1,173 @@
#include "cpu_mon.hpp"
CpuMon::CpuMon(int8_t num_hilos) { CpuMon::num_hilos = num_hilos; }
#include <chrono>
#include <fstream>
#include <iostream>
#include <sstream>
#include <thread>
CpuMon::CpuMon(uint8_t num_hilos, WINDOW *ventanaMonitorCPU) {
CpuMon::num_hilos = num_hilos;
CpuMon::ventanaMonitorCPU = ventanaMonitorCPU;
CpuMon::enFuncionamiento = true;
void CpuMon::iniciarCPU_MON() {
int columnas = ui::g_maxCols / 2;
int lineas = ui::g_maxLines;
uint8_t num_sectores = 1;
int lineas = ui::g_maxLines;
while (lineas < (CpuMon::num_hilos / num_sectores)) {
num_sectores++;
}
CpuMon::num_sectores = num_sectores;
CpuMon::columnas = (ui::g_maxCols / 2) / CpuMon::num_sectores;
}
void CpuMon::esperar(int segundos) {
std::this_thread::sleep_for(std::chrono::seconds(segundos));
}
void CpuMon::setNum_sectores(uint8_t num_sectores) {
CpuMon::num_sectores = num_sectores;
}
void CpuMon::iniciarCPU_MON() {
std::vector<DatosCPU> entries1;
std::vector<DatosCPU> entries2;
while (CpuMon::enFuncionamiento) {
std::thread dormir(CpuMon::esperar, 1);
// snapshot 1
leerEstadoCPU(entries1);
// 100ms pause
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// snapshot 2
leerEstadoCPU(entries2);
// print output
obtenerUsoCPU(entries1, entries2);
dormir.join();
}
ui::borrarVentana(CpuMon::ventanaMonitorCPU);
}
void CpuMon::pararCPU_MON() { CpuMon::enFuncionamiento = false; }
// int CpuMon::getColumnas() { return CpuMon::columnas; }
// uint8_t CpuMon::getNum_sectores() { return CpuMon::num_sectores; }
void CpuMon::setEnfuncionamiento(bool enFuncionamiento) {
CpuMon::enFuncionamiento = enFuncionamiento;
}
void CpuMon::leerEstadoCPU(std::vector<DatosCPU> &entradas) {
std::ifstream fileStat("/proc/stat");
std::string linea;
const std::string STR_CPU("cpu");
const std::size_t LEN_STR_CPU = STR_CPU.size();
const std::string STR_TOT("tot");
while (std::getline(fileStat, linea)) {
// cpu stats line found
if (!linea.compare(0, LEN_STR_CPU, STR_CPU)) {
std::istringstream ss(linea);
// store entry
entradas.emplace_back(DatosCPU());
DatosCPU &entry = entradas.back();
// read cpu label
ss >> entry.cpu;
// remove "cpu" from the label when it's a processor number
if (entry.cpu.size() > LEN_STR_CPU)
entry.cpu.erase(0, LEN_STR_CPU);
// replace "cpu" with "tot" when it's total values
else
entry.cpu = STR_TOT;
// read times
for (int i = 0; i < NUM_ESTADOS_CPU; ++i)
ss >> entry.times[i];
}
}
}
size_t CpuMon::getTiempoInactivo(const DatosCPU &e) {
return e.times[S_IDLE] + e.times[S_IOWAIT];
}
size_t CpuMon::getTiempoActivo(const DatosCPU &e) {
return e.times[S_USER] + e.times[S_NICE] + e.times[S_SYSTEM] +
e.times[S_IRQ] + e.times[S_SOFTIRQ] + e.times[S_STEAL] +
e.times[S_GUEST] + e.times[S_GUEST_NICE];
}
void CpuMon::obtenerUsoCPU(const std::vector<DatosCPU> &entradas1,
const std::vector<DatosCPU> &entradas2) {
const size_t NUM_ENTRADAS = entradas1.size();
std::vector<std::string> salida(CpuMon::num_hilos);
// Comienza en 1 para saltarse el total
for (uint8_t i = 1; i < NUM_ENTRADAS; ++i) {
const DatosCPU &e1 = entradas1[i];
const DatosCPU &e2 = entradas2[i];
std::cout.width(3);
std::cout << e1.cpu << "] ";
const float TIEMPO_ACTIVO =
static_cast<float>(getTiempoActivo(e2) - getTiempoActivo(e1));
const float TIEMPO_INACTIVO =
static_cast<float>(getTiempoInactivo(e2) - getTiempoInactivo(e1));
const float TIEMPO_TOTAL = TIEMPO_ACTIVO + TIEMPO_INACTIVO;
float usoCPU = 1.f * TIEMPO_ACTIVO / TIEMPO_TOTAL;
salida[i - 1] = CpuMon::obtenerBarra(&usoCPU, &i);
}
ui::mostrarVentana(ventanaMonitorCPU, &salida, &columnas, &num_sectores);
}
std::string CpuMon::obtenerBarra(float *porcentaje, uint8_t *cpu) {
std::string barra = " CPU ";
if (CpuMon::num_hilos > 9 && *cpu < 10) {
barra.append("0").append(std::to_string(*cpu).append(" ["));
} else {
barra.append(std::to_string(*cpu).append(" ["));
}
std::string cierre = "] ";
cierre.append(std::to_string((int)(100 * *porcentaje)));
cierre.append(" %% ");
// El ancho se calcula con el ancho máximo menos la longitud de los caracteres
// iniciales y menos los carateres de cierre.
int ancho = CpuMon::columnas - barra.length() - cierre.length() - 3;
// Bucle para almohadillas
for (uint16_t i = 0; i < (int)(ancho * *porcentaje); i++) {
barra.append("#");
}
// Bucle para guiones
int num_veces = (int)(ancho - (ancho * *porcentaje));
if (*porcentaje == 0) {
num_veces--;
}
for (uint16_t i = 0; i < num_veces; i++) {
barra.append("-");
}
barra.append(cierre);
return barra;
}

View File

@ -46,6 +46,8 @@ void showMenu(vector<string> *menu_elems, const uint8_t *num_menu,
void showMenu(vector<string> *menu_elems, const uint8_t *num_menu,
Config *config);
void monitorHilo(CpuMon monitor) { monitor.iniciarCPU_MON(); }
int main(int argc, char *argv[]) {
txt::inicializarIdioma(setlocale(LC_ALL, ""));
@ -84,7 +86,17 @@ void userInterface(const uint8_t *num_menu, vector<string> *mensaje,
/*TODO
*Lleva al menú principal
*/
// CpuMon monitor = CpuMon(std::thread::hardware_concurrency());
CpuMon monitor =
CpuMon(std::thread::hardware_concurrency(),
newwin(ui::g_maxLines - (TITULO_PRINCIPAL.size() + 4),
ui::g_maxCols / 2 - 1, TITULO_PRINCIPAL.size() + 4,
ui::g_maxCols - ui::g_maxCols / 2 - 1));
std::thread monHilo(monitorHilo, monitor);
sleep(10);
monitor.setEnfuncionamiento(false);
vector<string> elem_menu = {txt::g_menuPrincipal_1, txt::g_menuPrincipal_2,
txt::g_menuPrincipal_3};
showMenu(&elem_menu, &MENU_PRINCIPAL, mensaje, config);

View File

@ -135,3 +135,22 @@ void ui::showTopTitle(const vector<string> *titulo) {
attroff(A_BOLD);
wrefresh(topTitleWin);
}
void ui::borrarVentana(WINDOW *ventana) {
wborder(ventana, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ');
wrefresh(ventana);
delwin(ventana);
}
void ui::mostrarVentana(WINDOW *ventana, std::vector<std::string> *texto,
int *ancho, uint8_t *sectores) {
attron(A_BOLD);
box(ventana, 0, 0);
for (uint8_t i = 1; i < *sectores + 1; i++) {
for (uint8_t j = 0; j < texto->size(); j++) {
mvwprintw(ventana, j + 1, *ancho - *ancho / i + 1, texto->at(j).c_str());
}
}
attroff(A_BOLD);
wrefresh(ventana);
}