mirror of
https://github.com/Llewellynvdm/conky.git
synced 2025-01-29 01:58:26 +00:00
NetBSD: Fix CPU Usage.
Report the correct number of CPUs and calculate the per-CPU load. Start implementing a common BSD interface, as all BSD implementations use *slightly* different functions to achieve the same goal, and maintaining them in one place would be easier. Fixes #2097.
This commit is contained in:
parent
d0247218a8
commit
e9f343ffee
@ -174,7 +174,7 @@ if(OS_SOLARIS)
|
||||
endif(OS_SOLARIS)
|
||||
|
||||
if(OS_NETBSD)
|
||||
set(netbsd netbsd.cc netbsd.h)
|
||||
set(netbsd netbsd.cc netbsd.h bsdcommon.cc bsdcommon.h)
|
||||
set(optional_sources ${optional_sources} ${netbsd})
|
||||
endif(OS_NETBSD)
|
||||
|
||||
|
163
src/bsdcommon.cc
Normal file
163
src/bsdcommon.cc
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
*
|
||||
* Conky, a system monitor, based on torsmo
|
||||
*
|
||||
* Please see COPYING for details
|
||||
*
|
||||
* Copyright (c) 2005-2024 Brenden Matthews, Philip Kovacs, et. al.
|
||||
* (see AUTHORS)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bsdcommon.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include <kvm.h>
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static kvm_t *kd = nullptr;
|
||||
static bool kvm_initialised = false;
|
||||
static bool cpu_initialised = false;
|
||||
|
||||
static struct bsdcommon::cpu_load *cpu_loads = nullptr;
|
||||
|
||||
bool bsdcommon::init_kvm() {
|
||||
if (kvm_initialised) {
|
||||
return true;
|
||||
}
|
||||
|
||||
kd = kvm_open(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr);
|
||||
if (kd == nullptr) {
|
||||
NORM_ERR("opening kvm");
|
||||
return false;
|
||||
}
|
||||
|
||||
kvm_initialised = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void bsdcommon::deinit_kvm() {
|
||||
if (!kvm_initialised || kd == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
kvm_close(kd);
|
||||
}
|
||||
|
||||
void bsdcommon::get_cpu_count(float **cpu_usage, unsigned int *cpu_count) {
|
||||
int ncpu = 1;
|
||||
int mib[2] = {CTL_HW, HW_NCPU};
|
||||
size_t len = sizeof(ncpu);
|
||||
|
||||
if (sysctl(mib, 2, &ncpu, &len, nullptr, 0) != 0) {
|
||||
NORM_ERR("error getting kern.ncpu, defaulting to 1");
|
||||
ncpu = 1;
|
||||
}
|
||||
|
||||
if (*cpu_count != ncpu) {
|
||||
*cpu_count = ncpu;
|
||||
|
||||
if (*cpu_usage != nullptr) {
|
||||
free(*cpu_usage);
|
||||
*cpu_usage = nullptr;
|
||||
}
|
||||
|
||||
if (cpu_loads != nullptr) {
|
||||
free(cpu_loads);
|
||||
cpu_loads = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (*cpu_usage == nullptr) {
|
||||
// [0] - Total CPU
|
||||
// [1, 2, ... ] - CPU1, CPU2, ...
|
||||
*cpu_usage = (float*)calloc(ncpu + 1, sizeof(float));
|
||||
if (*cpu_usage == nullptr) {
|
||||
CRIT_ERR("calloc of cpu_usage");
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu_loads == nullptr) {
|
||||
cpu_loads = (struct cpu_load*)calloc(ncpu + 1, sizeof(struct cpu_load));
|
||||
if (cpu_loads == nullptr) {
|
||||
CRIT_ERR("calloc of cpu_loads");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bsdcommon::update_cpu_usage(float **cpu_usage, unsigned int *cpu_count) {
|
||||
uint64_t cp_time0[CPUSTATES];
|
||||
int mib_cpu0[2] = {CTL_KERN, KERN_CP_TIME};
|
||||
uint64_t cp_timen[CPUSTATES];
|
||||
int mib_cpun[3] = {CTL_KERN, KERN_CP_TIME, 0};
|
||||
size_t size = 0;
|
||||
u_int64_t used = 0, total = 0;
|
||||
|
||||
if (!cpu_initialised) {
|
||||
get_cpu_count(cpu_usage, cpu_count);
|
||||
cpu_initialised = true;
|
||||
}
|
||||
|
||||
size = sizeof(cp_time0);
|
||||
if (sysctl(mib_cpu0, 2, &cp_time0, &size, nullptr, 0) != 0) {
|
||||
NORM_ERR("unable to get kern.cp_time for cpu0");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int j = 0; j < CPUSTATES; ++j) {
|
||||
total += cp_time0[j];
|
||||
}
|
||||
used = total - cp_time0[CP_IDLE];
|
||||
|
||||
if ((total - cpu_loads[0].old_total) != 0) {
|
||||
const float diff_used = (float)(used - cpu_loads[0].old_used);
|
||||
const float diff_total = (float)(total - cpu_loads[0].old_total);
|
||||
(*cpu_usage)[0] = diff_used / diff_total;
|
||||
} else {
|
||||
(*cpu_usage)[0] = 0;
|
||||
}
|
||||
cpu_loads[0].old_used = used;
|
||||
cpu_loads[0].old_total = total;
|
||||
|
||||
for (int i = 0; i < *cpu_count; ++i) {
|
||||
mib_cpun[2] = i;
|
||||
size = sizeof(cp_timen);
|
||||
if (sysctl(mib_cpun, 3, &cp_timen, &size, nullptr, 0) != 0) {
|
||||
NORM_ERR("unable to get kern.cp_time for cpu%d", i);
|
||||
return;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
used = 0;
|
||||
for (int j = 0; j < CPUSTATES; ++j) {
|
||||
total += cp_timen[j];
|
||||
}
|
||||
used = total - cp_timen[CP_IDLE];
|
||||
|
||||
const int n = i + 1; // [0] is the total CPU, must shift by 1
|
||||
if ((total - cpu_loads[n].old_total) != 0) {
|
||||
const float diff_used = (float)(used - cpu_loads[n].old_used);
|
||||
const float diff_total = (float)(total - cpu_loads[n].old_total);
|
||||
(*cpu_usage)[n] = diff_used / diff_total;
|
||||
} else {
|
||||
(*cpu_usage)[n] = 0;
|
||||
}
|
||||
|
||||
cpu_loads[n].old_used = used;
|
||||
cpu_loads[n].old_total = total;
|
||||
}
|
||||
}
|
49
src/bsdcommon.h
Normal file
49
src/bsdcommon.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
*
|
||||
* Conky, a system monitor, based on torsmo
|
||||
*
|
||||
* Please see COPYING for details
|
||||
*
|
||||
* Copyright (c) 2005-2024 Brenden Matthews, Philip Kovacs, et. al.
|
||||
* (see AUTHORS)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Shared or very similar code across BSDs.
|
||||
*/
|
||||
|
||||
#ifndef BSDCOMMON_H_
|
||||
#define BSDCOMMON_H_
|
||||
|
||||
#define BSD_COMMON
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace bsdcommon {
|
||||
struct cpu_load {
|
||||
uint64_t old_used;
|
||||
uint64_t old_total;
|
||||
};
|
||||
|
||||
bool init_kvm();
|
||||
void deinit_kvm();
|
||||
|
||||
void get_cpu_count(float **cpu_usage, unsigned int *cpu_count);
|
||||
void update_cpu_usage(float **cpu_usage, unsigned int *cpu_count);
|
||||
};
|
||||
|
||||
#endif /*BSDCOMMON_H_*/
|
@ -52,6 +52,10 @@
|
||||
#include "freebsd.h"
|
||||
#endif /* FreeBSD */
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
#include "netbsd.h"
|
||||
#endif /* NetBSD */
|
||||
|
||||
#if defined(__HAIKU__)
|
||||
#include "haiku.h"
|
||||
#endif /* Haiku */
|
||||
@ -411,6 +415,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
conky::shutdown_display_outputs();
|
||||
|
||||
#ifdef BSD_COMMON
|
||||
bsdcommon::deinit_kvm();
|
||||
#endif
|
||||
|
||||
//TODO(gmb): Move this to bsdcommon and remove external kd.
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
kvm_close(kd);
|
||||
#endif
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "netbsd.h"
|
||||
#include "net_stat.h"
|
||||
#include "bsdcommon.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
@ -53,23 +54,10 @@
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
static kvm_t *kd = nullptr;
|
||||
static int kd_init = 0, nkd_init = 0, cpu_setup = 0;
|
||||
static int nkd_init = 0;
|
||||
static u_int32_t sensvalue;
|
||||
static char errbuf[_POSIX2_LINE_MAX];
|
||||
|
||||
static int init_kvm(void) {
|
||||
if (kd_init) { return 0; }
|
||||
|
||||
kd = kvm_openfiles(nullptr, NULL, NULL, KVM_NO_FILES, errbuf);
|
||||
if (kd == nullptr) {
|
||||
NORM_ERR("cannot kvm_openfiles: %s", errbuf);
|
||||
return -1;
|
||||
}
|
||||
kd_init = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int swapmode(int *retavail, int *retfree) {
|
||||
int n;
|
||||
struct swapent *sep;
|
||||
@ -243,6 +231,8 @@ int update_net_stats() {
|
||||
int update_total_processes() {
|
||||
/* It's easier to use kvm here than sysctl */
|
||||
|
||||
// TODO(gmb): Use bsdcommon.
|
||||
/*
|
||||
int n_processes;
|
||||
|
||||
info.procs = 0;
|
||||
@ -255,10 +245,14 @@ int update_total_processes() {
|
||||
}
|
||||
|
||||
info.procs = n_processes;
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
int update_running_processes() {
|
||||
|
||||
// TODO(gmb): Use bsdcommon.
|
||||
/*
|
||||
struct kinfo_proc2 *p;
|
||||
int n_processes;
|
||||
int i, cnt = 0;
|
||||
@ -279,56 +273,16 @@ int update_running_processes() {
|
||||
}
|
||||
|
||||
info.run_procs = cnt;
|
||||
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct cpu_load_struct {
|
||||
unsigned long load[5];
|
||||
};
|
||||
|
||||
struct cpu_load_struct fresh = {{0, 0, 0, 0, 0}};
|
||||
|
||||
long cpu_used, oldtotal, oldused;
|
||||
|
||||
// TODO(gmb): Implement support for multiple processors.
|
||||
void get_cpu_count(void) {
|
||||
int cpu_count = 1;
|
||||
info.cpu_count = cpu_count;
|
||||
info.cpu_usage = (float *)malloc((info.cpu_count + 1) * sizeof(float));
|
||||
if (info.cpu_usage == nullptr) { CRIT_ERR("malloc"); }
|
||||
bsdcommon::get_cpu_count(&info.cpu_usage, &info.cpu_count);
|
||||
}
|
||||
|
||||
// TODO(gmb): Implement support for multiple processors.
|
||||
int update_cpu_usage() {
|
||||
long used, total;
|
||||
static u_int64_t cp_time[CPUSTATES];
|
||||
size_t len = sizeof(cp_time);
|
||||
|
||||
info.cpu_usage[0] = 0;
|
||||
|
||||
if (sysctlbyname("kern.cp_time", &cp_time, &len, nullptr, 0) < 0) {
|
||||
NORM_ERR("cannot get kern.cp_time");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fresh.load[0] = cp_time[CP_USER];
|
||||
fresh.load[1] = cp_time[CP_NICE];
|
||||
fresh.load[2] = cp_time[CP_SYS];
|
||||
fresh.load[3] = cp_time[CP_IDLE];
|
||||
fresh.load[4] = cp_time[CP_IDLE];
|
||||
|
||||
used = fresh.load[0] + fresh.load[1] + fresh.load[2];
|
||||
total = fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
|
||||
|
||||
if ((total - oldtotal) != 0) {
|
||||
info.cpu_usage[0] = ((float)(used - oldused)) / (float)(total - oldtotal);
|
||||
} else {
|
||||
info.cpu_usage[0] = 0;
|
||||
}
|
||||
|
||||
oldused = used;
|
||||
oldtotal = total;
|
||||
bsdcommon::update_cpu_usage(&info.cpu_usage, &info.cpu_count);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "common.h"
|
||||
#include "conky.h"
|
||||
|
||||
#include "bsdcommon.h"
|
||||
|
||||
int get_entropy_avail(unsigned int *);
|
||||
int get_entropy_poolsize(unsigned int *);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user