bin/64811: systat can't display big numbers in some fields

Valentin Nechayev netch at netch.kiev.ua
Sat Mar 27 09:50:01 PST 2004


>Number:         64811
>Category:       bin
>Synopsis:       systat can't display big numbers in some fields
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Mar 27 09:50:00 PST 2004
>Closed-Date:
>Last-Modified:
>Originator:     Valentin Nechayev
>Release:        FreeBSD 4.9-RELEASE i386
>Organization:
home sweet home
>Environment:
System: FreeBSD iv.nn.kiev.ua 4.9-RELEASE FreeBSD 4.9-RELEASE #2: Thu Mar 18 07:24:01 EET 2004 root at iv.nn.kiev.ua:/var2/usr/obj/sys4/nn14 i386

>Description:

I say only for vmstat page, but this can be valid for other pages and
other fields.
It isn't rare now see huge syscalls, traps, context switches... count.
My home system which is almost obsolete now (Cel800, i815E) allows 1.7
millions of simple syscalls per second. systat can't show 100000 or more;
and five-digit values (10000...99999) aren't separated from neighbours.

>How-To-Repeat:

Run systat & a program which getpid()s in forever cycle.

>Fix:

Following shows big numbers in radiotechnic style: 13400 -> 13k4,
1234567 -> 1m234...
Number cells in counters line are reduced to have space separator.

This may be applicable to other fields, in case they overflow.

Format selection works correctly only if width >= 4.

--- src/usr.bin/systat/vmstat.c.0	Tue Apr  2 23:11:59 2002
+++ src/usr.bin/systat/vmstat.c	Sat Mar 27 19:34:20 2004
@@ -518,20 +518,20 @@
 	putint(s.desiredvnodes, VMSTATROW + 15, VMSTATCOL, 9);
 	putint(s.numvnodes, VMSTATROW + 16, VMSTATCOL, 9);
 	putint(s.freevnodes, VMSTATROW + 17, VMSTATCOL, 9);
-	PUTRATE(Cnt.v_vnodein, PAGEROW + 2, PAGECOL + 5, 5);
-	PUTRATE(Cnt.v_vnodeout, PAGEROW + 2, PAGECOL + 10, 5);
-	PUTRATE(Cnt.v_swapin, PAGEROW + 2, PAGECOL + 17, 5);
-	PUTRATE(Cnt.v_swapout, PAGEROW + 2, PAGECOL + 22, 5);
-	PUTRATE(Cnt.v_vnodepgsin, PAGEROW + 3, PAGECOL + 5, 5);
-	PUTRATE(Cnt.v_vnodepgsout, PAGEROW + 3, PAGECOL + 10, 5);
-	PUTRATE(Cnt.v_swappgsin, PAGEROW + 3, PAGECOL + 17, 5);
-	PUTRATE(Cnt.v_swappgsout, PAGEROW + 3, PAGECOL + 22, 5);
-	PUTRATE(Cnt.v_swtch, GENSTATROW + 1, GENSTATCOL, 5);
-	PUTRATE(Cnt.v_trap, GENSTATROW + 1, GENSTATCOL + 5, 5);
-	PUTRATE(Cnt.v_syscall, GENSTATROW + 1, GENSTATCOL + 10, 5);
-	PUTRATE(Cnt.v_intr, GENSTATROW + 1, GENSTATCOL + 15, 5);
-	PUTRATE(Cnt.v_soft, GENSTATROW + 1, GENSTATCOL + 20, 5);
-	PUTRATE(Cnt.v_vm_faults, GENSTATROW + 1, GENSTATCOL + 25, 5);
+	PUTRATE(Cnt.v_vnodein, PAGEROW + 2, PAGECOL + 5, 4);
+	PUTRATE(Cnt.v_vnodeout, PAGEROW + 2, PAGECOL + 10, 4);
+	PUTRATE(Cnt.v_swapin, PAGEROW + 2, PAGECOL + 17, 4);
+	PUTRATE(Cnt.v_swapout, PAGEROW + 2, PAGECOL + 22, 4);
+	PUTRATE(Cnt.v_vnodepgsin, PAGEROW + 3, PAGECOL + 5, 4);
+	PUTRATE(Cnt.v_vnodepgsout, PAGEROW + 3, PAGECOL + 10, 4);
+	PUTRATE(Cnt.v_swappgsin, PAGEROW + 3, PAGECOL + 17, 4);
+	PUTRATE(Cnt.v_swappgsout, PAGEROW + 3, PAGECOL + 22, 4);
+	PUTRATE(Cnt.v_swtch, GENSTATROW + 1, GENSTATCOL + 1, 4);
+	PUTRATE(Cnt.v_trap, GENSTATROW + 1, GENSTATCOL + 6, 4);
+	PUTRATE(Cnt.v_syscall, GENSTATROW + 1, GENSTATCOL + 11, 4);
+	PUTRATE(Cnt.v_intr, GENSTATROW + 1, GENSTATCOL + 16, 4);
+	PUTRATE(Cnt.v_soft, GENSTATROW + 1, GENSTATCOL + 21, 4);
+	PUTRATE(Cnt.v_vm_faults, GENSTATROW + 1, GENSTATCOL + 25, 4);
 	mvprintw(DISKROW, DISKCOL + 5, "                              ");
 	for (i = 0, c = 0; i < num_devices && c < MAXDRIVES; i++)
 		if (dev_select[i].selected) {
@@ -665,6 +665,7 @@
 	int n, l, c, w;
 {
 	char b[128];
+	size_t ll;
 
 	move(l, c);
 	if (n == 0) {
@@ -672,8 +673,20 @@
 			addch(' ');
 		return;
 	}
-	snprintf(b, sizeof(b), "%*d", w, n);
-	if (strlen(b) > w) {
+	ll = snprintf(b, sizeof(b), "%*d", w, n);
+	if (ll > w && n >= 1000 && n < 1000000) {	/* kilo */
+		div_t d = div(n,1000);
+		snprintf(b, sizeof b, "%dk%-*d", d.quot, w, d.rem);
+		b[w] = 0;
+		ll = strchr(b, 'k') ? w : w + 1;
+	}
+	if (ll > w && n >= 1000000 && n < 1000000000) {	/* mega */
+		div_t d = div(n,1000000);
+		snprintf(b, sizeof b, "%dm%-*d", d.quot, w, d.rem);
+		b[w] = 0;
+		ll = strchr(b, 'm') ? w : w + 1;
+	}
+	if (ll > w) {
 		while (w-- > 0)
 			addch('*');
 		return;
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list