Sysinfo Gadgets: Add sysctl/bsd support to the remaining sysinfo gadgets.

These gadgets include cpumonitor, memusage, and netstatus
This commit is contained in:
Al 'netstar' Poole 2017-02-15 15:48:09 -06:00 committed by Stephen 'Okra' Houston
parent 6becc2b179
commit 784ebcb187
10 changed files with 537 additions and 4 deletions

View File

@ -44,22 +44,34 @@ else
if HAVE_OPENBSD
src_modules_sysinfo_module_la_SOURCES += src/modules/sysinfo/batman/batman_sysctl.c \
src/modules/sysinfo/thermal/thermal_sysctl.c \
src/modules/sysinfo/cpuclock/cpuclock_sysctl.c
src/modules/sysinfo/cpuclock/cpuclock_sysctl.c \
src/modules/sysinfo/netstatus/netstatus_sysctl.c \
src/modules/sysinfo/cpumonitor/cpumonitor_sysctl.c \
src/modules/sysinfo/memusage/memusage_sysctl.c
else
if HAVE_NETBSD
src_modules_sysinfo_module_la_SOURCES += src/modules/sysinfo/batman/batman_sysctl.c \
src/modules/sysinfo/thermal/thermal_sysctl.c \
src/modules/sysinfo/cpuclock/cpuclock_sysctl.c
src/modules/sysinfo/cpuclock/cpuclock_sysctl.c \
src/modules/sysinfo/netstatus/netstatus_sysctl.c \
src/modules/sysinfo/cpumonitor/cpumonitor_sysctl.c \
src/modules/sysinfo/memusage/memusage_sysctl.c
else
if HAVE_DRAGONFLY
src_modules_sysinfo_module_la_SOURCES += src/modules/sysinfo/batman/batman_sysctl.c \
src/modules/sysinfo/thermal/thermal_sysctl.c \
src/modules/sysinfo/cpuclock/cpuclock_sysctl.c
src/modules/sysinfo/cpuclock/cpuclock_sysctl.c \
src/modules/sysinfo/netstatus/netstatus_sysctl.c \
src/modules/sysinfo/cpumonitor/cpumonitor_sysctl.c \
src/modules/sysinfo/memusage/memusage_sysctl.c
else
if HAVE_FREEBSD
src_modules_sysinfo_module_la_SOURCES += src/modules/sysinfo/batman/batman_sysctl.c \
src/modules/sysinfo/thermal/thermal_sysctl.c \
src/modules/sysinfo/cpuclock/cpuclock_sysctl.c
src/modules/sysinfo/cpuclock/cpuclock_sysctl.c \
src/modules/sysinfo/netstatus/netstatus_sysctl.c \
src/modules/sysinfo/cpumonitor/cpumonitor_sysctl.c \
src/modules/sysinfo/memusage/memusage_sysctl.c
else
src_modules_sysinfo_module_la_SOURCES += src/modules/sysinfo/batman/batman_upower.c \
src/modules/sysinfo/thermal/thermal_sysctl.c \

View File

@ -160,7 +160,11 @@ _cpumonitor_cb_usage_check_main(void *data, Ecore_Thread *th)
for (;;)
{
if (ecore_thread_check(th)) break;
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
_cpumonitor_sysctl_getusage(thc->inst);
#else
_cpumonitor_proc_getusage(thc->inst);
#endif
ecore_thread_feedback(th, NULL);
if (ecore_thread_check(th)) break;
usleep((1000000.0 / 8.0) * (double)thc->interval);
@ -226,7 +230,11 @@ _cpumonitor_config_updated(Instance *inst)
{
thc->inst = inst;
thc->interval = inst->cfg->cpumonitor.poll_interval;
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
thc->cores = _cpumonitor_sysctl_getcores();
#else
thc->cores = _cpumonitor_proc_getcores();
#endif
for (i = 0; i < thc->cores; i++)
{
core = E_NEW(CPU_Core, 1);

View File

@ -6,5 +6,7 @@
void _cpumonitor_config_updated(Instance *inst);
int _cpumonitor_proc_getcores(void);
void _cpumonitor_proc_getusage(Instance *inst);
int _cpumonitor_sysctl_getcores(void);
void _cpumonitor_sysctl_getusage(Instance *inst);
Evas_Object *cpumonitor_configure(Instance *inst);
#endif

View File

@ -0,0 +1,140 @@
#include "cpumonitor.h"
#if defined(__FreeBSD__) || defined (__DragonFly__)
# include <sys/types.h>
# include <sys/sysctl.h>
# define CPU_STATES 5
#endif
#if defined(__OpenBSD__)
# include <sys/sysctl.h>
# define CPU_STATES 6
#endif
int
_cpumonitor_sysctl_getcores(void)
{
int cores = 0;
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
size_t len;
int mib[2] = { CTL_HW, HW_NCPU };
len = sizeof(cores);
if (sysctl(mib, 2, &cores, &len, NULL, 0) < 0) return 0;
#endif
return cores;
}
void
_cpumonitor_sysctl_getusage(Instance *inst)
{
CPU_Core *core;
size_t size;
unsigned long percent_all = 0, total_all = 0, idle_all = 0;
int i, j;
#if defined(__FreeBSD__) || defined(__DragonFly__)
int ncpu = _cpumonitor_sysctl_getcores();
if (!ncpu) return;
size = sizeof(long) * (CPU_STATES * ncpu);
long cpu_times[ncpu][CPU_STATES];
if (sysctlbyname("kern.cp_times", cpu_times, &size, NULL, 0) < 0)
return;
for (i = 0; i < ncpu; i++)
{
long *cpu = cpu_times[i];
double total = 0;
for (j = 0; j < CPU_STATES; j++)
total += cpu[j];
double used = total - (cpu[4]); // + cpu[2] + cpu[1] + cpu[0]);
double ratio = (float) total / 100.0;
double percent = ((double)used / (double)ratio);
if (percent > 100)
percent = 100;
else if (percent < 0)
percent = 0;
core = eina_list_nth(inst->cfg->cpumonitor.cores, i);
core->percent = (int) percent;
core->total = total;
core->idle = cpu[4];
percent_all += (int) percent;
total_all += total;
idle_all += core->idle;
}
inst->cfg->cpumonitor.total = total_all / ncpu;
inst->cfg->cpumonitor.idle = idle_all / ncpu;
inst->cfg->cpumonitor.percent = (int) (percent_all / ncpu);
#elif defined(__OpenBSD__)
int ncpu = _cpumonitor_sysctl_getcores();
if (!ncpu) return;
if (ncpu == 1)
{
long cpu_times[CPU_STATES];
int cpu_time_mib[] = { CTL_KERN, KERN_CPTIME };
size = CPU_STATES * sizeof(long);
if (sysctl(cpu_time_mib, 2, &cpu_times, &size, NULL, 0) < 0)
return;
long total = 0;
for (j = 0; j < CPU_STATES; j++)
total += cpu_times[j];
//user", "nice", "system", "interrupt", "idle", NULL
long used = total - cpu_times[0] + cpu_times[1] + cpu_times[2] + cpu_times[3];
double ratio = (double) total / 100.0;
double percent = 100.0 - ((double) used / (double) ratio);
if (percent > 100)
percent = 100;
else if (percent < 0)
percent = 0;
inst->cfg->cpumonitor.total = total;
inst->cfg->cpumonitor.idle = cpu_times[3];
inst->cfg->cpumonitor.percent = (int) percent;
}
else if (ncpu > 1)
{
for (i = 0; i < ncpu; i++)
{
long cpu_times[CPU_STATES];
size = CPU_STATES * sizeof(long);
int cpu_time_mib[] = { CTL_KERN, KERN_CPTIME2, 0 };
cpu_time_mib[2] = i;
if (sysctl(cpu_time_mib, 3, &cpu_times, &size, NULL, 0) < 0)
return;
long total = 0;
for (j = 0; j < CPU_STATES - 1; j++)
total += cpu_times[j];
long used = total - (cpu_times[4]);
double ratio = (float) total / 100.0;
int percent = used / ratio;
if (percent > 100)
percent = 100;
else if (percent < 0)
percent = 0;
core = eina_list_nth(inst->cfg->cpumonitor.cores, i);
core->percent = (int) percent;
core->total = total;
core->idle = cpu_times[4];
percent_all += (int) percent;
total_all += total;
idle_all += core->idle;
}
inst->cfg->cpumonitor.total = total_all / ncpu;
inst->cfg->cpumonitor.idle = idle_all / ncpu;
inst->cfg->cpumonitor.percent = (percent_all / ncpu) + (percent_all % ncpu);
}
#endif
}

View File

@ -275,9 +275,15 @@ _memusage_cb_usage_check_main(void *data, Ecore_Thread *th)
for (;;)
{
if (ecore_thread_check(th)) break;
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
_memusage_sysctl_getusage(&thc->mem_total, &thc->mem_used,
&thc->mem_cached, &thc->mem_buffers, &thc->mem_shared,
&thc->swp_total, &thc->swp_used);
#else
_memusage_proc_getusage(&thc->mem_total, &thc->mem_used,
&thc->mem_cached, &thc->mem_buffers, &thc->mem_shared,
&thc->swp_total, &thc->swp_used);
#endif
if (thc->mem_total > 0)
thc->mem_percent = 100 * ((float)thc->mem_used / (float)thc->mem_total);
if (thc->swp_total > 0)

View File

@ -14,4 +14,12 @@ void _memusage_proc_getusage(unsigned long *mem_total,
unsigned long *swp_total,
unsigned long *swp_used);
void _memusage_sysctl_getusage(unsigned long *mem_total,
unsigned long *mem_used,
unsigned long *mem_cached,
unsigned long *mem_buffers,
unsigned long *mem_shared,
unsigned long *swp_total,
unsigned long *swp_used);
#endif

View File

@ -0,0 +1,147 @@
#include "memusage.h"
#if defined(__FreeBSD__) || defined(__DragonFly__)
# include <sys/types.h>
# include <sys/sysctl.h>
# include <vm/vm_param.h>
#endif
#if defined(__OpenBSD__)
# include <sys/param.h>
# include <sys/sysctl.h>
# include <sys/swap.h>
# include <sys/mount.h>
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
static long int
_sysctlfromname(const char *name, void *mib, int depth, size_t *len)
{
long int result;
if (sysctlnametomib(name, mib, len) < 0) return -1;
*len = sizeof(result);
if (sysctl(mib, depth, &result, len, NULL, 0) < 0) return -1;
return result;
}
#endif
void _memusage_sysctl_getusage(unsigned long *mem_total,
unsigned long *mem_used,
unsigned long *mem_cached,
unsigned long *mem_buffers,
unsigned long *mem_shared,
unsigned long *swp_total,
unsigned long *swp_used)
{
size_t len;
int i = 0;
*mem_total = *mem_used = *mem_cached = *mem_buffers = *mem_shared = 0;
*swp_total = *swp_used = 0;
#if defined(__FreeBSD__) || defined(__DragonFly__)
int total_pages = 0, free_pages = 0, inactive_pages = 0;
long int result = 0;
int page_size = getpagesize();
int *mib = malloc(sizeof(int) * 4);
if (mib == NULL) return;
mib[0] = CTL_HW; mib[1] = HW_PHYSMEM;
len = sizeof(*mem_total);
if (sysctl(mib, 2, mem_total, &len, NULL, 0) == -1)
return;
*mem_total /= 1024;
total_pages = _sysctlfromname("vm.stats.vm.v_page_count", mib, 4, &len);
if (total_pages < 0) return;
free_pages = _sysctlfromname("vm.stats.vm.v_free_count", mib, 4, &len);
if (free_pages < 0) return;
inactive_pages = _sysctlfromname("vm.stats.vm.v_inactive_count", mib, 4, &len);
if (inactive_pages < 0) return;
*mem_used = (total_pages - free_pages - inactive_pages) * page_size >> 10;
result = _sysctlfromname("vfs.bufspace", mib, 2, &len);
if (result < 0) return;
*mem_buffers = (result / 1024);
result = _sysctlfromname("vm.stats.vm.v_active_count", mib, 4, &len);
if (result < 0) return;
*mem_cached = ((result * page_size) / 1024);
result = _sysctlfromname("vm.stats.vm.v_cache_count", mib, 4, &len);
if (result < 0) return;
*mem_shared = (result * page_size) / 1024;
result = _sysctlfromname("vm.swap_total", mib, 2, &len);
if (result < 0) return;
*swp_total = (result / 1024);
struct xswdev xsw;
// previous mib is important for this one...
while (i++)
{
mib[2] = i;
len = sizeof(xsw);
if (sysctl(mib, 3, &xsw, &len, NULL, 0) == -1) break;
*swp_used += xsw.xsw_used * page_size;
}
*swp_used >>= 10;
free(mib);
#elif defined(__OpenBSD__)
static int mib[] = { CTL_HW, HW_PHYSMEM64 };
static int bcstats_mib[] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT };
struct bcachestats bcstats;
static int uvmexp_mib[] = { CTL_VM, VM_UVMEXP };
struct uvmexp uvmexp;
int nswap, rnswap;
struct swapent *swdev = NULL;
len = sizeof(*mem_total);
if (sysctl(mib, 2, mem_total, &len, NULL, 0) == -1)
return;
len = sizeof(uvmexp);
if (sysctl(uvmexp_mib, 2, &uvmexp, &len, NULL, 0) == -1)
return;
len = sizeof(bcstats);
if (sysctl(bcstats_mib, 3, &bcstats, &len, NULL, 0) == -1)
return;
// Don't fail if there's not swap!
nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap == 0) goto swap_out;
swdev = calloc(nswap, sizeof(*swdev));
if (swdev == NULL) goto swap_out;
rnswap = swapctl(SWAP_STATS, swdev, nswap);
if (rnswap == -1) goto swap_out;
for (i = 0; i < nswap; i++)// nswap; i++)
{
if (swdev[i].se_flags & SWF_ENABLE)
{
*swp_used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
*swp_total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
}
}
swap_out:
if (swdev) free(swdev);
*mem_total /= 1024;
*mem_cached = (uvmexp.pagesize * bcstats.numbufpages) / 1024;
*mem_used = (uvmexp.active * uvmexp.pagesize) / 1024 ;
*mem_buffers = (uvmexp.pagesize * (uvmexp.npages - uvmexp.free)) / 1024;
*mem_shared = (uvmexp.pagesize * uvmexp.wired) / 1024;
#endif
}

View File

@ -128,8 +128,13 @@ _netstatus_cb_usage_check_main(void *data, Ecore_Thread *th)
for (;;)
{
if (ecore_thread_check(th)) break;
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
_netstatus_sysctl_getrstatus(thc->inst);
_netstatus_sysctl_gettstatus(thc->inst);
#else
_netstatus_proc_getrstatus(thc->inst);
_netstatus_proc_gettstatus(thc->inst);
#endif
ecore_thread_feedback(th, NULL);
if (ecore_thread_check(th)) break;
usleep((1000000.0 / 8.0) * (double)thc->interval);

View File

@ -19,5 +19,7 @@ struct _Netstatus_Config
void _netstatus_config_updated(Instance *inst);
void _netstatus_proc_getrstatus(Instance *inst);
void _netstatus_proc_gettstatus(Instance *inst);
void _netstatus_sysctl_getrstatus(Instance *inst);
void _netstatus_sysctl_gettstatus(Instance *inst);
Evas_Object *netstatus_configure(Instance *inst);
#endif

View File

@ -0,0 +1,203 @@
#include "netstatus.h"
#if defined(__FreeBSD__) || defined(__DragonFly__)
# include <sys/socket.h>
# include <sys/sysctl.h>
# include <net/if.h>
# include <net/if_mib.h>
#endif
#if defined(__OpenBSD__)
# include <sys/types.h>
# include <sys/socket.h>
# include <sys/sysctl.h>
# include <sys/sockio.h>
# include <sys/ioctl.h>
# include <net/if.h>
# include <net/if_types.h>
# include <ifaddrs.h>
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
static int
get_ifmib_general(int row, struct ifmibdata *data)
{
int mib[6];
size_t len;
mib[0] = CTL_NET;
mib[1] = PF_LINK;
mib[2] = NETLINK_GENERIC;
mib[3] = IFMIB_IFDATA;
mib[4] = row;
mib[5] = IFDATA_GENERAL;
len = sizeof(*data);
return sysctl(mib, 6, data, &len, NULL, 0);
}
static void
_freebsd_generic_network_status(unsigned long int *in, unsigned long int *out)
{
struct ifmibdata *ifmd;
size_t len;
int i, count;
len = sizeof(count);
if (sysctlbyname("net.link.generic.system.ifcount", &count, &len, NULL, 0) < 0)
return;
ifmd = malloc(sizeof(struct ifmibdata));
if (!ifmd)
return;
for (i = 1; i <= count; i++)
{
get_ifmib_general(i, ifmd);
*in += ifmd->ifmd_data.ifi_ibytes;
*out += ifmd->ifmd_data.ifi_obytes;
}
free(ifmd);
}
#endif
#if defined(__OpenBSD__)
static void
_openbsd_generic_network_status(unsigned long int *in, unsigned long int *out)
{
struct ifaddrs *interfaces, *ifa;
if (getifaddrs(&interfaces) < 0)
return;
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
return;
for (ifa = interfaces; ifa; ifa = ifa->ifa_next)
{
struct ifreq ifreq;
struct if_data if_data;
ifreq.ifr_data = (void *)&if_data;
strncpy(ifreq.ifr_name, ifa->ifa_name, IFNAMSIZ-1);
if (ioctl(sock, SIOCGIFDATA, &ifreq) < 0)
return;
struct if_data * const ifi = &if_data;
if (ifi->ifi_type == IFT_ETHER || ifi->ifi_type == IFT_IEEE80211)
{
if (ifi->ifi_ibytes)
*in += ifi->ifi_ibytes;
else
*in += 0;
if (ifi->ifi_obytes)
*out += ifi->ifi_obytes;
else
*out += 0;
}
}
close(sock);
}
#endif
void
_netstatus_sysctl_getrstatus(Instance *inst)
{
char rin[256];
long tot_in = 0, diffin;
int percent = 0;
unsigned long int incoming = 0, outgoing = 0;
#if defined(__OpenBSD__)
_openbsd_generic_network_status(&incoming, &outgoing);
#elif defined(__FreeBSD__) || defined(__DragonFly__)
_freebsd_generic_network_status(&incoming, &outgoing);
#endif
tot_in = incoming;
diffin = tot_in - inst->cfg->netstatus.in;
if (!inst->cfg->netstatus.in)
inst->cfg->netstatus.in = tot_in;
else
{
inst->cfg->netstatus.in = tot_in;
if (inst->cfg->netstatus.automax)
{
if (diffin > inst->cfg->netstatus.inmax)
inst->cfg->netstatus.inmax = diffin;
}
inst->cfg->netstatus.incurrent = diffin;
if (inst->cfg->netstatus.inmax > 0)
percent = 100 * ((float)inst->cfg->netstatus.incurrent / (float)inst->cfg->netstatus.inmax);
if (percent > 100) percent = 100;
else if (percent < 0) percent = 0;
inst->cfg->netstatus.inpercent = percent;
}
if (!diffin)
{
snprintf(rin, sizeof(rin), "%s: 0 B/s", _("Receiving"));
}
else
{
if (diffin > 1048576)
snprintf(rin, sizeof(rin), "%s: %.2f MB/s", _("Receiving"), ((float)diffin / 1048576));
else if ((diffin > 1024) && (diffin < 1048576))
snprintf(rin, sizeof(rin), "%s: %lu KB/s", _("Receiving"), (diffin / 1024));
else
snprintf(rin, sizeof(rin), "%s: %lu B/s", _("Receiving"), diffin);
}
eina_stringshare_replace(&inst->cfg->netstatus.instring, rin);
}
void
_netstatus_sysctl_gettstatus(Instance *inst)
{
char rout[256];
long tot_out = 0, diffout;
int percent = 0;
unsigned long int incoming = 0, outgoing = 0;
#if defined(__OpenBSD__)
_openbsd_generic_network_status(&incoming, &outgoing);
#elif defined(__FreeBSD__) || defined(__DragonFly__)
_freebsd_generic_network_status(&incoming, &outgoing);
#endif
tot_out = outgoing;
diffout = tot_out - inst->cfg->netstatus.out;
if (!inst->cfg->netstatus.out)
inst->cfg->netstatus.out = tot_out;
else
{
inst->cfg->netstatus.out = tot_out;
if (inst->cfg->netstatus.automax)
{
if (diffout > inst->cfg->netstatus.outmax)
inst->cfg->netstatus.outmax = diffout;
}
inst->cfg->netstatus.outcurrent = diffout;
if (inst->cfg->netstatus.outcurrent > 0)
percent = 100 * ((float)inst->cfg->netstatus.outcurrent / (float)inst->cfg->netstatus.outmax);
if (percent > 100) percent = 100;
else if (percent < 0) percent = 0;
inst->cfg->netstatus.outpercent = percent;
}
if (!diffout)
{
snprintf(rout, sizeof(rout), "%s: 0 B/s", _("Sending"));
}
else
{
if (diffout > 1048576)
snprintf(rout, sizeof(rout), "%s: %.2f MB/s", _("Sending"), ((float)diffout / 1048576));
else if ((diffout > 1024) && (diffout < 1048576))
snprintf(rout, sizeof(rout), "%s: %lu KB/s", _("Sending"), (diffout / 1024));
else
snprintf(rout, sizeof(rout), "%s: %lu B/s", _("Sending"), diffout);
}
eina_stringshare_replace(&inst->cfg->netstatus.outstring, rout);
}