From abba2c89ab7a28813588507e918f53dc14db10dd Mon Sep 17 00:00:00 2001 From: lucic71 Date: Tue, 19 Jul 2022 23:56:57 +0300 Subject: [PATCH 01/13] Fix platform dependent field --- src/print_cpu_usage.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/print_cpu_usage.c b/src/print_cpu_usage.c index a7ee2e46..968f044f 100644 --- a/src/print_cpu_usage.c +++ b/src/print_cpu_usage.c @@ -45,14 +45,12 @@ struct cpu_usage { long system; long idle; long total; + int spin; #else int user; int nice; int system; int idle; -#if defined(__OpenBSD__) - int spin; -#endif int total; #endif }; From 0ade29c99b190843ae59fea6bd0be43892f94a7a Mon Sep 17 00:00:00 2001 From: lucic71 Date: Tue, 19 Jul 2022 23:59:33 +0300 Subject: [PATCH 02/13] Document some of the requirements on OpenBSD --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index eb65e10f..e08851a7 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,11 @@ On debian-based systems, the following line will install all requirements: apt-get install autoconf libconfuse-dev libyajl-dev libasound2-dev libiw-dev asciidoc libpulse-dev libnl-genl-3-dev meson ``` +On OpenBSD, the following line will install all requirements: +```bash +pkg_add pluseaudio meson +``` + ## Upstream i3status is developed at https://github.com/i3/i3status From 6b2831223093891e117cee342b6c9f68808c4e6e Mon Sep 17 00:00:00 2001 From: lucic71 Date: Wed, 20 Jul 2022 09:28:53 +0300 Subject: [PATCH 03/13] Add function that prints formatted output This function will be called from all architectures --- src/print_mem.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 4 deletions(-) diff --git a/src/print_mem.c b/src/print_mem.c index 76a70b90..bb94985d 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "i3status.h" #define MAX_DECIMALS 4 @@ -12,12 +14,9 @@ #define BINARY_BASE 1024UL -#if defined(__linux__) 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__) /* * Prints the given amount of bytes in a human readable manner. * @@ -40,7 +39,10 @@ static int print_bytes_human(char *outwalk, unsigned long bytes, const char *uni static int print_percentage(char *outwalk, float percent) { return snprintf(outwalk, STRING_SIZE, "%.1f%s", percent, pct_mark); } -#endif + +static unsigned long page2mbyte (unsigned pageCnt) { + return (pageCnt * getpagesize ()) >> 20; +} #if defined(__linux__) /* @@ -86,6 +88,70 @@ static unsigned long memory_absolute(const char *mem_amount, const unsigned long } #endif +struct print_mem_info { + unsigned long ram_total; + unsigned long ram_free; + unsigned long ram_used; + unsigned long ram_available; + unsigned long ram_buffers; + unsigned long ram_cached; + unsigned long ram_shared; + char *output_color; +}; + + +void print_formatted_memory(struct print_mem_info *minfo, memory_ctx_t *ctx) { + char *outwalk = ctx->buf; + const char *selected_format = ctx->format; + char string_ram_total[STRING_SIZE]; + char string_ram_used[STRING_SIZE]; + char string_ram_free[STRING_SIZE]; + char string_ram_available[STRING_SIZE]; + char string_ram_shared[STRING_SIZE]; + char string_percentage_free[STRING_SIZE]; + char string_percentage_available[STRING_SIZE]; + char string_percentage_used[STRING_SIZE]; + char string_percentage_shared[STRING_SIZE]; + + if (minfo->output_color) { + START_COLOR(minfo->output_color); + + if (ctx->format_degraded) + selected_format = ctx->format_degraded; + } + + print_bytes_human(string_ram_total, minfo->ram_total, ctx->unit, ctx->decimals); + print_bytes_human(string_ram_used, minfo->ram_used, ctx->unit, ctx->decimals); + print_bytes_human(string_ram_free, minfo->ram_free, ctx->unit, ctx->decimals); + print_bytes_human(string_ram_available, minfo->ram_available, ctx->unit, ctx->decimals); + print_bytes_human(string_ram_shared, minfo->ram_shared, ctx->unit, ctx->decimals); + print_percentage(string_percentage_free, 100.0 * minfo->ram_free / minfo->ram_total); + print_percentage(string_percentage_available, 100.0 * minfo->ram_available / minfo->ram_total); + print_percentage(string_percentage_used, 100.0 * minfo->ram_used / minfo->ram_total); + print_percentage(string_percentage_shared, 100.0 * minfo->ram_shared / minfo->ram_total); + + placeholder_t placeholders[] = { + {.name = "%total", .value = string_ram_total}, + {.name = "%used", .value = string_ram_used}, + {.name = "%free", .value = string_ram_free}, + {.name = "%available", .value = string_ram_available}, + {.name = "%shared", .value = string_ram_shared}, + {.name = "%percentage_free", .value = string_percentage_free}, + {.name = "%percentage_available", .value = string_percentage_available}, + {.name = "%percentage_used", .value = string_percentage_used}, + {.name = "%percentage_shared", .value = string_percentage_shared}}; + + const size_t num = sizeof(placeholders) / sizeof(placeholder_t); + char *formatted = format_placeholders(selected_format, &placeholders[0], num); + OUTPUT_FORMATTED; + free(formatted); + + if (minfo->output_color) + END_COLOR; + + OUTPUT_FULL_TEXT(ctx->buf); +} + void print_memory(memory_ctx_t *ctx) { char *outwalk = ctx->buf; @@ -214,6 +280,36 @@ void print_memory(memory_ctx_t *ctx) { error: OUTPUT_FULL_TEXT("can't read memory"); fputs("i3status: Cannot read system memory using /proc/meminfo\n", stderr); + +#elif defined(__OpenBSD__) + struct print_mem_info minfo; + + int mib [] = { CTL_VM, VM_UVMEXP }; + struct uvmexp our_uvmexp; + size_t size = sizeof (our_uvmexp); + + if (sysctl (mib, 2, &our_uvmexp, &size, NULL, 0) < 0) { + OUTPUT_FULL_TEXT(""); + fputs("i3status: cannot get memory info!\n", stderr); + return; + } + +/* + OUTPUT_FULL_TEXT(""); + fprintf(stderr, "i3status: used memory=%d\n", ((our_uvmexp.npages - our_uvmexp.free - our_uvmexp.inactive) * getpagesize()) >> 20); +*/ + + minfo.ram_total = page2mbyte(our_uvmexp.npages); + minfo.ram_free = page2mbyte(our_uvmexp.free + our_uvmexp.inactive); + minfo.ram_used = page2mbyte(our_uvmexp.npages - our_uvmexp.free - our_uvmexp.inactive); + minfo.ram_available = minfo.ram_free; + minfo.ram_buffers = 0; + minfo.ram_cached = 0; + minfo.ram_shared = 0; + minfo.output_color = NULL; + + print_formatted_memory(&minfo, ctx); + #else OUTPUT_FULL_TEXT(""); fputs("i3status: Memory status information is not supported on this system\n", stderr); From a6ca7b4f2f08b6910b1b748451cf633b5c40b05c Mon Sep 17 00:00:00 2001 From: lucic71 Date: Wed, 20 Jul 2022 09:50:49 +0300 Subject: [PATCH 04/13] Get memory info in a different function --- src/print_mem.c | 206 +++++++++++++++++------------------------------- 1 file changed, 72 insertions(+), 134 deletions(-) diff --git a/src/print_mem.c b/src/print_mem.c index bb94985d..a727a97d 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -99,73 +99,12 @@ struct print_mem_info { char *output_color; }; - -void print_formatted_memory(struct print_mem_info *minfo, memory_ctx_t *ctx) { +static void get_memory_info(struct print_mem_info *minfo, memory_ctx_t *ctx) { char *outwalk = ctx->buf; - const char *selected_format = ctx->format; - char string_ram_total[STRING_SIZE]; - char string_ram_used[STRING_SIZE]; - char string_ram_free[STRING_SIZE]; - char string_ram_available[STRING_SIZE]; - char string_ram_shared[STRING_SIZE]; - char string_percentage_free[STRING_SIZE]; - char string_percentage_available[STRING_SIZE]; - char string_percentage_used[STRING_SIZE]; - char string_percentage_shared[STRING_SIZE]; - - if (minfo->output_color) { - START_COLOR(minfo->output_color); - - if (ctx->format_degraded) - selected_format = ctx->format_degraded; - } - - print_bytes_human(string_ram_total, minfo->ram_total, ctx->unit, ctx->decimals); - print_bytes_human(string_ram_used, minfo->ram_used, ctx->unit, ctx->decimals); - print_bytes_human(string_ram_free, minfo->ram_free, ctx->unit, ctx->decimals); - print_bytes_human(string_ram_available, minfo->ram_available, ctx->unit, ctx->decimals); - print_bytes_human(string_ram_shared, minfo->ram_shared, ctx->unit, ctx->decimals); - print_percentage(string_percentage_free, 100.0 * minfo->ram_free / minfo->ram_total); - print_percentage(string_percentage_available, 100.0 * minfo->ram_available / minfo->ram_total); - print_percentage(string_percentage_used, 100.0 * minfo->ram_used / minfo->ram_total); - print_percentage(string_percentage_shared, 100.0 * minfo->ram_shared / minfo->ram_total); - - placeholder_t placeholders[] = { - {.name = "%total", .value = string_ram_total}, - {.name = "%used", .value = string_ram_used}, - {.name = "%free", .value = string_ram_free}, - {.name = "%available", .value = string_ram_available}, - {.name = "%shared", .value = string_ram_shared}, - {.name = "%percentage_free", .value = string_percentage_free}, - {.name = "%percentage_available", .value = string_percentage_available}, - {.name = "%percentage_used", .value = string_percentage_used}, - {.name = "%percentage_shared", .value = string_percentage_shared}}; - - const size_t num = sizeof(placeholders) / sizeof(placeholder_t); - char *formatted = format_placeholders(selected_format, &placeholders[0], num); - OUTPUT_FORMATTED; - free(formatted); - - if (minfo->output_color) - END_COLOR; - - OUTPUT_FULL_TEXT(ctx->buf); -} - -void print_memory(memory_ctx_t *ctx) { - char *outwalk = ctx->buf; - #if defined(__linux__) - 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; - unsigned long ram_buffers; - unsigned long ram_cached; - unsigned long ram_shared; + + minfo->output_color = NULL FILE *file = fopen("/proc/meminfo", "r"); if (!file) { @@ -173,17 +112,17 @@ void print_memory(memory_ctx_t *ctx) { } for (char line[128]; fgets(line, sizeof line, file);) { if (BEGINS_WITH(line, "MemTotal:")) { - ram_total = strtoul(line + strlen("MemTotal:"), NULL, 10); + minfo->ram_total = strtoul(line + strlen("MemTotal:"), NULL, 10); } else if (BEGINS_WITH(line, "MemFree:")) { - ram_free = strtoul(line + strlen("MemFree:"), NULL, 10); + minfo->ram_free = strtoul(line + strlen("MemFree:"), NULL, 10); } else if (BEGINS_WITH(line, "MemAvailable:")) { - ram_available = strtoul(line + strlen("MemAvailable:"), NULL, 10); + minfo->ram_available = strtoul(line + strlen("MemAvailable:"), NULL, 10); } else if (BEGINS_WITH(line, "Buffers:")) { - ram_buffers = strtoul(line + strlen("Buffers:"), NULL, 10); + minfo->ram_buffers = strtoul(line + strlen("Buffers:"), NULL, 10); } else if (BEGINS_WITH(line, "Cached:")) { - ram_cached = strtoul(line + strlen("Cached:"), NULL, 10); + minfo->ram_cached = strtoul(line + strlen("Cached:"), NULL, 10); } else if (BEGINS_WITH(line, "Shmem:")) { - ram_shared = strtoul(line + strlen("Shmem:"), NULL, 10); + minfo->ram_shared = strtoul(line + strlen("Shmem:"), NULL, 10); } else { continue; } @@ -198,43 +137,67 @@ void print_memory(memory_ctx_t *ctx) { } // Values are in kB, convert them to B. - ram_total *= 1024UL; - ram_free *= 1024UL; - ram_available *= 1024UL; - ram_buffers *= 1024UL; - ram_cached *= 1024UL; - ram_shared *= 1024UL; - - unsigned long ram_used; + minfo->ram_total *= 1024UL; + minfo->ram_free *= 1024UL; + minfo->ram_available *= 1024UL; + minfo->ram_buffers *= 1024UL; + minfo->ram_cached *= 1024UL; + minfo->ram_shared *= 1024UL; + + unsigned long minfo->ram_used; if (BEGINS_WITH(ctx->memory_used_method, "memavailable")) { - ram_used = ram_total - ram_available; + minfo->ram_used = minfo->ram_total - minfo->ram_available; } else if (BEGINS_WITH(ctx->memory_used_method, "classical")) { - ram_used = ram_total - ram_free - ram_buffers - ram_cached; + minfo->ram_used = minfo->ram_total - minfo->ram_free - minfo->ram_buffers - minfo->ram_cached; } else { die("Unexpected value: memory_used_method = %s", ctx->memory_used_method); } if (ctx->threshold_degraded) { - const unsigned long threshold = memory_absolute(ctx->threshold_degraded, ram_total); - if (ram_available < threshold) { + const unsigned long threshold = memory_absolute(ctx->threshold_degraded, minfo->ram_total); + if (minfo->ram_available < threshold) { output_color = "color_degraded"; } } if (ctx->threshold_critical) { - const unsigned long threshold = memory_absolute(ctx->threshold_critical, ram_total); - if (ram_available < threshold) { - output_color = "color_bad"; + const unsigned long threshold = memory_absolute(ctx->threshold_critical, minfo->ram_total); + if (minfo->ram_available < threshold) { + minfo->output_color = "color_bad"; } } +error: + OUTPUT_FULL_TEXT("can't read memory"); + fputs("i3status: Cannot read system memory using /proc/meminfo\n", stderr); - if (output_color) { - START_COLOR(output_color); +#elif defined(__OpenBSD__) + int mib [] = { CTL_VM, VM_UVMEXP }; + struct uvmexp our_uvmexp; + size_t size = sizeof (our_uvmexp); - if (ctx->format_degraded) - selected_format = ctx->format_degraded; + if (sysctl (mib, 2, &our_uvmexp, &size, NULL, 0) < 0) { + OUTPUT_FULL_TEXT(""); + fputs("i3status: cannot get memory info!\n", stderr); + return; } + minfo->ram_total = page2mbyte(our_uvmexp.npages); + minfo->ram_free = page2mbyte(our_uvmexp.free + our_uvmexp.inactive); + minfo->ram_used = page2mbyte(our_uvmexp.npages - our_uvmexp.free - our_uvmexp.inactive); + minfo->ram_available = minfo->ram_free; + minfo->ram_buffers = 0; + minfo->ram_cached = 0; + minfo->ram_shared = 0; + minfo->output_color = NULL; +#else + OUTPUT_FULL_TEXT(""); + fputs("i3status: Memory status information is not supported on this system\n", stderr); +#endif +} + +void print_formatted_memory(struct print_mem_info *minfo, memory_ctx_t *ctx) { + char *outwalk = ctx->buf; + const char *selected_format = ctx->format; char string_ram_total[STRING_SIZE]; char string_ram_used[STRING_SIZE]; char string_ram_free[STRING_SIZE]; @@ -245,15 +208,22 @@ void print_memory(memory_ctx_t *ctx) { char string_percentage_used[STRING_SIZE]; char string_percentage_shared[STRING_SIZE]; - print_bytes_human(string_ram_total, ram_total, ctx->unit, ctx->decimals); - print_bytes_human(string_ram_used, ram_used, ctx->unit, ctx->decimals); - print_bytes_human(string_ram_free, ram_free, ctx->unit, ctx->decimals); - print_bytes_human(string_ram_available, ram_available, ctx->unit, ctx->decimals); - print_bytes_human(string_ram_shared, ram_shared, ctx->unit, ctx->decimals); - print_percentage(string_percentage_free, 100.0 * ram_free / ram_total); - print_percentage(string_percentage_available, 100.0 * ram_available / ram_total); - print_percentage(string_percentage_used, 100.0 * ram_used / ram_total); - print_percentage(string_percentage_shared, 100.0 * ram_shared / ram_total); + if (minfo->output_color) { + START_COLOR(minfo->output_color); + + if (ctx->format_degraded) + selected_format = ctx->format_degraded; + } + + print_bytes_human(string_ram_total, minfo->ram_total, ctx->unit, ctx->decimals); + print_bytes_human(string_ram_used, minfo->ram_used, ctx->unit, ctx->decimals); + print_bytes_human(string_ram_free, minfo->ram_free, ctx->unit, ctx->decimals); + print_bytes_human(string_ram_available, minfo->ram_available, ctx->unit, ctx->decimals); + print_bytes_human(string_ram_shared, minfo->ram_shared, ctx->unit, ctx->decimals); + print_percentage(string_percentage_free, 100.0 * minfo->ram_free / minfo->ram_total); + print_percentage(string_percentage_available, 100.0 * minfo->ram_available / minfo->ram_total); + print_percentage(string_percentage_used, 100.0 * minfo->ram_used / minfo->ram_total); + print_percentage(string_percentage_shared, 100.0 * minfo->ram_shared / minfo->ram_total); placeholder_t placeholders[] = { {.name = "%total", .value = string_ram_total}, @@ -271,47 +241,15 @@ void print_memory(memory_ctx_t *ctx) { OUTPUT_FORMATTED; free(formatted); - if (output_color) + if (minfo->output_color) END_COLOR; OUTPUT_FULL_TEXT(ctx->buf); +} - return; -error: - OUTPUT_FULL_TEXT("can't read memory"); - fputs("i3status: Cannot read system memory using /proc/meminfo\n", stderr); - -#elif defined(__OpenBSD__) +void print_memory(memory_ctx_t *ctx) { struct print_mem_info minfo; - int mib [] = { CTL_VM, VM_UVMEXP }; - struct uvmexp our_uvmexp; - size_t size = sizeof (our_uvmexp); - - if (sysctl (mib, 2, &our_uvmexp, &size, NULL, 0) < 0) { - OUTPUT_FULL_TEXT(""); - fputs("i3status: cannot get memory info!\n", stderr); - return; - } - -/* - OUTPUT_FULL_TEXT(""); - fprintf(stderr, "i3status: used memory=%d\n", ((our_uvmexp.npages - our_uvmexp.free - our_uvmexp.inactive) * getpagesize()) >> 20); -*/ - - minfo.ram_total = page2mbyte(our_uvmexp.npages); - minfo.ram_free = page2mbyte(our_uvmexp.free + our_uvmexp.inactive); - minfo.ram_used = page2mbyte(our_uvmexp.npages - our_uvmexp.free - our_uvmexp.inactive); - minfo.ram_available = minfo.ram_free; - minfo.ram_buffers = 0; - minfo.ram_cached = 0; - minfo.ram_shared = 0; - minfo.output_color = NULL; - + get_memory_info(&minfo, ctx); print_formatted_memory(&minfo, ctx); - -#else - OUTPUT_FULL_TEXT(""); - fputs("i3status: Memory status information is not supported on this system\n", stderr); -#endif } From 547683e84f953707bd5d0382f139909dfefe2b62 Mon Sep 17 00:00:00 2001 From: lucic71 Date: Wed, 20 Jul 2022 13:49:19 +0300 Subject: [PATCH 05/13] Use bytes instead of kbytes --- src/print_mem.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/print_mem.c b/src/print_mem.c index a727a97d..2d8b1d19 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -40,8 +40,8 @@ static int print_percentage(char *outwalk, float percent) { return snprintf(outwalk, STRING_SIZE, "%.1f%s", percent, pct_mark); } -static unsigned long page2mbyte (unsigned pageCnt) { - return (pageCnt * getpagesize ()) >> 20; +static unsigned long page2byte (unsigned pageCnt) { + return pageCnt * getpagesize (); } #if defined(__linux__) @@ -181,9 +181,9 @@ static void get_memory_info(struct print_mem_info *minfo, memory_ctx_t *ctx) { return; } - minfo->ram_total = page2mbyte(our_uvmexp.npages); - minfo->ram_free = page2mbyte(our_uvmexp.free + our_uvmexp.inactive); - minfo->ram_used = page2mbyte(our_uvmexp.npages - our_uvmexp.free - our_uvmexp.inactive); + minfo->ram_total = page2byte(our_uvmexp.npages); + minfo->ram_free = page2byte(our_uvmexp.free + our_uvmexp.inactive); + minfo->ram_used = page2byte(our_uvmexp.npages - our_uvmexp.free - our_uvmexp.inactive); minfo->ram_available = minfo->ram_free; minfo->ram_buffers = 0; minfo->ram_cached = 0; From 685817c17eb46d1bc85a8f93f757ee0511114133 Mon Sep 17 00:00:00 2001 From: lucic71 Date: Wed, 20 Jul 2022 13:49:51 +0300 Subject: [PATCH 06/13] Delete bad code --- src/print_mem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/print_mem.c b/src/print_mem.c index 2d8b1d19..49f47638 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -144,7 +144,6 @@ static void get_memory_info(struct print_mem_info *minfo, memory_ctx_t *ctx) { minfo->ram_cached *= 1024UL; minfo->ram_shared *= 1024UL; - unsigned long minfo->ram_used; if (BEGINS_WITH(ctx->memory_used_method, "memavailable")) { minfo->ram_used = minfo->ram_total - minfo->ram_available; } else if (BEGINS_WITH(ctx->memory_used_method, "classical")) { From b3a120611fd4d10a5c0c7779511db81a4c0c6fbc Mon Sep 17 00:00:00 2001 From: lucic71 Date: Wed, 20 Jul 2022 13:50:08 +0300 Subject: [PATCH 07/13] Make local function static --- src/print_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/print_mem.c b/src/print_mem.c index 49f47638..cfd36083 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -194,7 +194,7 @@ static void get_memory_info(struct print_mem_info *minfo, memory_ctx_t *ctx) { #endif } -void print_formatted_memory(struct print_mem_info *minfo, memory_ctx_t *ctx) { +static void print_formatted_memory(struct print_mem_info *minfo, memory_ctx_t *ctx) { char *outwalk = ctx->buf; const char *selected_format = ctx->format; char string_ram_total[STRING_SIZE]; From c1b088b21fd2e75d3b033fc39ebaf290c812884b Mon Sep 17 00:00:00 2001 From: lucic71 Date: Wed, 20 Jul 2022 14:02:45 +0300 Subject: [PATCH 08/13] Handle memory used and threshold options --- src/print_mem.c | 74 +++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/src/print_mem.c b/src/print_mem.c index cfd36083..1e508a4d 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -17,6 +17,17 @@ static const char *const iec_symbols[] = {"B", "KiB", "MiB", "GiB", "TiB"}; #define MAX_EXPONENT ((sizeof iec_symbols / sizeof *iec_symbols) - 1) +struct print_mem_info { + unsigned long ram_total; + unsigned long ram_free; + unsigned long ram_used; + unsigned long ram_available; + unsigned long ram_buffers; + unsigned long ram_cached; + unsigned long ram_shared; + char *output_color; +}; + /* * Prints the given amount of bytes in a human readable manner. * @@ -44,7 +55,6 @@ static unsigned long page2byte (unsigned pageCnt) { return pageCnt * getpagesize (); } -#if defined(__linux__) /* * Convert a string to its absolute representation based on the total * memory of `mem_total`. @@ -86,18 +96,32 @@ static unsigned long memory_absolute(const char *mem_amount, const unsigned long return amount; } -#endif -struct print_mem_info { - unsigned long ram_total; - unsigned long ram_free; - unsigned long ram_used; - unsigned long ram_available; - unsigned long ram_buffers; - unsigned long ram_cached; - unsigned long ram_shared; - char *output_color; -}; +static void handle_used_method(struct print_mem_info *minfo, memory_ctx_t *ctx) { + if (BEGINS_WITH(ctx->memory_used_method, "memavailable")) { + minfo->ram_used = minfo->ram_total - minfo->ram_available; + } else if (BEGINS_WITH(ctx->memory_used_method, "classical")) { + minfo->ram_used = minfo->ram_total - minfo->ram_free - minfo->ram_buffers - minfo->ram_cached; + } else { + die("Unexpected value: memory_used_method = %s", ctx->memory_used_method); + } +} + +static void handle_threshold(struct print_mem_info *minfo, memory_ctx_t *ctx) { + if (ctx->threshold_degraded) { + const unsigned long threshold = memory_absolute(ctx->threshold_degraded, minfo->ram_total); + if (minfo->ram_available < threshold) { + minfo->output_color = "color_degraded"; + } + } + + if (ctx->threshold_critical) { + const unsigned long threshold = memory_absolute(ctx->threshold_critical, minfo->ram_total); + if (minfo->ram_available < threshold) { + minfo->output_color = "color_bad"; + } + } +} static void get_memory_info(struct print_mem_info *minfo, memory_ctx_t *ctx) { char *outwalk = ctx->buf; @@ -144,27 +168,8 @@ static void get_memory_info(struct print_mem_info *minfo, memory_ctx_t *ctx) { minfo->ram_cached *= 1024UL; minfo->ram_shared *= 1024UL; - if (BEGINS_WITH(ctx->memory_used_method, "memavailable")) { - minfo->ram_used = minfo->ram_total - minfo->ram_available; - } else if (BEGINS_WITH(ctx->memory_used_method, "classical")) { - minfo->ram_used = minfo->ram_total - minfo->ram_free - minfo->ram_buffers - minfo->ram_cached; - } else { - die("Unexpected value: memory_used_method = %s", ctx->memory_used_method); - } - - if (ctx->threshold_degraded) { - const unsigned long threshold = memory_absolute(ctx->threshold_degraded, minfo->ram_total); - if (minfo->ram_available < threshold) { - output_color = "color_degraded"; - } - } - - if (ctx->threshold_critical) { - const unsigned long threshold = memory_absolute(ctx->threshold_critical, minfo->ram_total); - if (minfo->ram_available < threshold) { - minfo->output_color = "color_bad"; - } - } + handle_used_method(minfo, ctx); + handle_threshold(minfo, ctx); error: OUTPUT_FULL_TEXT("can't read memory"); fputs("i3status: Cannot read system memory using /proc/meminfo\n", stderr); @@ -188,6 +193,9 @@ static void get_memory_info(struct print_mem_info *minfo, memory_ctx_t *ctx) { minfo->ram_cached = 0; minfo->ram_shared = 0; minfo->output_color = NULL; + + handle_used_method(minfo, ctx); + handle_threshold(minfo, ctx); #else OUTPUT_FULL_TEXT(""); fputs("i3status: Memory status information is not supported on this system\n", stderr); From 2f9efa9ed34e3507d63b4b45b71913211aa6e889 Mon Sep 17 00:00:00 2001 From: lucic71 Date: Wed, 20 Jul 2022 14:24:24 +0300 Subject: [PATCH 09/13] Add some more requirements for OpenBSD --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e08851a7..49ad9e6f 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,9 @@ On debian-based systems, the following line will install all requirements: apt-get install autoconf libconfuse-dev libyajl-dev libasound2-dev libiw-dev asciidoc libpulse-dev libnl-genl-3-dev meson ``` -On OpenBSD, the following line will install all requirements: +On OpenBSD, the following line will install some of the requirements: ```bash -pkg_add pluseaudio meson +pkg_add autoconf libconfuse libyajl asciidoc pluseaudio meson ``` ## Upstream From 7f523c33d94656e2591d2933e3d72a51fde6f521 Mon Sep 17 00:00:00 2001 From: lucic71 Date: Wed, 20 Jul 2022 13:09:12 +0000 Subject: [PATCH 10/13] Add link to FreeBSD implementation --- src/print_mem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/print_mem.c b/src/print_mem.c index 1e508a4d..decc644e 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -197,6 +197,7 @@ static void get_memory_info(struct print_mem_info *minfo, memory_ctx_t *ctx) { handle_used_method(minfo, ctx); handle_threshold(minfo, ctx); #else + // For FreeBSD implementation see: https://bal0n.es/git/slstatus/file/components/ram.c.html OUTPUT_FULL_TEXT(""); fputs("i3status: Memory status information is not supported on this system\n", stderr); #endif From 1ca722bfa36eb7f068589378e1428e678c625f30 Mon Sep 17 00:00:00 2001 From: lucic71 Date: Thu, 21 Jul 2022 09:24:38 +0300 Subject: [PATCH 11/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49ad9e6f..3c1b0878 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ On debian-based systems, the following line will install all requirements: apt-get install autoconf libconfuse-dev libyajl-dev libasound2-dev libiw-dev asciidoc libpulse-dev libnl-genl-3-dev meson ``` -On OpenBSD, the following line will install some of the requirements: +On OpenBSD, the following line will install the requirements: ```bash pkg_add autoconf libconfuse libyajl asciidoc pluseaudio meson ``` From 62ae24861e484dbffb45bb251e85ab80de8f9bd7 Mon Sep 17 00:00:00 2001 From: lucic71 Date: Thu, 11 Aug 2022 19:04:03 +0300 Subject: [PATCH 12/13] Add buffers and shared mem --- src/print_mem.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/print_mem.c b/src/print_mem.c index decc644e..ddf5f67c 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include "i3status.h" @@ -175,23 +177,41 @@ static void get_memory_info(struct print_mem_info *minfo, memory_ctx_t *ctx) { fputs("i3status: Cannot read system memory using /proc/meminfo\n", stderr); #elif defined(__OpenBSD__) - int mib [] = { CTL_VM, VM_UVMEXP }; + int uvm_mib [] = { CTL_VM, VM_UVMEXP }; + int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT}; + int malloc_mib[] = {CTL_KERN, KERN_MALLOCSTATS, KERN_MALLOC_KMEMSTATS, M_SHM}; struct uvmexp our_uvmexp; + struct bcachestats bcstats; + struct kmemstats kmemstats; size_t size = sizeof (our_uvmexp); - if (sysctl (mib, 2, &our_uvmexp, &size, NULL, 0) < 0) { + if (sysctl(uvm_mib, 2, &our_uvmexp, &size, NULL, 0) < 0) { OUTPUT_FULL_TEXT(""); - fputs("i3status: cannot get memory info!\n", stderr); + fputs("i3status: cannot get memory info (uvm)!\n", stderr); return; } + size = sizeof(bcstats); + if (sysctl(bcstats_mib, 3, &bcstats, &size, NULL, 0) == -1) { + OUTPUT_FULL_TEXT(""); + fputs("i3status: cannot get memory info (bcachestats)!\n", stderr); + return; + } + + size = sizeof(kmemstats); + if (sysctl(malloc_mib, 4, &kmemstats, &size, NULL, 0) == -1) { + OUTPUT_FULL_TEXT(""); + fputs("i3status: cannot get memory info (malloc)!\n", stderr); + return; + } + minfo->ram_total = page2byte(our_uvmexp.npages); minfo->ram_free = page2byte(our_uvmexp.free + our_uvmexp.inactive); minfo->ram_used = page2byte(our_uvmexp.npages - our_uvmexp.free - our_uvmexp.inactive); minfo->ram_available = minfo->ram_free; - minfo->ram_buffers = 0; + minfo->ram_buffers = page2byte(bcstats.numbufpages); minfo->ram_cached = 0; - minfo->ram_shared = 0; + minfo->ram_shared = kmemstats.ks_memuse; minfo->output_color = NULL; handle_used_method(minfo, ctx); From 702d1abc8050a212ce10626c3ecb93e345438bec Mon Sep 17 00:00:00 2001 From: lucic71 Date: Thu, 11 Aug 2022 19:18:00 +0300 Subject: [PATCH 13/13] Update man --- man/i3status.man | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/man/i3status.man b/man/i3status.man index 36e1a6e7..df04c87e 100644 --- a/man/i3status.man +++ b/man/i3status.man @@ -467,8 +467,8 @@ starting from %cpu0. This feature is currently not supported in FreeBSD. === 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 system on Linux from +/proc/meminfo+, on OpenBSD +from sysctl. 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 @@ -495,7 +495,8 @@ 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. The methods are availabe on +OpenBSD as well. *Example memory_used_method*: +memavailable+ ("total memory" - "MemAvailable", matches +free+ command)