10 Commits

Author SHA1 Message Date
Christian Barthel
cfb359736f Whitespace cleanup 2022-02-05 07:40:03 +01:00
Christian Barthel
34c8e85e49 Add Linux support, fix whitespace
Read /proc/meminfo, pull out some numbers and use them.
2022-01-08 08:31:23 +01:00
Christian Barthel
a6e2ded980 Whitespace 2022-01-08 08:28:08 +01:00
Christian Barthel
2458539dc7 Add Linux makefile 2022-01-07 22:55:21 +01:00
Christian Barthel
65bf48110a Cleanup get_mem for Open-/FreeBSD
Remove unnecessary files, use ifdef to decide
for which platform to compile for.
2020-11-17 18:14:24 +01:00
Christian Barthel
1268b76c3c Typo in Makefile 2020-11-16 18:40:32 +01:00
bch
d3837a3dbf Update 'README.md' 2020-11-16 14:13:39 +00:00
bch
25677ed9ff Update 'README.md' 2020-11-16 14:13:19 +00:00
christian barthel
382c8ec129 Add web stuff etc 2020-11-16 15:11:08 +01:00
Christian Barthel
34548bbd21 Makefile - default to OpenBSD 2020-11-16 14:56:56 +01:00
12 changed files with 516 additions and 246 deletions

View File

@@ -1,25 +1,17 @@
# OS=$(uname) make
### OS = FreeBSD
PROG= xmem
VERSION= 1.27
FreeBSD_lflag= -lkvm
LDFLAGS+= -L/usr/X11R6/lib -L/usr/local/lib/ -lX11 -lXt -lXaw -lXmu
LDFLAGS+= $($(OS)_lflag)
LDFLAGS+= -L/usr/X11R6/lib -L/usr/local/lib/ -lX11 -lXt -lXaw -lXmu
LDFLAGS+= -lkvm
CFLAGS+= -Wall -I/usr/X11R6/include/ -I/usr/local/include/
OBJECTS= xmem.o MemStripChart.o
FreeBSD_stub = get_mem_fbsd.o
OpenBSD_stub = get_mem.o
OBJECTS += $($(OS)_stub)
OBJECTS= xmem.o MemStripChart.o get_mem.o
all: xmem
xmem.full:
echo "full not supported yet"
@echo "full not supported yet"
xmem.debug:
echo "debug not supported yet"
@echo "debug not supported yet"
xmem: $(OBJECTS)
$(CC) -o xmem $(OBJECTS) $(LDFLAGS)
@@ -27,10 +19,10 @@ xmem: $(OBJECTS)
%.o: %c
$(CC) $(CFLAGS) -c $<
clean:
clean:
-rm -rf $(OBJECTS) $(PROG)
dist:
dist:
mkdir -p ${PROG}-${VERSION}
cp *.h *.c Makefile xmem.1 xmem.bit copyright XMem.ad ${PROG}-${VERSION}
tar cfvz ${PROG}-${VERSION}.tar.gz ${PROG}-${VERSION}
@@ -40,15 +32,14 @@ dist-clean:
-rm ${PROG}-${VERSION}.tar.gz
install:
install -d -m 755 {PREFIX}/bin/
install -d -m 755 ${PREFIX}/bin/
install -c -S -s -o root -g bin -m 755 xmem ${PREFIX}/bin/xmem
install -d -m 755 ${PREFIX}/man/man1/
install -c -o root -g bin -m 644 xmem.1 ${PREFIX}/man/man1/xmem.1
install -d -m 755 ${PREFIX}/lib/X11/app-defaults/
install -c -o root -g bin -m 644 XMem.ad ${PREFIX}/lib/X11/app-defaults/XMem
install -d -m 755 ${PREFIX}/share/${PROG}/
install -d -m 755 ${PREFIX}/share/${PROG}/
install -c -o root -g bin -m 644 xmem.bit ${PREFIX}/share/${PROG}/xmem.bit
install -c -o root -g bin -m 644 copyright ${PREFIX}/share/${PROG}/copyright
.include <bsd.prog.mk>

44
Makefile.linux Normal file
View File

@@ -0,0 +1,44 @@
PROG= xmem
VERSION= 1.27
LDFLAGS+= -L/usr/lib/x86_64-linux-gnu/ -lX11 -lXt -lXaw -lXmu
CFLAGS+= -Wall -I/usr/include/X11/ -I/usr/X11R6/include/ -I/usr/local/include/
OBJECTS= xmem.o MemStripChart.o get_mem.o
all: xmem
xmem.full:
@echo "full not supported yet"
xmem.debug:
@echo "debug not supported yet"
xmem: $(OBJECTS)
$(CC) -o xmem $(OBJECTS) $(LDFLAGS)
%.o: %c
$(CC) $(CFLAGS) -c $<
clean:
-rm -rf $(OBJECTS) $(PROG)
dist:
mkdir -p ${PROG}-${VERSION}
cp *.h *.c Makefile xmem.1 xmem.bit copyright XMem.ad ${PROG}-${VERSION}
tar cfvz ${PROG}-${VERSION}.tar.gz ${PROG}-${VERSION}
rm -rf ${PROG}-${VERSION}
dist-clean:
-rm ${PROG}-${VERSION}.tar.gz
install:
install -d -m 755 ${PREFIX}/bin/
install -c -S -s -o root -g bin -m 755 xmem ${PREFIX}/bin/xmem
install -d -m 755 ${PREFIX}/man/man1/
install -c -o root -g bin -m 644 xmem.1 ${PREFIX}/man/man1/xmem.1
install -d -m 755 ${PREFIX}/lib/X11/app-defaults/
install -c -o root -g bin -m 644 XMem.ad ${PREFIX}/lib/X11/app-defaults/XMem
install -d -m 755 ${PREFIX}/share/${PROG}/
install -c -o root -g bin -m 644 xmem.bit ${PREFIX}/share/${PROG}/xmem.bit
install -c -o root -g bin -m 644 copyright ${PREFIX}/share/${PROG}/copyright

View File

@@ -1,7 +1,7 @@
/***********************************************************************
*
* MemStripChart Widget
* from StripChart Widget derived
* from StripChart Widget derived
*
* Author: Hans-Helmut B"uhmann 20. Jan. 1996
*
@@ -165,10 +165,10 @@ CreateGC(MemStripChartWidget w, unsigned int which)
static void
DestroyGC(MemStripChartWidget w, unsigned int which)
{
if (which & FOREGROUND)
if (which & FOREGROUND)
XtReleaseGC((Widget) w, w->mem_strip_chart.fgGC);
if (which & HIGHLIGHT)
if (which & HIGHLIGHT)
XtReleaseGC((Widget) w, w->mem_strip_chart.hiGC);
if (which & CODE) {
@@ -229,7 +229,7 @@ DrawMemStrip(MemStripChartWidget w, unsigned int x)
if (w->mem_strip_chart.valuedata[x].buffer != 0.0) {
top = (int) (w->core.height
- (int)(w->core.height * (1.0 - w->mem_strip_chart.valuedata[x].free))
- (int)(w->core.height * (1.0 - w->mem_strip_chart.valuedata[x].free))
/ w->mem_strip_chart.scale);
XFillRectangle(XtDisplay(w), XtWindow(w), w->mem_strip_chart.bufferGC,
x, top, (unsigned int) 1, bottom - top);
@@ -246,7 +246,7 @@ DrawMemStrip(MemStripChartWidget w, unsigned int x)
}
if (w->mem_strip_chart.valuedata[x].swap != 0.0) {
top = (int) (w->core.height
- (int)(w->core.height * (1.0 + w->mem_strip_chart.valuedata[x].swap))
- (int)(w->core.height * (1.0 + w->mem_strip_chart.valuedata[x].swap))
/ w->mem_strip_chart.scale);
XFillRectangle(XtDisplay(w), XtWindow(w), w->mem_strip_chart.swapGC,
x, top, (unsigned int) 1, bottom - top);
@@ -261,7 +261,7 @@ static void Initialize (Widget greq, Widget gnew, ArgList args, Cardinal *num_ar
if (w->mem_strip_chart.update > 0)
w->mem_strip_chart.interval_id = XtAppAddTimeOut(
XtWidgetToApplicationContext(gnew),
w->mem_strip_chart.update * MS_PER_SEC,
w->mem_strip_chart.update * MS_PER_SEC,
draw_it, (XtPointer) gnew);
CreateGC(w, (unsigned int) ALL_GCS);
@@ -271,7 +271,7 @@ static void Initialize (Widget greq, Widget gnew, ArgList args, Cardinal *num_ar
w->mem_strip_chart.points = NULL;
SetPoints(w);
}
static void Destroy (Widget gw)
{
MemStripChartWidget w = (MemStripChartWidget)gw;
@@ -284,7 +284,7 @@ static void Destroy (Widget gw)
}
/*
* NOTE: This function really needs to recieve graphics exposure
* NOTE: This function really needs to recieve graphics exposure
* events, but since this is not easily supported until R4 I am
* going to hold off until then.
*/
@@ -301,13 +301,13 @@ static void Redisplay(Widget w, XEvent *event, Region region)
}
/* ARGSUSED */
static void
static void
draw_it(XtPointer client_data, XtIntervalId *id)
{
MemStripChartWidget w = (MemStripChartWidget)client_data;
MemStripChartCallbackData value;
double usedmem;
if (w->mem_strip_chart.update > 0)
w->mem_strip_chart.interval_id =
XtAppAddTimeOut(XtWidgetToApplicationContext( (Widget) w),
@@ -323,15 +323,15 @@ draw_it(XtPointer client_data, XtIntervalId *id)
XtCallCallbacks( (Widget)w, XtNgetValue, (XtPointer)&value );
/*
* Keep w->mem_strip_chart.max_value up to date, and if this data
* point is off the graph, change the scale to make it fit.
/*
* Keep w->mem_strip_chart.max_value up to date, and if this data
* point is off the graph, change the scale to make it fit.
*/
usedmem = 1.0 + value.swap;
if (usedmem > w->mem_strip_chart.max_value) {
w->mem_strip_chart.max_value = usedmem;
if (XtIsRealized((Widget)w) &&
if (XtIsRealized((Widget)w) &&
w->mem_strip_chart.max_value > w->mem_strip_chart.scale) {
XClearWindow( XtDisplay (w), XtWindow (w));
w->mem_strip_chart.interval = repaint_window(w, 0, (int) w->core.width);
@@ -343,7 +343,7 @@ draw_it(XtPointer client_data, XtIntervalId *id)
/* XXX DrawMemStrip(w, w->mem_strip_chart.interval, value); */
DrawMemStrip(w, w->mem_strip_chart.interval);
/*
* Fill in the graph lines we just painted over.
*/
@@ -370,7 +370,7 @@ draw_it(XtPointer client_data, XtIntervalId *id)
* largest data point.
*/
static int
static int
repaint_window(MemStripChartWidget w, int left, int width)
{
int i, j;
@@ -393,7 +393,7 @@ repaint_window(MemStripChartWidget w, int left, int width)
SetPoints(w);
if (XtIsRealized ((Widget) w))
if (XtIsRealized ((Widget) w))
XClearWindow (XtDisplay (w), XtWindow (w));
}
@@ -445,20 +445,20 @@ MoveChart(MemStripChartWidget w, Boolean blit)
if (j < 0) j = 0;
}
(void) memmove((char *)(w->mem_strip_chart.valuedata),
(void) memmove((char *)(w->mem_strip_chart.valuedata),
(char *)(w->mem_strip_chart.valuedata + next - j),
j * sizeof(MemStripChartCallbackData));
next = w->mem_strip_chart.interval = j;
/*
* Since we just lost some data, recompute the
* w->mem_strip_chart.max_value.
* Since we just lost some data, recompute the
* w->mem_strip_chart.max_value.
*/
old_max = w->mem_strip_chart.max_value;
w->mem_strip_chart.max_value = 0.0;
for (i = 0; i < next; i++) {
if (w->mem_strip_chart.valuedata[i].swap + 1.0 > w->mem_strip_chart.max_value)
if (w->mem_strip_chart.valuedata[i].swap + 1.0 > w->mem_strip_chart.max_value)
w->mem_strip_chart.max_value = w->mem_strip_chart.valuedata[i].swap + 1.0;
}
@@ -475,8 +475,8 @@ MoveChart(MemStripChartWidget w, Boolean blit)
(unsigned int) j, (unsigned int) w->core.height,
0, 0);
XClearArea(XtDisplay((Widget)w), XtWindow((Widget)w),
(int) j, 0,
XClearArea(XtDisplay((Widget)w), XtWindow((Widget)w),
(int) j, 0,
(unsigned int) w->core.width - j, (unsigned int)w->core.height,
FALSE);
@@ -510,12 +510,12 @@ static Boolean SetValues (Widget current, Widget request, Widget new, ArgList ar
if ( w->mem_strip_chart.min_scale > (int) ((w->mem_strip_chart.max_value) + 1) )
ret_val = TRUE;
if ( w->mem_strip_chart.fgpixel != old->mem_strip_chart.fgpixel ) {
new_gc |= FOREGROUND;
ret_val = True;
}
if ( w->mem_strip_chart.hipixel != old->mem_strip_chart.hipixel ) {
new_gc |= HIGHLIGHT;
ret_val = True;

11
README.md Normal file
View File

@@ -0,0 +1,11 @@
# xmem(1) X11 Utility
![fvwm and xmem](https://git.sdf.org/bch/xmem/raw/branch/master/www/xmem_fvwmbar.png)
# Compile
```shell
# Linux with DEBUG:
CFLAGS=-DDEBUG make -f Makefile.linux
# BSD:
make
```

371
get_mem.c
View File

@@ -1,17 +1,19 @@
/* $Id: get_mem.c,v 1.5 2018/12/26 18:46:04 bch Exp $
*
* Adapted: get memory usage on OpenBSD
* Author: Christian Barthel <bch@online.de>
*
* xmem(1) utility adapted by Christian Barthel <bch@online.de>:
* - Added OpenBSD support
* - Added FreeBSD support
*
* get memory usage, from get_load.c derived
*
* Author: Hans-Helmut Buehmann 20. Jan. 1996
*
*
* Modified for more recent kernels Helmut Geyer Oct. 1996
*/
#if __OpenBSD__
#include <sys/param.h> /* DEV_BSIZE MAXCOMLEN PZERO */
#include <sys/param.h> /* DEV_BSIZE MAXCOMLEN PZERO */
#include <sys/sysctl.h>
#include <sys/swap.h>
#include <sys/mount.h>
@@ -26,91 +28,322 @@
#include <err.h>
#include "MemStripChart.h"
static int pageshift = -1;
static int pageshift = -1;
#define pagetok(size) ((size) << pageshift)
#define LOG1024 10
#define LOG1024 10
static double allmem_kb = 0;
static double allmem_kb = 0;
static void initPageShift(void)
{
int pagesize = getpagesize();
pageshift = 0;
while (pagesize > 1) {
pageshift++;
pagesize >>= 1;
}
pageshift -= LOG1024;
int pagesize = getpagesize();
pageshift = 0;
while (pagesize > 1) {
pageshift++;
pagesize >>= 1;
}
pageshift -= LOG1024;
}
static double getSwapFrac()
static double getSwapFrac()
{
struct swapent *swdev;
int used, total, nswap, rnswap, i;
struct swapent *swdev;
int used, total, nswap, rnswap, i;
nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap == 0)
return 0;
nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap == 0)
return 0;
swdev = calloc(nswap, sizeof(*swdev));
if (swdev == NULL)
return 0;
swdev = calloc(nswap, sizeof(*swdev));
if (swdev == NULL)
return 0;
rnswap = swapctl(SWAP_STATS, swdev, nswap);
if (rnswap == -1) {
free(swdev);
return 0;
}
rnswap = swapctl(SWAP_STATS, swdev, nswap);
if (rnswap == -1) {
free(swdev);
return 0;
}
/* if rnswap != nswap, then what? */
/* if rnswap != nswap, then what? */
/* Total things up */
total = used = 0;
for (i = 0; i < nswap; i++) {
if (swdev[i].se_flags & SWF_ENABLE) {
used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
}
}
free(swdev);
return (double)used/total;
/* Total things up */
total = used = 0;
for (i = 0; i < nswap; i++) {
if (swdev[i].se_flags & SWF_ENABLE) {
used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
}
}
free(swdev);
return (double)used/total;
}
void GetMemLoadPoint(Widget w, caddr_t closure, caddr_t call_data)
void GetMemLoadPoint(Widget w, caddr_t closure, caddr_t call_data)
{
static int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT};
static int uvmexp_mib[] = {CTL_VM, VM_UVMEXP};
MemStripChartCallbackData ret;
struct uvmexp uvmexp;
struct bcachestats bcstats;
size_t size;
if (pageshift < 0)
initPageShift();
static int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT};
static int uvmexp_mib[] = {CTL_VM, VM_UVMEXP};
MemStripChartCallbackData ret;
struct uvmexp uvmexp;
struct bcachestats bcstats;
size_t size;
size = sizeof(uvmexp);
if (sysctl(uvmexp_mib, 2, &uvmexp, &size, NULL, 0) < 0) {
warn("sysctl failed");
bzero(&uvmexp, sizeof(uvmexp));
}
size = sizeof(bcstats);
if (sysctl(bcstats_mib, 3, &bcstats, &size, NULL, 0) < 0) {
warn("sysctl failed");
bzero(&bcstats, sizeof(bcstats));
}
if (pageshift < 0)
initPageShift();
size = sizeof(uvmexp);
if (sysctl(uvmexp_mib, 2, &uvmexp, &size, NULL, 0) < 0) {
warn("sysctl failed");
bzero(&uvmexp, sizeof(uvmexp));
}
size = sizeof(bcstats);
if (sysctl(bcstats_mib, 3, &bcstats, &size, NULL, 0) < 0) {
warn("sysctl failed");
bzero(&bcstats, sizeof(bcstats));
}
allmem_kb = pagetok(uvmexp.npages);
ret.cached = pagetok(bcstats.numbufpages) / allmem_kb;
ret.free = pagetok(uvmexp.free) / allmem_kb;
ret.buffer = 0;
ret.code = (1 - ret.cached - ret.free);
ret.swap = getSwapFrac();
allmem_kb = pagetok(uvmexp.npages);
ret.cached = pagetok(bcstats.numbufpages) / allmem_kb;
ret.free = pagetok(uvmexp.free) / allmem_kb;
ret.buffer = 0;
ret.code = (1 - ret.cached - ret.free);
ret.swap = getSwapFrac();
#ifdef DEBUG
printf("%lf %lf %lf %lf %lf\n", allmem_kb, ret.code, ret.cached, ret.free, ret.swap);
printf("%lf %lf %lf %lf %lf\n",
allmem_kb,
ret.code,
ret.cached,
ret.free,
ret.swap);
#endif
memcpy(call_data, &ret, sizeof(MemStripChartCallbackData));
memcpy(call_data, &ret, sizeof(MemStripChartCallbackData));
}
#endif
/* ------------------------------------------------------------------- */
#if __FreeBSD__
/* $Id: get_mem_fbsd.c,v 1.1 2018/12/26 18:46:16 bch Exp $
*
* Author: Christian Barthel <bch@online.de>
*/
#include <sys/types.h> /* DEV_BSIZE MAXCOMLEN PZERO */
#include <sys/sysctl.h>
#include <unistd.h>
#include <kvm.h>
#include <X11/Xos.h>
#include <X11/Intrinsic.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include "MemStripChart.h"
static int pageshift = -1;
static int pagesize = 0;
static kvm_t *kd = 0;
#define pagetok(size) ((size) << pageshift)
#define LOG1024 10
static unsigned int allmem_pages = 0;
static void initPageShift(void)
{
pagesize = getpagesize();
size_t len = sizeof(allmem_pages);
int mib[len];
pageshift = 0;
while (pagesize > 1) {
pageshift++;
pagesize >>= 1;
}
pageshift -= LOG1024;
kd = kvm_open(NULL, "/dev/null" ,NULL, O_RDONLY, "kvm_open");
if (sysctlbyname("vm.stats.vm.v_page_count", &allmem_pages, &len, NULL, 0) == -1)
perror("sysctl");
#ifdef DEBUG
printf("page_count: %d\n", allmem_pages);
#endif
}
static double getSwapFrac()
{
/* XXX Borrowed from top(1) code: */
int n;
struct kvm_swap swapary[1];
static int pagesize = 0;
static unsigned long swap_maxpages = 0;
size_t sz = sizeof(swap_maxpages);
int retavail = 0;
int retfree = 0;
n = kvm_getswapinfo(kd, swapary, 1, 0);
if (n < 0 || swapary[0].ksw_total == 0)
return (0);
if (swap_maxpages == 0)
sysctlbyname("vm.swap_maxpages",
&swap_maxpages, &sz, NULL, 0);
if ( swapary[0].ksw_total > swap_maxpages )
swapary[0].ksw_total = swap_maxpages;
retavail = swapary[0].ksw_total;
retfree = swapary[0].ksw_total - swapary[0].ksw_used;
#ifdef DEBUG
printf("swap: %d %d %d %d\n", retavail,
retavail, swapary[0].ksw_total,
swapary[0].ksw_used);
#endif
return (double)(retavail-retfree)/(double)retavail;
}
void GetMemLoadPoint(Widget w, caddr_t closure, caddr_t call_data)
{
MemStripChartCallbackData ret;
int a, b;
size_t sz = sizeof(int);
double cache = 0;
if (pageshift < 0)
initPageShift();
sysctlbyname("vm.stats.vm.v_wire_count", &a, &sz, NULL, 0);
ret.code = (double)a / (double)allmem_pages;
sysctlbyname("vm.stats.vm.v_active_count", &a, &sz, NULL, 0);
ret.buffer = (double)a / (double)allmem_pages;
/* v_cache_count and v_inactive_count are treated similarly */
sysctlbyname("vm.stats.vm.v_inactive_count", &a, &sz, NULL, 0);
sysctlbyname("vm.stats.vm.v_cache_count", &b, &sz, NULL, 0);
ret.cached = (double)(a + b) / allmem_pages;
sysctlbyname("vm.stats.vm.v_free_count", &a, &sz, NULL, 0);
ret.free = (double)a / allmem_pages;
ret.swap = getSwapFrac();
#ifdef DEBUG
printf("%u %lf %lf %lf %lf\n", allmem_pages,
ret.code, ret.cached, ret.free, ret.swap);
#endif
memcpy(call_data, &ret, sizeof(MemStripChartCallbackData));
}
#endif
/* ------------------------------------------------------------------ */
#if __gnu_linux__
#include <X11/Xos.h>
#include <X11/Intrinsic.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include "MemStripChart.h"
static unsigned int total_mem = 0;
int GetRamInKB(int type)
{
FILE *meminfo = fopen("/proc/meminfo", "r");
if(meminfo == NULL)
err(1, "fopen on /proc/meminfo failed: ");
char line[256];
int memory = -1;
int found = 0;
while(found == 0 && fgets(line, sizeof(line), meminfo))
{
if (type == 1) {
if((sscanf(line, "MemTotal: %d kB", &memory)) == 1)
found = 1;
}
if (type == 2) {
if(sscanf(line, "MemFree: %d kB", &memory) == 1)
found = 1;
}
if (type == 3) {
if(sscanf(line, "Buffers: %d kB", &memory) == 1)
found = 1;
}
if (type == 4) {
if(sscanf(line, "Cached: %d kB", &memory) == 1)
found = 1;
}
if (type == 5) {
if(sscanf(line, "SwapTotal: %d kB", &memory) == 1)
found = 1;
}
if (type == 6) {
if(sscanf(line, "SwapFree: %d kB", &memory) == 1)
found = 1;
}
}
if (!found)
warnx("failed to sscanf type %d", type);
fclose(meminfo);
return memory;
}
static void init_total_mem(void)
{
if (total_mem <= 0)
total_mem = GetRamInKB(1);
#ifdef DEBUG
printf("MemTotal: %d\n", total_mem);
#endif
}
void GetMemLoadPoint(Widget w, caddr_t closure, caddr_t call_data)
{
MemStripChartCallbackData ret;
init_total_mem();
/* free(1):
* total
* used = total - free - buffers - cache
* /proc/meminfo
* total = MemTotal
* code = total - free - buffers - cache (“used”)
* buffer = Buffers
* cached = Cached
* free = MemFree
*/
int mem_free = GetRamInKB(2);
int buffers = GetRamInKB(3);
int cached = GetRamInKB(4);
int swap_total = GetRamInKB(5);
int swap_free = GetRamInKB(6);
ret.code = (total_mem - mem_free - buffers - cached)/(float)total_mem;
ret.buffer = (buffers)/(float)total_mem;
ret.cached = (cached)/(float)total_mem;
ret.free = (mem_free)/(float)total_mem;
ret.swap = (swap_total - swap_free)/(float)swap_total;
#ifdef DEBUG
printf("%u %lf %lf %lf %lf\n", total_mem,
ret.code, ret.cached, ret.free, ret.swap);
#endif
memcpy(call_data, &ret, sizeof(MemStripChartCallbackData));
}
#endif

View File

@@ -1,113 +0,0 @@
/* $Id: get_mem_fbsd.c,v 1.1 2018/12/26 18:46:16 bch Exp $
*
* Author: Christian Barthel <bch@online.de>
*/
#include <sys/types.h> /* DEV_BSIZE MAXCOMLEN PZERO */
#include <sys/sysctl.h>
#include <unistd.h>
#include <kvm.h>
#include <X11/Xos.h>
#include <X11/Intrinsic.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include "MemStripChart.h"
static int pageshift = -1;
static int pagesize = 0;
static kvm_t *kd = 0;
#define pagetok(size) ((size) << pageshift)
#define LOG1024 10
static unsigned int allmem_pages = 0;
static void initPageShift(void)
{
pagesize = getpagesize();
size_t len = sizeof(allmem_pages);
int mib[len];
pageshift = 0;
while (pagesize > 1) {
pageshift++;
pagesize >>= 1;
}
pageshift -= LOG1024;
kd = kvm_open(NULL, "/dev/null" ,NULL, O_RDONLY, "kvm_open");
if (sysctlbyname("vm.stats.vm.v_page_count", &allmem_pages, &len, NULL, 0) == -1)
perror("sysctl");
#ifdef DEBUG
printf("page_count: %d\n", allmem_pages);
#endif
}
static double getSwapFrac()
{
/* XXX Borrowed from top(1) code: */
int n;
struct kvm_swap swapary[1];
static int pagesize = 0;
static unsigned long swap_maxpages = 0;
size_t sz = sizeof(swap_maxpages);
int retavail = 0;
int retfree = 0;
n = kvm_getswapinfo(kd, swapary, 1, 0);
if (n < 0 || swapary[0].ksw_total == 0)
return (0);
if (swap_maxpages == 0)
sysctlbyname("vm.swap_maxpages", &swap_maxpages, &sz, NULL, 0);
if ( swapary[0].ksw_total > swap_maxpages )
swapary[0].ksw_total = swap_maxpages;
retavail = swapary[0].ksw_total;
retfree = swapary[0].ksw_total - swapary[0].ksw_used;
#ifdef DEBUG
printf("swap: %d %d %d %d\n", retavail, retavail, swapary[0].ksw_total,
swapary[0].ksw_used);
#endif
return (double)(retavail-retfree)/(double)retavail;
}
void GetMemLoadPoint(Widget w, caddr_t closure, caddr_t call_data)
{
MemStripChartCallbackData ret;
int a, b;
size_t sz = sizeof(int);
double cache = 0;
if (pageshift < 0)
initPageShift();
sysctlbyname("vm.stats.vm.v_wire_count", &a, &sz, NULL, 0);
ret.code = (double)a / (double)allmem_pages;
sysctlbyname("vm.stats.vm.v_active_count", &a, &sz, NULL, 0);
ret.buffer = (double)a / (double)allmem_pages;
/* v_cache_count and v_inactive_count are treated similarly */
sysctlbyname("vm.stats.vm.v_inactive_count", &a, &sz, NULL, 0);
sysctlbyname("vm.stats.vm.v_cache_count", &b, &sz, NULL, 0);
ret.cached = (double)(a + b) / allmem_pages;
sysctlbyname("vm.stats.vm.v_free_count", &a, &sz, NULL, 0);
ret.free = (double)a / allmem_pages;
ret.swap = getSwapFrac();
#ifdef DEBUG
printf("%u %lf %lf %lf %lf\n", allmem_pages,
ret.code, ret.cached, ret.free, ret.swap);
#endif
memcpy(call_data, &ret, sizeof(MemStripChartCallbackData));
}

104
www/index.html Executable file
View File

@@ -0,0 +1,104 @@
<head>
<link rel="shortcut icon" href="stat//icons/favicon.ico" />
<title>onfire.org</title>
<style type="text/css">
body {font-family:"Comic Sans MS", cursive, sans-serif;
color: black;
}
#footer {
position:relative;
bottom:-5em;
text-align:right;
margin-top: 10px;
width: 100%;
height: 2em;
text-align: right;
line-height: 2.0em;
padding-right=5px;
}
#all {
position: relative;
padding-left: 10px;
padding-right: 38px;
}
.blink {
animation: blink 1s steps(5, start) infinite;
-webkit-animation: blink 1s steps(5, start) infinite;
}
@keyframes blink {
to {
visibility: hidden;
}
}
@-webkit-keyframes blink {
to {
visibility: hidden;
}
}
</style>
</head>
<body bgcolor="white">
<h1>xmem</h1>
<tt>xmem</tt> is an X11 utility to display memory and swap usage. It was initially
created by the K. Shane Hartman (MIT-LCS) and Stuart A. Malone (MIT-LCS); with
features added by Jim Gettys (MIT-Athena), Bob Scheifler (MIT-LCS),
Tony Della Fera (MIT-Athena), and Chris Peterson (MIT-LCS). I did the initial
import from a Debian package and added support for OpenBSD and pledged the code.
<br>
I wasn't able to find any homepage, so I decided to host
<a href="https://git.onfire.org/bch/cgi-bin/gitweb.cgi?p=unix/xmem;a=summary">code</a>
and
<a href="http://onfire.org/snapshots/xmem/xmem-1.26.tar.gz">snapshots</a> here.
Current version is 1.26.
If you are, or know the author, please let <a href="mailto:bch@online.de">me</a> know!
<br>
<h2>Sample: running xmem on my system: </h2>
<table border=0>
<tr>
<td>
<a href="./xmem.png"><img src="./xmem_s.png" alt="xmem pic"></a>
</td>
<td>
<a href="./xmem_fvwmbar.png"><img src="./xmem_fvwmbar_s.png" alt="xmem pic"></a>
</td>
</tr>
</table>
<p>Another xmem(1) user: <a href="https://xteddy.org/xmem.html">xteddy.org/xmem</a></p>
<h2>xmem license</h2>
<pre>
Copyright (C) 1987 X Consortium
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the X Consortium shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization from
the X Consortium.
</pre>
</body>
</html>

BIN
www/xmem.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 950 KiB

BIN
www/xmem_fvwmbar.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
www/xmem_fvwmbar_s.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
www/xmem_s.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

38
xmem.c
View File

@@ -136,20 +136,20 @@ int main(int argc, char **argv)
Arg args[1];
Pixmap icon_pixmap = None;
char *label, host[256];
/* For security reasons, we reset our uid/gid after doing the necessary
system initialization and before calling any X routines. */
if (setgid(getgid()) == -1)
if (setgid(getgid()) == -1)
errx(1, "%s: setgid failed: %s\n", argv[0], strerror(errno));
if (setuid(getuid()) == -1)
if (setuid(getuid()) == -1)
errx(1, "%s: setuid failed: %s\n", argv[0], strerror(errno));
toplevel = XtAppInitialize(&app_con, "XMem", options_mem, XtNumber(options_mem),
&argc, argv, NULL, NULL, (Cardinal) 0);
if (argc != 1) usage(argv[0]);
XtGetApplicationResources( toplevel, (XtPointer) &resources,
my_resources_mem, XtNumber(my_resources_mem),
NULL, (Cardinal) 0);
@@ -160,7 +160,7 @@ int main(int argc, char **argv)
XtAppAddActions (app_con, xload_actions, XtNumber(xload_actions));
XtOverrideTranslations(toplevel,
XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
XtSetArg (args[0], XtNiconPixmap, &icon_pixmap);
XtGetValues(toplevel, args, ONE);
if (icon_pixmap == None) {
@@ -171,33 +171,33 @@ int main(int argc, char **argv)
xload_width, xload_height));
XtSetValues (toplevel, args, ONE);
}
if (resources.show_label) {
pane = XtCreateManagedWidget ("paned", panedWidgetClass,
toplevel, NULL, ZERO);
label_wid = XtCreateManagedWidget ("label", labelWidgetClass,
pane, NULL, ZERO);
XtSetArg (args[0], XtNlabel, &label);
XtGetValues(label_wid, args, ONE);
if ( strcmp("label", label) == 0 ) {
(void) XmuGetHostname (host, 255);
XtSetArg (args[0], XtNlabel, host);
XtSetValues (label_wid, args, ONE);
}
load_parent = pane;
}
else
load_parent = toplevel;
load = XtCreateManagedWidget ("mem", memStripChartWidgetClass,
load_parent, NULL, ZERO);
XtAddCallback(load, XtNgetValue, (void*)GetMemLoadPoint, NULL);
XtRealizeWidget (toplevel);
wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW",
False);
@@ -205,12 +205,12 @@ int main(int argc, char **argv)
&wm_delete_window, 1);
#if __OpenBSD__
if (pledge("ps vminfo stdio", NULL) == -1)
errx(1, "pledge failed: %s", strerror(errno));
if (pledge("ps vminfo stdio", NULL) == -1)
errx(1, "pledge failed: %s", strerror(errno));
#endif
XtAppMainLoop(app_con);
return 0;
return 0;
}