Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Aug 2003 01:01:58 -0400 (EDT)
From:      Andriy Gapon <agapon@cv-nj.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/55985: icewm: CPU status indicator corruption
Message-ID:  <200308260501.h7Q51wXB037081@edge.foundation.invalid>
Resent-Message-ID: <200308260510.h7Q5AFwD004173@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         55985
>Category:       ports
>Synopsis:       icewm: CPU status indicator corruption
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Aug 25 22:10:15 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Andriy Gapon
>Release:        FreeBSD 4.8-RELEASE i386
>Organization:
>Environment:
System: FreeBSD edge.foundation.invalid 4.8-RELEASE FreeBSD 4.8-RELEASE #0: Mon Aug 4 16:23:07 EDT 2003
icewm-1.2.11


	
>Description:
there seems to be a bug in a FreeBSD port patch that enables CPU status
indicator to show interrupt CPU usage, namely "sys" and "nice" heights are
incorrectly calculated.

>How-To-Repeat:
I regularly observe corruptions of CPU status indicator with random pixels
YMMV
>Fix:
this is an updated version of patch-at, my changes are in paint() method

--- patch-cpu begins here ---
--- acpustatus.cc.orig	Tue Aug 19 15:16:17 2003
+++ acpustatus.cc	Tue Aug 26 00:30:57 2003
@@ -27,7 +27,16 @@
 
 #include "intl.h"
 
-#if (defined(linux) || defined(HAVE_KSTAT_H))
+#if (defined(linux) || defined(HAVE_KSTAT_H) || defined(__FreeBSD__))
+
+#ifdef __FreeBSD__
+#include <fcntl.h>
+#include <kvm.h>
+#include <nlist.h>
+#include <sys/dkstat.h>
+#include <sys/resource.h>
+#include <devstat.h>
+#endif
 
 #define UPDATE_INTERVAL 500
 
@@ -50,13 +59,42 @@
     color[IWM_SYS]  = new YColor(clrCpuSys);
     color[IWM_IDLE] = *clrCpuIdle
     		    ? new YColor(clrCpuIdle) : NULL;
-
+#ifdef __FreeBSD__
+    color[IWM_INTR] = new YColor(clrCpuIntr);
+    for (unsigned int i = 0; i < taskBarCPUSamples; i++) {
+        cpu[i][IWM_USER] = cpu[i][IWM_NICE] =
+        cpu[i][IWM_SYS] = cpu[i][IWM_INTR] = 0;
+        cpu[i][IWM_IDLE] = 1;
+    }
+    setSize(taskBarCPUSamples, 20);
+    last_cpu[IWM_USER] = last_cpu[IWM_NICE] = last_cpu[IWM_SYS] =
+    last_cpu[IWM_IDLE] = last_cpu[IWM_INTR] = 0;
+    if( setegid( 2 ) == 0 ) {
+       char errbuf[_POSIX2_LINE_MAX];
+       kd = kvm_openfiles( NULL, NULL, NULL, O_RDONLY, errbuf );
+       setegid( getgid() );
+       if( kd == NULL )
+           fprintf( stderr, "kvm_openfiles: %s\n", errbuf );
+       else {
+           memset( namelist, 0, sizeof(namelist) );
+           namelist[0].n_name = (char*)("_cp_time");
+           if( kvm_nlist( kd, namelist ) != 0 ) {
+               kvm_close( kd );
+               kd = NULL;
+           }
+       }
+    } else {
+       fprintf( stderr, "can't setegid(2), I'm not a setgid exec ?\n" );
+       kd = NULL;
+    }
+#else
     for (int i(0); i < taskBarCPUSamples; i++) {
         cpu[i][IWM_USER] = cpu[i][IWM_NICE] = cpu[i][IWM_SYS] = 0;
         cpu[i][IWM_IDLE] = 1;
     }
     setSize(taskBarCPUSamples, 20);
     last_cpu[IWM_USER] = last_cpu[IWM_NICE] = last_cpu[IWM_SYS] = last_cpu[IWM_IDLE] = 0;
+#endif
     getStatus();
     updateStatus();
     updateToolTip();
@@ -71,6 +109,13 @@
     delete color[IWM_NICE]; color[IWM_NICE] = 0;
     delete color[IWM_SYS];  color[IWM_SYS]  = 0;
     delete color[IWM_IDLE]; color[IWM_IDLE] = 0;
+#ifdef __FreeBSD__
+    delete color[IWM_INTR]; color[IWM_INTR] = 0;
+    if( kd != NULL ) {
+       kvm_close( kd );
+       kd = NULL;
+    }
+#endif
 }
 
 void CPUStatus::paint(Graphics &g, const YRect &/*r*/) {
@@ -81,13 +126,34 @@
         int nice = cpu[i][IWM_NICE];
         int sys = cpu[i][IWM_SYS];
         int idle = cpu[i][IWM_IDLE];
+#ifdef __FreeBSD__
+        int intr = cpu[i][IWM_INTR];
+        int total = user + sys + intr + nice + idle;
+	int totald = total;
+#else
         int total = user + sys + nice + idle;
+#endif
 
         int y = height() - 1;
 
         if (total > 0) {
+#ifdef __FreeBSD__
+           if (intr) {
+               totald -= intr;
+                n = (h * totald) / total; // check rounding
+                if (n >= y) n = y;
+                g.setColor(color[IWM_INTR]);
+                g.drawLine(i, y, i, n);
+                y = n - 1;
+            }
+#endif
             if (sys) {
+#ifdef __FreeBSD__
+                totald -= sys;
+                n = (h * totald)/ total;
+#else
                 n = (h * (total - sys)) / total; // check rounding
+#endif
                 if (n >= y) n = y;
                 g.setColor(color[IWM_SYS]);
                 g.drawLine(i, y, i, n);
@@ -95,7 +161,12 @@
             }
 
             if (nice) {
+#ifdef __FreeBSD__
+                totald -= nice;
+                n = (h * totald)/ total;
+#else
                 n = (h * (total - sys - nice))/ total;
+#endif
                 if (n >= y) n = y;
                 g.setColor(color[IWM_NICE]);
                 g.drawLine(i, y, i, n);
@@ -103,7 +174,12 @@
             }
 
             if (user) {
+#ifdef __FreeBSD__
+                totald -= user;
+                n = (h * totald)/ total;
+#else
                 n = (h * (total - sys - nice - user))/ total;
+#endif
                 if (n >= y) n = y;
                 g.setColor(color[IWM_USER]);
                 g.drawLine(i, y, i, n);
@@ -153,6 +229,14 @@
     sprintf(load, _("CPU Load: %3.2f %3.2f %3.2f, %d processes."),
             l1, l5, l15, sys.procs);
     setToolTip(load);
+#elif defined(__FreeBSD__)
+    char load[31]; // enough for "CPU Load: 999.99 999.99 999.99\0"
+    double loadavg[3];
+    if( kd != NULL && kvm_getloadavg( kd, loadavg, 3 ) != 3 )
+       return;
+    snprintf(load, sizeof(load), "CPU Load: %3.2f %3.2f %3.2f",
+            loadavg[0], loadavg[1], loadavg[2]);
+    setToolTip(load);
 #endif
 }
 
@@ -170,13 +254,43 @@
         cpu[i - 1][IWM_NICE] = cpu[i][IWM_NICE];
         cpu[i - 1][IWM_SYS]  = cpu[i][IWM_SYS];
         cpu[i - 1][IWM_IDLE] = cpu[i][IWM_IDLE];
+#ifdef __FreeBSD__
+        cpu[i - 1][IWM_INTR] = cpu[i][IWM_INTR];
+#endif
     }
     getStatus(),
     repaint();
 }
 
 void CPUStatus::getStatus() {
-#ifdef linux
+#ifdef __FreeBSD__
+    
+    cpu[taskBarCPUSamples-1][IWM_USER] = 0;
+    cpu[taskBarCPUSamples-1][IWM_NICE] = 0;
+    cpu[taskBarCPUSamples-1][IWM_SYS] = 0;
+    cpu[taskBarCPUSamples-1][IWM_INTR] = 0;
+    cpu[taskBarCPUSamples-1][IWM_IDLE] = 0;
+
+    if( kd == NULL ) return;
+
+    long cp_time[CPUSTATES];
+    int c = sizeof( cp_time );
+    if (kvm_read(kd, namelist[0].n_value, &cp_time, c) != c)
+       return;
+
+    long cur[IWM_STATES];
+    cur[IWM_USER] = cp_time[CP_USER];
+    cur[IWM_NICE] = cp_time[CP_NICE];
+    cur[IWM_SYS] = cp_time[CP_SYS];
+    cur[IWM_INTR] = cp_time[CP_INTR];
+    cur[IWM_IDLE] = cp_time[CP_IDLE];
+
+    for (int i = 0; i < IWM_STATES; i++) {
+        cpu[taskBarCPUSamples-1][i] = cur[i] - last_cpu[i];
+       last_cpu[i] = cur[i];
+    }
+
+#elif defined(linux)
     char *p, buf[128];
     long cur[IWM_STATES];
     int len, fd = open("/proc/stat", O_RDONLY);
@@ -210,8 +324,8 @@
             cpu[taskBarCPUSamples-1][IWM_USER], cpu[taskBarCPUSamples-1][IWM_NICE],
             cpu[taskBarCPUSamples-1][IWM_SYS],  cpu[taskBarCPUSamples-1][IDLE]);
 #endif
-#endif /* linux */
-#ifdef HAVE_KSTAT_H
+
+#elif defined(HAVE_KSTAT_H)
 #ifdef HAVE_OLD_KSTAT
 #define ui32 ul
 #endif
--- patch-cpu ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200308260501.h7Q51wXB037081>