Download raw body.
Patch: x11/i3status
Hi all, the i3status port didn't include memory information, so I added
it in. Enclosed is a patch for the memory and additional documentation
in the manpage.
The calculation for used/available memory is a little different than on
Linux:
total = (usermem from sysctl)
free = (from sysctl)
cached = (from sysctl)
buffers = shared = 0
available = free + cached
used (memavailable) = total - available
used (classical) = total - free - buffers - cached
shared = 0
So both methods of used memory are equivalent.
These are already in an upstream PR.
Best,
Kristaps
Index: src/print_mem.c
--- src/print_mem.c.orig
+++ src/print_mem.c
@@ -5,6 +5,11 @@
#include <stdlib.h>
#include <yajl/yajl_gen.h>
#include <yajl/yajl_version.h>
+#ifdef __OpenBSD__
+# include <sys/mount.h>
+# include <sys/shm.h>
+# include <sys/sysctl.h>
+#endif
#include "i3status.h"
#define MAX_DECIMALS 4
@@ -12,12 +17,12 @@
#define BINARY_BASE 1024UL
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
static const char *const iec_symbols[] = {"B", "KiB", "MiB", "GiB", "TiB"};
#define MAX_EXPONENT ((sizeof iec_symbols / sizeof *iec_symbols) - 1)
#endif
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
/*
* Prints the given amount of bytes in a human readable manner.
*
@@ -42,7 +47,7 @@ static int print_percentage(char *outwalk, float perce
}
#endif
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
/*
* Convert a string to its absolute representation based on the total
* memory of `mem_total`.
@@ -89,11 +94,10 @@ static unsigned long memory_absolute(const char *mem_a
void print_memory(memory_ctx_t *ctx) {
char *outwalk = ctx->buf;
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
const char *selected_format = ctx->format;
const char *output_color = NULL;
- int unread_fields = 6;
unsigned long ram_total;
unsigned long ram_free;
unsigned long ram_available;
@@ -101,6 +105,51 @@ void print_memory(memory_ctx_t *ctx) {
unsigned long ram_cached;
unsigned long ram_shared;
+#if defined(__OpenBSD__)
+ int64_t tmp;
+ size_t sz;
+
+ /* Total memory set to the physical memory less kernel. */
+
+ int usermem_mib[] = {CTL_HW, HW_USERMEM64};
+ sz = sizeof(tmp);
+ if (sysctl(usermem_mib, 2, &tmp, &sz, NULL, 0) != 0) {
+ goto error;
+ }
+ ram_total = tmp;
+
+ int uvmexp_mib[] = {CTL_VM, VM_UVMEXP};
+ struct uvmexp uvmexp;
+ sz = sizeof(uvmexp);
+ if (sysctl(uvmexp_mib, 2, &uvmexp, &sz, NULL, 0) == -1) {
+ goto error;
+ }
+ const long pagesize = sysconf(_SC_PAGESIZE);
+ ram_free = uvmexp.free * pagesize;
+
+ int shmall_mib[] = {CTL_KERN, KERN_SHMINFO, KERN_SHMINFO_SHMALL};
+ sz = sizeof(tmp);
+ if (sysctl(shmall_mib, 3, &tmp, &sz, NULL, 0) == -1) {
+ goto error;
+ }
+
+ int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT};
+ struct bcachestats bcstats;
+ sz = sizeof(bcstats);
+ if (sysctl(bcstats_mib, 3, &bcstats, &sz, NULL, 0) == -1) {
+ goto error;
+ }
+ ram_cached = bcstats.numbufpages * pagesize;
+
+ /* Available is free and cached memory. */
+
+ ram_available = ram_free + ram_cached;
+
+ /* This information doesn't seem to exist. */
+
+ ram_shared = ram_buffers = 0;
+#elif defined(__linux__)
+ int unread_fields = 6;
FILE *file = fopen("/proc/meminfo", "r");
if (!file) {
goto error;
@@ -138,6 +187,7 @@ void print_memory(memory_ctx_t *ctx) {
ram_buffers *= 1024UL;
ram_cached *= 1024UL;
ram_shared *= 1024UL;
+#endif
unsigned long ram_used;
if (BEGINS_WITH(ctx->memory_used_method, "memavailable")) {
Index: man/i3status.man
--- man/i3status.man.orig
+++ man/i3status.man
@@ -469,8 +469,8 @@ starting from %cpu0. This feature is currently not sup
=== Memory
-Gets the memory usage from system on a Linux system from +/proc/meminfo+. Other
-systems are currently not supported.
+Gets the memory usage from +/proc/meminfo+ on a Linux system and +sysctl+ on
+OpenBSD. Other systems are currently not supported.
As format placeholders, +total+, +used+, +free+, +available+ and +shared+ are
available. These will print human readable values. It's also possible to prefix
@@ -487,17 +487,16 @@ If the +format_degraded+ parameter is given and either
degraded threshold applies, +format_degraded+ will get used as format string.
It acts equivalently to +format+.
-It's also possible to define the unit for the various format placeholders. As
-+/proc/meminfo+ returns the memory in kB they will be converted to the given
-unit. If no unit is given or the +auto+ option is used, the conversion will
-select the maximum possible unit.
+It's also possible to define the unit for the various format placeholders.
+If no unit is given or the +auto+ option is used, the conversion will select the
+maximum possible unit.
As the converted format placeholder will be a decimal number, the number of
decimals can be configured via the +decimals+ option. If no such option is
given the converted format placeholder will have one decimal.
As Linux' meminfo doesn't expose the overall memory in use, there are multiple
-methods to distinguish the actually used memory.
+methods to distinguish the actually used memory. On OpenBSD, these are the same.
*Example memory_used_method*: +memavailable+ ("total memory" - "MemAvailable", matches +free+ command)
Patch: x11/i3status