mirror of
https://github.com/aristocratos/btop.git
synced 2024-09-28 22:21:35 +02:00
reduce memleak drastically
This commit is contained in:
parent
682746ff0e
commit
30b33730b3
@ -40,6 +40,7 @@ tab-size = 4
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/vmmeter.h>
|
#include <sys/vmmeter.h>
|
||||||
#include <sys/limits.h>
|
#include <sys/limits.h>
|
||||||
|
#include <vector>
|
||||||
#include <vm/vm_param.h>
|
#include <vm/vm_param.h>
|
||||||
#include <kvm.h>
|
#include <kvm.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
@ -100,6 +101,9 @@ namespace Cpu {
|
|||||||
|
|
||||||
namespace Mem {
|
namespace Mem {
|
||||||
double old_uptime;
|
double old_uptime;
|
||||||
|
std::vector<string> zpools;
|
||||||
|
|
||||||
|
void get_zpools();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Shared {
|
namespace Shared {
|
||||||
@ -169,6 +173,7 @@ namespace Shared {
|
|||||||
//? Init for namespace Mem
|
//? Init for namespace Mem
|
||||||
Mem::old_uptime = system_uptime();
|
Mem::old_uptime = system_uptime();
|
||||||
Mem::collect();
|
Mem::collect();
|
||||||
|
Mem::get_zpools();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Shared
|
} // namespace Shared
|
||||||
@ -245,13 +250,17 @@ namespace Cpu {
|
|||||||
Logger::warning("Could not get temp sensor - maybe you need to load the coretemp module");
|
Logger::warning("Could not get temp sensor - maybe you need to load the coretemp module");
|
||||||
} else {
|
} else {
|
||||||
got_sensors = true;
|
got_sensors = true;
|
||||||
|
int temp;
|
||||||
|
size_t size = sizeof(temp);
|
||||||
|
sysctlbyname("dev.cpu.0.coretemp.tjmax", &temp, &size, NULL, 0); //asuming the max temp is same for all cores
|
||||||
|
temp = (temp - 2732) / 10; // since it's an int, it's multiplied by 10, and offset to absolute zero...
|
||||||
|
current_cpu.temp_max = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return got_sensors;
|
return got_sensors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_sensors() {
|
void update_sensors() {
|
||||||
current_cpu.temp_max = 95; // we have no idea how to get the critical temp
|
|
||||||
int temp;
|
int temp;
|
||||||
size_t size = sizeof(temp);
|
size_t size = sizeof(temp);
|
||||||
sysctlbyname("hw.acpi.thermal.tz0.temperature", &temp, &size, NULL, 0);
|
sysctlbyname("hw.acpi.thermal.tz0.temperature", &temp, &size, NULL, 0);
|
||||||
@ -499,23 +508,35 @@ namespace Mem {
|
|||||||
class PipeWrapper {
|
class PipeWrapper {
|
||||||
public:
|
public:
|
||||||
PipeWrapper(const char *file, const char *mode) {fd = popen(file, mode);}
|
PipeWrapper(const char *file, const char *mode) {fd = popen(file, mode);}
|
||||||
virtual ~PipeWrapper() {std::fclose(fd);}
|
virtual ~PipeWrapper() {if (fd) pclose(fd);}
|
||||||
auto operator()() -> FILE* { return fd;};
|
auto operator()() -> FILE* { return fd;};
|
||||||
private:
|
private:
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// find all zpools in the system. Do this only at startup.
|
||||||
|
void get_zpools() {
|
||||||
|
PipeWrapper poolPipe = PipeWrapper("zpool list -H -o name", "r");
|
||||||
|
while (not std::feof(poolPipe())) {
|
||||||
|
char poolName[512];
|
||||||
|
size_t len = 512;
|
||||||
|
if (fgets(poolName, len, poolPipe())) {
|
||||||
|
poolName[strcspn(poolName, "\n")] = 0;
|
||||||
|
Logger::debug("zpool found: " + string(poolName));
|
||||||
|
Mem::zpools.push_back(poolName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void collect_disk(unordered_flat_map<string, disk_info> &disks, unordered_flat_map<string, string> &mapping) {
|
void collect_disk(unordered_flat_map<string, disk_info> &disks, unordered_flat_map<string, string> &mapping) {
|
||||||
// this bit is for 'regular' mounts
|
// this bit is for 'regular' mounts
|
||||||
static struct statinfo cur, last;
|
static struct statinfo cur;
|
||||||
long double etime = 0;
|
long double etime = 0;
|
||||||
uint64_t total_bytes_read;
|
uint64_t total_bytes_read;
|
||||||
uint64_t total_bytes_write;
|
uint64_t total_bytes_write;
|
||||||
|
|
||||||
static std::unique_ptr<struct devinfo, decltype(std::free)*> curDevInfo (reinterpret_cast<struct devinfo*>(std::calloc(1, sizeof(struct devinfo))), std::free);
|
static std::unique_ptr<struct devinfo, decltype(std::free)*> curDevInfo (reinterpret_cast<struct devinfo*>(std::calloc(1, sizeof(struct devinfo))), std::free);
|
||||||
static std::unique_ptr<struct devinfo, decltype(std::free)*> lastDevInfo (reinterpret_cast<struct devinfo*>(std::calloc(1, sizeof(struct devinfo))), std::free);
|
|
||||||
cur.dinfo = curDevInfo.get();
|
cur.dinfo = curDevInfo.get();
|
||||||
last.dinfo = lastDevInfo.get();
|
|
||||||
|
|
||||||
if (devstat_getdevs(NULL, &cur) != -1) {
|
if (devstat_getdevs(NULL, &cur) != -1) {
|
||||||
for (int i = 0; i < cur.dinfo->numdevs; i++) {
|
for (int i = 0; i < cur.dinfo->numdevs; i++) {
|
||||||
@ -535,29 +556,25 @@ namespace Mem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this code is for ZFS mounts
|
// this code is for ZFS mounts
|
||||||
PipeWrapper poolPipe = PipeWrapper("zpool list -H -o name", "r");
|
for (string poolName : Mem::zpools) {
|
||||||
if (poolPipe()) {
|
|
||||||
while (not std::feof(poolPipe())) {
|
|
||||||
char poolName[512];
|
|
||||||
size_t len = 512;
|
|
||||||
if (fgets(poolName, len, poolPipe())) {
|
|
||||||
poolName[strcspn(poolName, "\n")] = 0;
|
|
||||||
char sysCtl[1024];
|
char sysCtl[1024];
|
||||||
snprintf(sysCtl, sizeof(sysCtl), "sysctl kstat.zfs.%s.dataset", poolName);
|
snprintf(sysCtl, sizeof(sysCtl), "sysctl kstat.zfs.%s.dataset | grep dataset_name", poolName.c_str());
|
||||||
|
Logger::debug(poolName + string("->") + string(sysCtl));
|
||||||
PipeWrapper f = PipeWrapper(sysCtl, "r");
|
PipeWrapper f = PipeWrapper(sysCtl, "r");
|
||||||
if (f()) {
|
if (f()) {
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
size_t len = 512;
|
||||||
while (not std::feof(f())) {
|
while (not std::feof(f())) {
|
||||||
uint64_t nread, nwritten;
|
uint64_t nread, nwritten;
|
||||||
string datasetname; // this is the zfs volume, like 'zroot/usr/home' -> this maps onto the device we get back from getmntinfo(3)
|
|
||||||
if (fgets(buf, len, f())) {
|
if (fgets(buf, len, f())) {
|
||||||
char *name = std::strtok(buf, ": \n");
|
char *name = std::strtok(buf, ": \n");
|
||||||
char *value = std::strtok(NULL, ": \n");
|
char *value = std::strtok(NULL, ": \n");
|
||||||
|
Logger::debug(name + string("=") + string(value));
|
||||||
if (string(name).find("dataset_name") != string::npos) {
|
if (string(name).find("dataset_name") != string::npos) {
|
||||||
// create entry if datasetname matches with anything in mapping
|
// create entry if datasetname matches with anything in mapping
|
||||||
// relies on the fact that the dataset name is last value in the list
|
// relies on the fact that the dataset name is last value in the list
|
||||||
// alternatively you could parse the objset-0x... when this changes, you have a new entry
|
// alternatively you could parse the objset-0x... when this changes, you have a new entry
|
||||||
datasetname = string(value);
|
string datasetname = string(value);// this is the zfs volume, like 'zroot/usr/home' -> this maps onto the device we get back from getmntinfo(3)
|
||||||
if (mapping.contains(datasetname)) {
|
if (mapping.contains(datasetname)) {
|
||||||
string mountpoint = mapping.at(datasetname);
|
string mountpoint = mapping.at(datasetname);
|
||||||
if (disks.contains(mountpoint)) {
|
if (disks.contains(mountpoint)) {
|
||||||
@ -575,8 +592,6 @@ namespace Mem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user