Project

General

Profile

Actions

Bug #1607

closed

DragonFly patch for top-3.8b1

Added by lentferj over 14 years ago. Updated over 14 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Category:
-
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:

Description

Dear all,

below is a patch that should add native DF support to the latest
version of top (3.8beta1).

You will also need to update config.guess and config.sub as supplied
by top with the latest version. The can be fetched from here:

http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD

Please test and comment. If ok I will send the patch to unixtop.org
and ask for incorporation into offical branch.

Cheers

Jan

----- Weitergeleitete Nachricht von -----
Datum: Wed, 18 Nov 2009 16:42:16 +0100 (CET)
Von:
Antwort an:
Betreff: DragonFly patch for top-3.8b1
An:

diff x 'config.guess*' -x 'config.sub*' -rNu top-3.8beta1/configure
top-3.8beta1df/configure
--
top-3.8beta1/configure 2008-05-07 05:41:39 0200
++ top-3.8beta1df/configure 2009-11-18 16:02:10 0100
@ -6116,6 +6116,7 @
osf1*) MODULE=decosf1;;
osf4*) MODULE=decosf1;;
osf5*) MODULE=decosf1;;
dragonfly*) MODULE=dragonfly; LIBS="$LIBS lkinfo";;
freebsd*) MODULE=freebsd; USE_KMEM=1; USE_FPH=1;;
hpux7*) MODULE=hpux7;;
hpux8*) MODULE=hpux8;;
diff -x 'config.guess*' -x 'config.sub*' -rNu
top-3.8beta1/machine/m_dragonfly.c top-3.8beta1df/machine/m_dragonfly.c
--
top-3.8beta1/machine/m_dragonfly.c 1970-01-01 01:00:00 0100
++ top-3.8beta1df/machine/m_dragonfly.c 2009-11-18 16:32:37 0100
@ -0,0 +1,961 @
/*
+ * top - a top users display for Unix
+
+ * SYNOPSIS: For FreeBSD-2.x and later
+ *
+ * DESCRIPTION:
+ * Originally written for BSD4.4 system by Christos Zoulas.
+ * Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider
+ * Order support hacked in from top-3.5beta6/machine/m_aix41.c
+ * by Monte Mitzelfelt (for latest top see
http://www.groupsys.com/topinfo/)
+ *
+ * This is the machine-dependent module for FreeBSD 2.2
+ * Works for:
+ * FreeBSD 2.2.x, 3.x, 4.x, and probably FreeBSD 2.1.x
+ *
+ * LIBS: lkvm
+ *
+ * AUTHOR: Christos Zoulas <>
+ * Steven Wallace <>
+ * Wolfram Schneider <>
+ * Hiten Pandya <>
+ *
+ * $FreeBSD: src/usr.bin/top/machine.c,v 1.29.2.2 2001/07/31 20:27:05
tmm Exp $
+ * $DragonFly: src/usr.bin/top/machine.c,v 1.26 2008/10/16 01:52:33
swildner Exp $
+ */

#include <sys/time.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/param.h>

#include "os.h"
#include <err.h>
#include <kvm.h>
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <pwd.h>
#include <sys/errno.h>
#include <sys/sysctl.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/user.h>
#include <sys/vmmeter.h>
#include <sys/resource.h>
#include <sys/rtprio.h>

/
Swap /
#include <stdlib.h>
#include <stdio.h>
#include <sys/conf.h>

#include <osreldate.h> /
for changes in kernel structures /

#include <sys/kinfo.h>
#include <kinfo.h>
#include "top.h"
#include "display.h"
#include "machine.h"
#include "screen.h"
#include "utils.h"

#if 0
static int check_nlist(struct nlist *);
+static int getkval(unsigned long, int *, int, char *);
#endif
int swapmode(int *retavail, int *retfree);
+static int smpmode;
+static int namelength;
+static int cmdlength;

int n_cpus = 0;

/

* needs to be a global symbol, so wrapper can be
+ * modified accordingly.
+ /
static int show_threads = 0;

/
get_process_info passes back a handle. This is what it looks like: /

struct handle
{
+ struct kinfo_proc **next_proc; /
points to next valid proc pointer /
+ int remaining; /
number of pointers remaining /
};

/
declarations for load_avg /
#include "loadavg.h"

#define PP ((pp)>kp_ ## field)
#define LP ((pp)->kp_lwp.kl_ ## field)
#define VP ((pp)->kp_vm_ ## field)

/
define what weighted cpu is. /
#define weighted_cpu(pct, pp) (PP, swtime) == 0 ? 0.0 : \
((pct) / (1.0 - exp(PP, swtime) * logcpu))))

/
what we consider to be process size: /
#define PROCSIZE (VP, map_size) / 1024)

/

* These definitions control the format of the per-process area
+ /

+static char smp_header[] =
" PID
.*s PRI NICE SIZE RES STATE C TIME WCPU CPU COMMAND";

#define smp_Proc_format \
+ "%5d %*.*s %3d %3d%7s %6s %6.6s %1x%7s %5.2f% 5.2f% .*s"

+static char up_header[] =
" PID %
*.*s PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND";

#define up_Proc_format \
+ "%5d %*.*s %3d %3d%7s %6s %-6.6s.0d%7s 5.2f% 5.2f% .*s"



/* process state names for the "STATE" column of the display /
/
the extra nulls in the string "run" are for adding a slash and
the processor number when needed /

+const char *state_abbrev[] =
{
+ "", "RUN\0\0\0", "STOP", "SLEEP",
};


+static kvm_t *kd;

/
values that we stash away in _init and use in later routines /

static double logcpu;

static long lastpid;
+static int ccpu;

/
these are for calculating cpu state percentages /

static struct kinfo_cputime *cp_time, *cp_old;

/
these are for detailing the process states /

int process_states6;
+char *procstatenames[] = {
"", " starting, ", " running, ", " sleeping, ", " stopped, ",
+ " zombie, ",
+ NULL
};

/
these are for detailing the cpu states /
#define CPU_STATES 5
int *cpu_states;
+char *cpustatenames[CPU_STATES + 1] = {
"user", "nice", "system", "interrupt", "idle", NULL
};

/
these are for detailing the memory statistics /

long memory_stats7;
+char *memorynames[] = {
"K Active, ", "K Inact, ", "K Wired, ", "K Cache, ", "K Buf, ", "K Free",
+ NULL
};

long swap_stats7;
+char *swapnames[] = {
/
0 1 2 3 4 5 /
+ "K Total, ", "K Used, ", "K Free, ", "
Inuse, ", "K In, ", "K Out",
+ NULL
};


/
these are for keeping track of the proc array /

+static int nproc;
+static int onproc = -1;
+static int pref_len;
+static struct kinfo_proc *pbase;
+static struct kinfo_proc **pref;

/
these are for getting the memory statistics /

static int pageshift; /
log base 2 of the pagesize /

/
define pagetok in terms of pageshift /

#define pagetok(size) ((size) << pageshift)

/
sorting orders. first is default /
+char *ordernames[] = {
"cpu", "size", "res", "time", "pri", "thr", NULL
};

/
compare routines /
+int proc_compare(), compare_size(), compare_res(), compare_time(),
compare_prio(), compare_thr();

int (*proc_compares[])() = {
proc_compare,
+ compare_size,
+ compare_res,
+ compare_time,
+ compare_prio,
+ NULL
};

static void
+cputime_percentages(int out[CPU_STATES], struct kinfo_cputime *new,
struct kinfo_cputime *old)
{
struct kinfo_cputime diffs;
+ uint64_t total_change, half_total;

/
initialization /
+ total_change = 0;

diffs.cp_user = new
>cp_user - old->cp_user;
+ diffs.cp_nice = new->cp_nice - old->cp_nice;
+ diffs.cp_sys = new->cp_sys - old->cp_sys;
+ diffs.cp_intr = new->cp_intr - old->cp_intr;
+ diffs.cp_idle = new->cp_idle - old->cp_idle;
+ total_change = diffs.cp_user + diffs.cp_nice + diffs.cp_sys
diffs.cp_intr + diffs.cp_idle;
+ old->cp_user = new->cp_user;
+ old->cp_nice = new->cp_nice;
+ old->cp_sys = new->cp_sys;
+ old->cp_intr = new->cp_intr;
+ old->cp_idle = new->cp_idle;

/
avoid divide by zero potential /
+ if (total_change == 0)
+ total_change = 1;

/
calculate percentages based on overall change, rounding up /
+ half_total = total_change >> 1;

out0 = ((diffs.cp_user * 1000LL + half_total) / total_change);
+ out1 = ((diffs.cp_nice * 1000LL + half_total) / total_change);
+ out2 = ((diffs.cp_sys * 1000LL + half_total) / total_change);
+ out3 = ((diffs.cp_intr * 1000LL + half_total) / total_change);
+ out4 = ((diffs.cp_idle * 1000LL + half_total) / total_change);
}

int
+machine_init(struct statics *statics)
{
+ int pagesize;
+ size_t modelen;
+ struct passwd *pw;
+ struct timeval boottime;

if (n_cpus < 1) {
+ if (kinfo_get_cpus(&n_cpus))
+ err(1, "kinfo_get_cpus failed");
+ }

/
get boot time /
+ modelen = sizeof(boottime);
+ if (sysctlbyname("kern.boottime", &boottime, &modelen, NULL, 0) == 1)
+ {
+ /
we have no boottime to report /
+ boottime.tv_sec = -1;
+ }

modelen = sizeof(smpmode);
+ if ((sysctlbyname("machdep.smp_active", &smpmode, &modelen, NULL,
0) < 0 &&
+ sysctlbyname("smp.smp_active", &smpmode, &modelen, NULL, 0) < 0) ||
+ modelen != sizeof(smpmode))
+ smpmode = 0;

while ((pw = getpwent()) != NULL) {
+ if ((int)strlen(pw>pw_name) > namelength)
+ namelength = strlen(pw->pw_name);
+ }
+ if (namelength < 8)
+ namelength = 8;
+ if (smpmode && namelength > 13)
+ namelength = 13;
+ else if (namelength > 15)
+ namelength = 15;

if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL)
+ return 1;

if (kinfo_get_sched_ccpu(&ccpu)) {
+ fprintf(stderr, "top: kinfo_get_sched_ccpu failed\n");
+ return(-1);
+ }

/
this is used in calculating WCPU - calculate it ahead of time /
+ logcpu = log(loaddouble(ccpu));

pbase = NULL;
+ pref = NULL;
+ nproc = 0;
+ onproc = 1;
+ /
get the page size with "getpagesize" and calculate pageshift
from it /
+ pagesize = getpagesize();
+ pageshift = 0;
+ while (pagesize > 1)
+ {
+ pageshift++;
+ pagesize >>= 1;
+ }

/
we only need the amount of log(2)1024 for our conversion /
+ pageshift -= LOG1024;

/
fill in the statics information /
+ statics>procstate_names = procstatenames;
+ statics->cpustate_names = cpustatenames;
+ statics->memory_names = memorynames;
+ statics->boottime = boottime.tv_sec;
+ statics->swap_names = swapnames;
+ statics->order_names = ordernames;

/
all done! /
+ return(0);
}

char *
+format_header(char *uname_field)
{
+ static char Header128;

snprintf(Header, sizeof(Header), smpmode ? smp_header : up_header,
+ namelength, namelength, uname_field);

if (screen_width <= 79)
+ cmdlength = 80;
+ else
+ cmdlength = 89;

cmdlength = cmdlength - strlen(Header) + 6;

return Header;
}

static int swappgsin = 1;
+static int swappgsout = -1;
+extern struct timeval timeout;

void
+get_system_info(struct system_info *si)
{
+ size_t len;
+ int cpu;

if (cpu_states == NULL) {
+ cpu_states = malloc(sizeof(*cpu_states) * CPU_STATES * n_cpus);
+ if (cpu_states NULL)
+ err(1, "malloc");
+ bzero(cpu_states, sizeof(*cpu_states) * CPU_STATES * n_cpus);
+ }
+ if (cp_time NULL) {
+ cp_time = malloc(2 * n_cpus * sizeof(cp_time0));
+ if (cp_time == NULL)
+ err(1, "cp_time");
+ cp_old = cp_time + n_cpus;

len = n_cpus * sizeof(cp_old0);
+ bzero(cp_time, len);
+ if (sysctlbyname("kern.cputime", cp_old, &len, NULL, 0))
+ err(1, "kern.cputime");
+ }

len = n_cpus * sizeof(cp_time0);
+ bzero(cp_time, len);
+ if (sysctlbyname("kern.cputime", cp_time, &len, NULL, 0))
+ err(1, "kern.cputime");

getloadavg(si>load_avg, 3);

lastpid = 0;

/
convert cp_time counts to percentages /
+ for (cpu = 0; cpu < n_cpus; +cpu) {
cputime_percentages(cpu_states + cpu * CPU_STATES,
+ &cp_time[cpu], &cp_old[cpu]);
+ }

/
sum memory & swap statistics /
+ {
+ struct vmmeter vmm;
+ struct vmstats vms;
+ size_t vms_size = sizeof(vms);
+ size_t vmm_size = sizeof(vmm);
+ static unsigned int swap_delay = 0;
+ static int swapavail = 0;
+ static int swapfree = 0;
+ static int bufspace = 0;

if (sysctlbyname("vm.vmstats", &vms, &vms_size, NULL, 0))
+ err(1, "sysctlbyname: vm.vmstats");

if (sysctlbyname("vm.vmmeter", &vmm, &vmm_size, NULL, 0))
+ err(1, "sysctlbyname: vm.vmmeter");

if (kinfo_get_vfs_bufspace(&bufspace))
+ err(1, "kinfo_get_vfs_bufspace");

/
convert memory stats to Kbytes /
+ memory_stats0 = pagetok(vms.v_active_count);
+ memory_stats1 = pagetok(vms.v_inactive_count);
+ memory_stats2 = pagetok(vms.v_wire_count);
+ memory_stats3 = pagetok(vms.v_cache_count);
+ memory_stats4 = bufspace / 1024;
+ memory_stats5 = pagetok(vms.v_free_count);
+ memory_stats6 = 1;

/
first interval /
+ if (swappgsin < 0) {
+ swap_stats4 = 0;
+ swap_stats5 = 0;
+ }

/
compute differences between old and new swap statistic /
+ else {
+ swap_stats4 = pagetok(((vmm.v_swappgsin - swappgsin)));
+ swap_stats5 = pagetok(((vmm.v_swappgsout - swappgsout)));
+ }

swappgsin = vmm.v_swappgsin;
+ swappgsout = vmm.v_swappgsout;

/
call CPU heavy swapmode() only for changes /
+ if (swap_stats4 > 0 || swap_stats5 > 0 || swap_delay == 0) {
+ swap_stats3 = swapmode(&swapavail, &swapfree);
+ swap_stats0 = swapavail;
+ swap_stats1 = swapavail - swapfree;
+ swap_stats2 = swapfree;
+ }
+ swap_delay = 1;
+ swap_stats6 = -1;
+ }

/
set arrays and strings /
+ si>cpustates = cpu_states;
+ si->memory = memory_stats;
+ si->swap = swap_stats;


+ if(lastpid > 0) {
+ si->last_pid = lastpid;
+ } else {
+ si->last_pid = 1;
+ }
}


+static struct handle handle;

caddr_t get_process_info(struct system_info *si, struct process_select *sel,
int compare_index)
{
register int i;
+ register int total_procs;
+ register int active_procs;
+ register struct kinfo_proc **prefp;
+ register struct kinfo_proc *pp;

/
these are copied out of sel for speed /
+ int show_idle;
+ int show_self;
+ int show_system;
+ int show_uid;

pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc);
+ if (nproc > onproc)
+ pref = (struct kinfo_proc *
) realloc(pref, sizeof(struct
kinfo_proc )
+ * (onproc = nproc));
+ if (pref NULL || pbase NULL) {
+ (void) fprintf(stderr, "top: Out of memory.\n");
+ quit(23);
+ }
+ /
get a pointer to the states summary array /
+ si>procstates = process_states;

/
set up flags which define what we are going to select /
+ show_idle = sel->idle;
+ show_self = 0;
+ show_system = sel->system;
+ show_uid = sel->uid != 1;

/
count up process states and get pointers to interesting procs /
+ total_procs = 0;
+ active_procs = 0;
+ memset((char *)process_states, 0, sizeof(process_states));
+ prefp = pref;
+ for (pp = pbase, i = 0; i < nproc; pp++, i++)
+ {
+ /

+ * Place pointers to each valid proc structure in pref[].
+ * Process slots that are actually in use have a non-zero
+ * status field. Processes with P_SYSTEM set are system
+ * processes---these get ignored unless show_sysprocs is set.
+ /
+ if (((show_threads && (LP == -1)) ||
+ ((show_self != PP) &&
+ (show_system || ((PP & P_SYSTEM) 0)))))
+ {
+ total_procs++;
+ process_states[(unsigned char) PP(pp, stat)]++;
+ if ((show_threads && (LP(pp, pid) -1)) ||
+ (show_idle || (LP != 0) ||
+ (((LP LSRUN)) &&
+ (!show_uid || PP(pp, ruid) (uid_t)sel>uid))))
+ {
+ *prefp++ = pp;
+ active_procs++;
+ }
+ }
+ }

qsort((char *)pref, active_procs, sizeof(struct kinfo_proc *),
+ proc_compares[compare_index]);

/
remember active and total counts /
+ si->p_total = total_procs;
+ si->p_active = pref_len = active_procs;

/
pass back a handle /
+ handle.next_proc = pref;
+ handle.remaining = active_procs;
+ return((caddr_t)&handle);
}

char fmt128; /
static area where result is built /

char *
+format_next_process(caddr_t xhandle, char *(*get_userid)())
{
+ struct kinfo_proc *pp;
+ long cputime;
+ double pct;
+ struct handle *hp;
+ char status16;
+ char const *wrapper;
+ int state;
+ int xnice;

/
find and remember the next proc structure /
+ hp = (struct handle *)xhandle;
+ pp = *(hp->next_proc++);
+ hp->remaining--;

/
set the wrapper for the process/thread name /
+ if ((PP & P_SWAPPEDOUT))
+ wrapper = "[]"; /
swapped process [pname] /
+ else if (((PP & P_SYSTEM) != 0) && (LP > 0))
+ wrapper = "()"; /
system process (pname) /
+ else if (show_threads && (LP == 1))
+ wrapper = "<>"; /
pure kernel threads <thread> /
+ else
+ wrapper = NULL;

/
get the process's command name /
+ if (wrapper != NULL) {
+ char *comm = PP;
#define COMSIZ sizeof(PP)
char buf[COMSIZ];
+ (void) strncpy(buf, comm, COMSIZ);
+ comm0 = wrapper0;
+ (void) strncpy(&comm1, buf, COMSIZ - 2);
+ comm[COMSIZ - 2] = '\0';
+ (void) strncat(comm, &wrapper1, COMSIZ - 1);
+ comm[COMSIZ - 1] = '\0';
+ }

/

+ * Convert the process's runtime from microseconds to seconds. This
+ * time includes the interrupt time although that is not wanted here.
+ * ps(1) is similarly sloppy.
+ /
+ cputime = (LP + LP) / 1000000;

/
calculate the base for cpu percentages /
+ pct = pctdouble(LP);

/
generate "STATE" field /
+ switch (state = LP) {
+ case LSRUN:
+ if (smpmode && LP & TDF_RUNNING)
+ sprintf(status, "CPU%d", LP);
+ else
+ strcpy(status, "RUN");
+ break;
+ case LSSLEEP:
+ if (LP != NULL) {
+ sprintf(status, "%.6s", LP);
+ break;
+ }
+ /
fall through /
+ default:

if (state >= 0 &&
+ (unsigned)state < sizeof(state_abbrev) / sizeof(*state_abbrev))
+ sprintf(status, "%.6s", state_abbrev[(unsigned char) state]);
+ else
+ sprintf(status, "?%5d", state);
+ break;
+ }

if (PP == SZOMB)
+ strcpy(status, "ZOMB");

/

+ * idle time 0 - 31 -> nice value 21 - +52
* normal time -> nice value -20 - 20
* real time 0 - 31 -> nice value -52 - -21
+ * thread 0 - 31 -> nice value -53 -
+ /
+ switch(LP) {
+ case RTP_PRIO_REALTIME:
+ xnice = PRIO_MIN - 1 - RTP_PRIO_MAX + LP;
+ break;
+ case RTP_PRIO_IDLE:
+ xnice = PRIO_MAX + 1 + LP;
+ break;
+ case RTP_PRIO_THREAD:
+ xnice = PRIO_MIN - 1 - RTP_PRIO_MAX - LP;
+ break;
+ default:
+ xnice = PP;
+ break;
+ }

/
format this entry /
+ snprintf(fmt, sizeof(fmt),
+ smpmode ? smp_Proc_format : up_Proc_format,
+ (int)PP,
+ namelength, namelength,
+ get_userid(PP),
+ (int)((show_threads && (LP == -1)) ?
+ LP : LP),
+ (int)xnice,
+ format_k(PROCSIZE),
+ format_k(pagetok(VP)),
+ status,
+ (int)(smpmode ? LP : 0),
+ format_time(cputime),
+ 100.0 * weighted_cpu(pct, pp),
+ 100.0 * pct,
+ cmdlength,
+ printable(PP));

/
return the result /
+ return(fmt);
}

#if 0
/

+ * check_nlist(nlst) - checks the nlist to see if any symbols were not
+ * found. For every symbol that was not found, a one-line
+ * message is printed to stderr. The routine returns the
+ * number of symbols NOT found.
+ /
static int
+check_nlist(struct nlist *nlst)
{
+ int i;

/
check to see if we got ALL the symbols we requested /
+ /
this will write one line to stderr for every symbol not found /

i = 0;
+ while (nlst>n_name != NULL)
+ {
+ if (nlst->n_type == 0)
+ {
+ /
this one wasn't found /
+ (void) fprintf(stderr, "kernel: no symbol named `%s'\n",
+ nlst->n_name);
+ i = 1;
+ }
+ nlst++;
+ }

return(i);
}
#endif

/
comparison routines for qsort /

/

+ * proc_compare - comparison function for "qsort"
+ * Compares the resource consumption of two processes using five
+ * distinct keys. The keys (in descending order of importance) are:
+ * percent cpu, cpu ticks, state, resident set size, total virtual
+ * memory usage. The process states are ordered as follows (from least
+ * to most important): WAIT, zombie, sleep, stop, start, run. The
+ * array declaration below maps a process state index into a number
+ * that reflects this ordering.
+ /

+static unsigned char sorted_state[] =
{
+ 0, /
not used /
+ 3, /
sleep /
+ 1, /
ABANDONED (WAIT) /
+ 6, /
run /
+ 5, /
start /
+ 2, /
zombie /
+ 4 /
stop /
};


#define ORDERKEY_PCTCPU \
+ if (lresult = (long) LP - (long) LP, \
+ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)

#define CPTICKS (LP + LP)

#define ORDERKEY_CPTICKS \
+ if ((result = CPTICKS > CPTICKS ? 1 : \
+ CPTICKS < CPTICKS ? -1 : 0) == 0)

#define ORDERKEY_STATE \
+ if ((result = sorted_state[(unsigned char) PP] - \
+ sorted_state[(unsigned char) PP]) 0)

#define ORDERKEY_PRIO \
+ if ((result = LP(p2, prio) - LP(p1, prio)) 0)

#define ORDERKEY_KTHREADS \
+ if ((result = (LP 0) - (LP(p2, pid) 0)) 0)

#define ORDERKEY_KTHREADS_PRIO \
+ if ((result = LP(p2, tdprio) - LP(p1, tdprio)) 0)

#define ORDERKEY_RSSIZE \
+ if ((result = VP - VP) 0)

#define ORDERKEY_MEM \
+ if ( (result = PROCSIZE(p2) - PROCSIZE(p1)) 0 )

/
compare_cpu - the comparison function for sorting by cpu percentage /

+int
/
compare_cpu(const void arg1, const void *arg2) */
proc_compare(const void *arg1, const void *arg2)
{
+ const struct proc *const*pp1 = arg1;
+ const struct proc *const*pp2 = arg2;
+ const struct kinfo_proc *p1;
+ const struct kinfo_proc *p2;
+ int result;
+ pctcpu lresult;

/
remove one level of indirection /
+ p1 = *(const struct kinfo_proc *const *) pp1;
+ p2 = *(const struct kinfo_proc *const *) pp2;

ORDERKEY_PCTCPU
+ ORDERKEY_CPTICKS
+ ORDERKEY_STATE
+ ORDERKEY_PRIO
+ ORDERKEY_RSSIZE
+ ORDERKEY_MEM
+ {}

return(result);
}

/
compare_size - the comparison function for sorting by total memory
usage /

int
+compare_size(const void *arg1, const void *arg2)
{
+ struct proc *const *pp1 = arg1;
+ struct proc *const *pp2 = arg2;
+ struct kinfo_proc *p1;
+ struct kinfo_proc *p2;
+ int result;
+ pctcpu lresult;

/
remove one level of indirection /
+ p1 = *(struct kinfo_proc *const
) pp1;
+ p2 = (struct kinfo_proc *const) pp2;

ORDERKEY_MEM
+ ORDERKEY_RSSIZE
+ ORDERKEY_PCTCPU
+ ORDERKEY_CPTICKS
+ ORDERKEY_STATE
+ ORDERKEY_PRIO
+ {}

return(result);
}

/* compare_res - the comparison function for sorting by resident set size /

int
+compare_res(const void *arg1, const void *arg2)
{
+ struct proc *const *pp1 = arg1;
+ struct proc *const *pp2 = arg2;
+ struct kinfo_proc *p1;
+ struct kinfo_proc *p2;
+ int result;
+ pctcpu lresult;

/
remove one level of indirection /
+ p1 = *(struct kinfo_proc *const
) pp1;
+ p2 = (struct kinfo_proc *const) pp2;

ORDERKEY_RSSIZE
+ ORDERKEY_MEM
+ ORDERKEY_PCTCPU
+ ORDERKEY_CPTICKS
+ ORDERKEY_STATE
+ ORDERKEY_PRIO
+ {}

return(result);
}

/* compare_time - the comparison function for sorting by total cpu time /

int
+compare_time(const void *arg1, const void *arg2)
{
+ struct proc *const *pp1 = arg1;
+ struct proc *const *pp2 = arg2;
+ const struct kinfo_proc *p1;
+ const struct kinfo_proc *p2;
+ int result;
+ pctcpu lresult;

/
remove one level of indirection /
+ p1 = *(struct kinfo_proc *const
) pp1;
+ p2 = (struct kinfo_proc *const) pp2;

ORDERKEY_CPTICKS
+ ORDERKEY_PCTCPU
+ ORDERKEY_KTHREADS
+ ORDERKEY_KTHREADS_PRIO
+ ORDERKEY_STATE
+ ORDERKEY_PRIO
+ ORDERKEY_RSSIZE
+ ORDERKEY_MEM
+ {}

return(result);
+ }

/* compare_prio - the comparison function for sorting by cpu percentage /

+int
+compare_prio(const void *arg1, const void *arg2)
{
+ struct proc *const *pp1 = arg1;
+ struct proc *const *pp2 = arg2;
+ const struct kinfo_proc *p1;
+ const struct kinfo_proc *p2;
+ int result;
+ pctcpu lresult;

/
remove one level of indirection /
+ p1 = *(struct kinfo_proc *const
) pp1;
+ p2 = (struct kinfo_proc *const) pp2;

ORDERKEY_KTHREADS
+ ORDERKEY_KTHREADS_PRIO
+ ORDERKEY_PRIO
+ ORDERKEY_CPTICKS
+ ORDERKEY_PCTCPU
+ ORDERKEY_STATE
+ ORDERKEY_RSSIZE
+ ORDERKEY_MEM
+ {}

return(result);
}

int
+compare_thr(const void arg1, const void *arg2)
{
+ struct proc *const *pp1 = arg1;
+ struct proc *const *pp2 = arg2;
+ const struct kinfo_proc *p1;
+ const struct kinfo_proc *p2;
+ int result;
+ pctcpu lresult;

/
remove one level of indirection /
+ p1 = *(struct kinfo_proc *const
) pp1;
+ p2 = (struct kinfo_proc *const) pp2;

ORDERKEY_KTHREADS
+ ORDERKEY_KTHREADS_PRIO
+ ORDERKEY_CPTICKS
+ ORDERKEY_PCTCPU
+ ORDERKEY_STATE
+ ORDERKEY_RSSIZE
+ ORDERKEY_MEM
+ {}

return(result);
}

/*
* proc_owner(pid) - returns the uid that owns process "pid", or -1 if
+ * the process does not exist.
+ * It is EXTREMLY IMPORTANT that this function work correctly.
+ * If top runs setuid root (as in SVR4), then this function
+ * is the only thing that stands in the way of a serious
+ * security problem. It validates requests for the "kill"
+ * and "renice" commands.
+ /

+int
+proc_owner(int pid)
{
+ int xcnt;
+ struct kinfo_proc **prefp;
+ struct kinfo_proc *pp;

prefp = pref;
+ xcnt = pref_len;
+ while (--xcnt >= 0)
+ {
+ pp = *prefp++;
+ if (PP == (pid_t)pid)
+ {
+ return((int)PP);
+ }
+ }
+ return(-1);
}


/

+ * swapmode is based on a program called swapinfo written
+ * by Kevin Lahey <>.
+ */
int
+swapmode(int *retavail, int *retfree)
{
+ int n;
+ int pagesize = getpagesize();
+ struct kvm_swap swapary1;

*retavail = 0;
+ *retfree = 0;

#define CONVERT ((quad_t)(v) * pagesize / 1024)

n = kvm_getswapinfo(kd, swapary, 1, 0);
+ if (n < 0 || swapary0.ksw_total == 0)
+ return(0);

*retavail = 0.ksw_total">CONVERT;
+ *retfree = 0.ksw_total - swapary0.ksw_used">CONVERT;

n = (int)((double)swapary0.ksw_used * 100.0 /
+ (double)swapary0.ksw_total);
+ return(n);
+}

----- Ende der weitergeleiteten Nachricht -----

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.


Files

top-3.8b1-df.patch (26.1 KB) top-3.8b1-df.patch lentferj, 11/18/2009 05:35 PM
Actions #1

Updated by lentferj over 14 years ago

Piping the diff directly into the mail propably wasn't the best idea.
Patch attached.

Regards

Jan

Actions #2

Updated by alexh over 14 years ago

Hi,

First off, indentation looks rather inconsistent: see for example lines 233
- 257 of the diff, it seems to use a random number of spaces each time
instead of tabs.
For the rest, the code looks ok and it would be definitely good to get it
into upstream top.

As far as we are concerned, WCPU is not of interest and there has been some
discussion on completely removing it or replacing it by something useful;
see issue1484 [1]. Matt's suggestion of showing a column with the
accumulated children CPU time would be a nice thing to have. While this may
not be acceptable for the upstream top, I'd definitely welcome a step in
that direction.

Keep up the good work!

Cheers,
Alex Hornung

[1]: http://bugs.dragonflybsd.org/issue1484

Actions #3

Updated by lentferj over 14 years ago

Patch submitted on unixtop sourceforge website.

Actions

Also available in: Atom PDF