From nobody Wed Jul 26 14:11:50 2023 X-Original-To: dev-commits-ports-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4R9wnL6QYdz4pgDx; Wed, 26 Jul 2023 14:11:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4R9wnL46Rrz3FQr; Wed, 26 Jul 2023 14:11:50 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1690380710; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=zd1Sf3KvJ65pM+KuAYdjQx0rYP7MseLsC5W6MspMxf0=; b=rkiWbqbYSGraHogbLqXtOft4XjIbVE7Z8irCpIpdrt75NWfnlb/1CrGR5NK9rJbIhMUrZO upJc2st/SxysoRFoUuP9ra3MBPQY+HbVvfTeRL3EKUiXU6dBj7hv+KI+miC88kvc9U+les YRP3xYD5Iqqrhp8GTK+7jwWBl1KrHqhnZrxC0R4zio2dLmK04lmuki88kWJJMr/9+GjxEZ w7pMFld7c4NG6cIVWcCiO1ZGTgDHXww0JICVOeiVI6kdgv0QL2ZKngl1HN+bb5Ie475Wj9 y4okIkjqVC92i83lWn59zq29fMfl/xXy9KuR2JToYOvTCs/ZgTdk9+RqNUJaFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1690380710; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=zd1Sf3KvJ65pM+KuAYdjQx0rYP7MseLsC5W6MspMxf0=; b=N7X2gJOu0iRscAP1U99TPjlU7CymyuDDeayaCP2K27xRYTJkQvHTVpzk23PwuHvYmTt1U/ As8HYulnbpzEvhkaDTnQggItsg5x+QPMVgLsfFi7HMkQM9X37NwvKux4lcyCnD4YSZirvR 5plaO9oV2AdZhLIZLIwBwBAtySgnQkud0CiibNIO6N+hYCDbKyKYAUJEdP1e+3ZGkzeBCz f5UCtdK1fHzgJ+vQtF3QlF+z0rUZyEKxpwed+RBqK6Q8ZHwNxFC/JVENyFkL8b8RhuQmEj +0oOoZ14SlYwLroapjaollD8bUNT9xL2PnuHSGi02k4zohYgoAQcRlEicmjqKg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1690380710; a=rsa-sha256; cv=none; b=JX1N2f1lIwlzWWf001XU2nzlgeDdM+jqOLnerGhVlKbiRQVVvIvc2buKXFakr3PgZXRx9a Ow7PGTbd6HkTD3dQbtPPU9awmucmE5KuwIidoWa2tw0OOo7I+NK62C555R4Ilu02HSjTYk JxsOMFd7oNMfV5/xLoVCubHm5B9vO3yleN5VFZDCGMbUaxnufmakQaK/HUaj+rrldXUEnP zYRStc63JHPDapHVCEEGJlo6oL9FEynAxAMdzthMpIqSPg5JVfldwa2DvB82gtH57yRP5i sxwOvC2CYJNX0mmRyoUV/VvYRJMQKcJIdzcTygosp9k1x79KOyNC82ZOUibQ0Q== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4R9wnL3BPwzlXY; Wed, 26 Jul 2023 14:11:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 36QEBoPc098026; Wed, 26 Jul 2023 14:11:50 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 36QEBopr098025; Wed, 26 Jul 2023 14:11:50 GMT (envelope-from git) Date: Wed, 26 Jul 2023 14:11:50 GMT Message-Id: <202307261411.36QEBopr098025@gitrepo.freebsd.org> To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org From: Alexey Dokuchaev Subject: git: c8bcf96c005b - main - sysutils/wmmemfree: modernize, unbreak, undeprecate the port (+) List-Id: Commits to the main branch of the FreeBSD ports repository List-Archive: https://lists.freebsd.org/archives/dev-commits-ports-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-ports-main@freebsd.org X-BeenThere: dev-commits-ports-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: danfe X-Git-Repository: ports X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c8bcf96c005b148e5a3074c53b6a5909958e37a4 Auto-Submitted: auto-generated The branch main has been updated by danfe: URL: https://cgit.FreeBSD.org/ports/commit/?id=c8bcf96c005b148e5a3074c53b6a5909958e37a4 commit c8bcf96c005b148e5a3074c53b6a5909958e37a4 Author: Alexey Dokuchaev AuthorDate: 2023-07-26 14:10:34 +0000 Commit: Alexey Dokuchaev CommitDate: 2023-07-26 14:10:34 +0000 sysutils/wmmemfree: modernize, unbreak, undeprecate the port (+) When I ported this dockapp 20 years ago, it was not uncommon to peek inside ``struct vmmeter'' and other kernel structures with kvm_read(3) to obtain various data (e.g. page counters). These interfaces had always been fragile and potentially unsafe (due to sgid-to-kmem requirement), so let's switch to sysctl(3) instead as it provides the same data via documented, stable API. Address another problem while here: the dockapp tried to update the window from the signal handler, and no Xlib function can be safely called within a signal handler*. Do as advised and only raise a "need update" flag upon receiving a signal, then gather new data and redraw the window in the main loop. This approach, however, cannot work without modifying process_events() because of the blocking nature of XNextEvent(3) -- put another select(2) call in front so it can relinquish control to the outer loop. [*] http://www-h.eng.cam.ac.uk/help/tpl/graphics/X/signals.html --- sysutils/wmmemfree/Makefile | 12 +-- sysutils/wmmemfree/files/mem_freebsd.c | 150 +++++++++++------------------ sysutils/wmmemfree/files/mem_freebsd.h | 32 ------ sysutils/wmmemfree/files/patch-Makefile | 2 +- sysutils/wmmemfree/files/patch-dockapp.c | 39 ++++++++ sysutils/wmmemfree/files/patch-draw.c | 11 --- sysutils/wmmemfree/files/patch-wmmemfree.c | 43 ++++++++- 7 files changed, 135 insertions(+), 154 deletions(-) diff --git a/sysutils/wmmemfree/Makefile b/sysutils/wmmemfree/Makefile index 37ffa81f9091..e2119be083f7 100644 --- a/sysutils/wmmemfree/Makefile +++ b/sysutils/wmmemfree/Makefile @@ -4,21 +4,15 @@ PORTREVISION= 4 CATEGORIES= sysutils windowmaker MASTER_SITES= SUNSITE/X11/xutils -MAINTAINER= ports@FreeBSD.org +MAINTAINER= danfe@FreeBSD.org COMMENT= Memory and swap monitoring dockapp -DEPRECATED= Broken on all supported FreeBSD releases for more than an year -EXPIRATION_DATE= 2023-08-16 -BROKEN_FreeBSD_12= fails to compile: read_mem.c: invalid use of undefined type 'struct vmmeter' -BROKEN_FreeBSD_13= fails to compile: read_mem.c: invalid use of undefined type 'struct vmmeter' -BROKEN_FreeBSD_14= fails to compile: read_mem.c: invalid use of undefined type 'struct vmmeter' -BROKEN_mips= fails to compile: mem_freebsd.c: storage size of 'vm' isn't known -BROKEN_mips64= fails to compile: mem_freebsd.c: storage size of 'vm' isn't known +LICENSE= GPLv2+ USES= localbase tar:bzip2 xorg USE_XORG= x11 xext xpm -PLIST_FILES= "@(,kmem,2555) bin/wmmemfree" man/man1/${PORTNAME}.1.gz +PLIST_FILES= bin/${PORTNAME} man/man1/${PORTNAME}.1.gz post-patch: @${CP} ${FILESDIR}/mem_freebsd.* ${WRKSRC} diff --git a/sysutils/wmmemfree/files/mem_freebsd.c b/sysutils/wmmemfree/files/mem_freebsd.c index 5575ee31792c..a639a5d8157c 100644 --- a/sysutils/wmmemfree/files/mem_freebsd.c +++ b/sysutils/wmmemfree/files/mem_freebsd.c @@ -1,118 +1,76 @@ -/* - * mem_freebsd.c - get memory status - * - * Copyright (C) 2003 Alexey Dokuchaev - * Parts are Copyright (C) 1993-2003 FreeBSD Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - */ - #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include -#include "mem_freebsd.h" +long long int mem_total, mem_used, mem_buffers, mem_cached; +long long int swp_total, swp_used; -long long int mem_total, mem_used, mem_free, mem_buffers, mem_cached; -long long int swp_total, swp_used, swp_free; - -static kvm_t *kd; -struct nlist nlst[] = { {"_cnt"}, {"_bufspace"}, {0} }; +enum { total, active, laundry, wired, buffers, swap }; +int mib[swap - total + 1][4]; +/* + * Values below are in kilobytes: we don't need higher granulation, + * and it allows to keep numbers relatively small. + */ +unsigned int mem[swap - total]; +int pagesize; void -mem_init(void) +mem_init() { - int pagesize; - - if (!(kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open"))) - { - perror("kvm_open"); - exit(1); - } + size_t len = 4; - kvm_nlist(kd, nlst); + /* Precache MIB name vectors for faster lookups later */ + sysctlnametomib("vm.stats.vm.v_page_count", mib[total], &len); + sysctlnametomib("vm.stats.vm.v_active_count", mib[active], &len); + sysctlnametomib("vm.stats.vm.v_laundry_count", mib[laundry], &len); + sysctlnametomib("vm.stats.vm.v_wire_count", mib[wired], &len); - if (!nlst[0].n_type) - { - perror("kvm_nlist"); - exit(1); - } + len = 2; + sysctlnametomib("vfs.bufspace", mib[buffers], &len); + sysctlnametomib("vm.swap_info", mib[swap], &len); - seteuid(getuid()); - setegid(getgid()); + pagesize = getpagesize() / 1024; +} - if (geteuid() != getuid() || getegid() != getgid()) - { - perror("sete?id"); - exit(1); +static void +get_swap_info() +{ + struct xswdev xsw; + size_t len = sizeof(xsw); + int n; + + for (swp_total = swp_used = n = 0; ; ++n) { + mib[swap][2] = n; + if (sysctl(mib[swap], 3, &xsw, &len, NULL, 0) == -1) + break; + swp_total += pagesize * xsw.xsw_nblks; + swp_used += pagesize * xsw.xsw_used; } } void mem_getfree() { - struct vmmeter vm; - struct kvm_swap sw; - int bufspace = 0; - unsigned long cnt_offset; - unsigned long bufspace_offset; - - static int firsttime = 1; - static time_t lasttime = 0; - time_t curtime; - - if ((kvm_read(kd, nlst[0].n_value, &vm, sizeof(vm)) - != sizeof(vm)) || - (kvm_read(kd, nlst[1].n_value, &bufspace, sizeof(bufspace)) - != sizeof(bufspace))) - { - perror("kvm_read"); - exit(1); - } + size_t len = 4; + int n; - mem_total = vm.v_page_count; - mem_free = vm.v_free_count; - mem_used = mem_total - mem_free; - mem_cached = vm.v_cache_count; - mem_buffers = bufspace / vm.v_page_size; + for (n = 0; n < buffers - total; ++n) + sysctl(mib[n], 4, &mem[n], &len, NULL, 0); + sysctl(mib[buffers], 2, &mem[buffers], &len, NULL, 0); /* - * Only calculate when first time or when changes took place. - * Do not call it more than 1 time per 2 seconds; otherwise - * it can eat up to 50% of CPU time on heavy swap activity. + * See the following links for explanation which pages we consider + * free and used (cf. Linux vs. FreeBSD): + * https://unix.stackexchange.com/questions/14102/real-memory-usage + * https://unix.stackexchange.com/questions/134862/what-do-the-different-memory-counters-in-freebsd-mean */ - - curtime = time(NULL); - - if (firsttime || curtime > lasttime + 5) - { - if (kvm_getswapinfo(kd, &sw, 1, 0) >= 0 && - sw.ksw_total) - { - swp_total = sw.ksw_total; - swp_used = sw.ksw_used; - swp_free = swp_total - swp_used; - } - firsttime = 0; - lasttime = curtime; - } + mem_total = pagesize * mem[total]; + /* On FreeBSD, "Laundry" had replaced "Cache" in November 2016 */ + mem_cached = pagesize * mem[laundry]; + mem_buffers = mem[buffers] / 1024; + mem_used = pagesize * (mem[active] + mem[wired]); + mem_used += mem_cached + mem_buffers; + + get_swap_info(); } diff --git a/sysutils/wmmemfree/files/mem_freebsd.h b/sysutils/wmmemfree/files/mem_freebsd.h deleted file mode 100644 index d0f86dc328a5..000000000000 --- a/sysutils/wmmemfree/files/mem_freebsd.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * mem_freebsd.h - * - * Copyright (C) 2003 Alexey Dokuchaev - * Parts are Copyright (C) 1993-2003 FreeBSD Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - */ - -#ifndef __MEM_FREEBSD_H__ -#define __MEM_FREEBSD_H__ - -extern long long int mem_total, mem_used; -extern long long int mem_shared, mem_buffers, mem_cached; -extern long long int swp_total, swp_used; - -void mem_init(); -void mem_getfree(); - -#endif /* __MEM_FREEBSD_H__ */ diff --git a/sysutils/wmmemfree/files/patch-Makefile b/sysutils/wmmemfree/files/patch-Makefile index 26f34c806042..0b775f3fc0b6 100644 --- a/sysutils/wmmemfree/files/patch-Makefile +++ b/sysutils/wmmemfree/files/patch-Makefile @@ -18,7 +18,7 @@ INST=install MANUAL=$(PROG).1 -LIBS=-L/usr/X11R6/lib -lX11 -lXext -lXpm -+LIBS+=-lX11 -lXext -lXpm -lkvm ++LIBS+=-lX11 -lXext -lXpm all: $(PROG) diff --git a/sysutils/wmmemfree/files/patch-dockapp.c b/sysutils/wmmemfree/files/patch-dockapp.c new file mode 100644 index 000000000000..94d51d597205 --- /dev/null +++ b/sysutils/wmmemfree/files/patch-dockapp.c @@ -0,0 +1,39 @@ +--- dockapp.c.orig 2003-03-22 18:30:01 UTC ++++ dockapp.c +@@ -41,7 +41,7 @@ + #define WINDOW_HEIGHT 64 + + Display *display; +-int screen; ++int screen, x11fd; + Window iconwindow, window, mapwindow; + Colormap colormap; + GC gc; +@@ -114,6 +114,7 @@ void make_window() + fprintf(stderr, "Could not open display %s\n", opt_display); + exit(1); + } ++ x11fd = ConnectionNumber(display); + screen = DefaultScreen(display); + screenwidth = DisplayWidth(display, screen); + screenheight = DisplayHeight(display, screen); +@@ -254,6 +255,19 @@ void process_events() + XEvent event; + int winx, winy; + ++ XSync(display, False); ++ if(!XPending(display)) ++ { ++ struct timeval timeout; ++ fd_set readset; ++ const int milliseconds = 200; ++ timeout.tv_sec = milliseconds / 1000; ++ timeout.tv_usec = (milliseconds % 1000) * 1000; ++ FD_ZERO(&readset); ++ FD_SET(x11fd, &readset); ++ if(select(x11fd + 1, &readset, NULL, NULL, &timeout) <= 0) ++ return; ++ } + XNextEvent(display, &event); + switch(event.type) + { diff --git a/sysutils/wmmemfree/files/patch-draw.c b/sysutils/wmmemfree/files/patch-draw.c deleted file mode 100644 index 1e107ac48a6e..000000000000 --- a/sysutils/wmmemfree/files/patch-draw.c +++ /dev/null @@ -1,11 +0,0 @@ ---- draw.c.orig Fri Apr 11 12:47:47 2003 -+++ draw.c Fri Apr 11 12:47:54 2003 -@@ -24,7 +24,7 @@ - - #include "dockapp.h" - #include "draw.h" --#include "mem_linux.h" -+#include "mem_freebsd.h" - #include "options.h" - - void draw_window() diff --git a/sysutils/wmmemfree/files/patch-wmmemfree.c b/sysutils/wmmemfree/files/patch-wmmemfree.c index 62f224511132..0193cc03bea5 100644 --- a/sysutils/wmmemfree/files/patch-wmmemfree.c +++ b/sysutils/wmmemfree/files/patch-wmmemfree.c @@ -1,10 +1,27 @@ ---- wmmemfree.c.orig Fri Apr 11 12:48:52 2003 -+++ wmmemfree.c Fri Apr 11 12:50:05 2003 -@@ -43,10 +43,11 @@ +--- wmmemfree.c.orig 2003-03-21 20:47:14 UTC ++++ wmmemfree.c +@@ -27,15 +27,18 @@ + #include "draw.h" + #include "options.h" + ++void mem_init(); ++ + int argc; + char **argv; + int exitloop = 0; ++volatile sig_atomic_t need_update = 0; + + void handle_timer(int sig) { - struct itimerval tv; + if(sig == SIGALRM) + { +- draw_window(); ++ need_update = 1; + } + } + +@@ -45,8 +48,8 @@ void start_timer() -+ mem_init(); tv.it_value.tv_sec = 2; /* give 2 seconds for safety */ tv.it_value.tv_usec = 0; - tv.it_interval.tv_sec = 0; @@ -14,3 +31,19 @@ signal(SIGALRM, handle_timer); setitimer(ITIMER_REAL, &tv, NULL); } +@@ -69,9 +72,15 @@ int main(int carg, char **varg) + argv = varg; + parse_args(); + make_window(); ++ mem_init(); + start_timer(); + while(!exitloop) + { ++ if(need_update) ++ { ++ draw_window(); ++ need_update = 0; ++ } + process_events(); + } + stop_timer();