Index | Thread | Search

From:
Josh Grosse <josh@jggimi.net>
Subject:
Re: Patch: x11/i3status
To:
ports@openbsd.org
Date:
Wed, 5 Nov 2025 17:54:58 -0500

Download raw body.

Thread
  • Kristaps Dzonsons:

    Patch: x11/i3status

    • Josh Grosse:

      Patch: x11/i3status

On Wed, Nov 05, 2025 at 09:28:42AM -0800, Kristaps Dzonsons wrote:
> 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.

Working well for me on amd64.  Thanks!

> 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)
>