2 * Copyright (c) 1984 through 2008, William LeFebvre
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
16 * * Neither the name of William LeFebvre nor the names of other
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * top - a top users display for Unix
36 * SYNOPSIS: For FreeBSD 5.x, 6.x, 7.x, 8.x
39 * Originally written for BSD4.4 system by Christos Zoulas.
40 * Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider
41 * Order support hacked in from top-3.5beta6/machine/m_aix41.c
43 * Ported to FreeBSD 5.x and higher by William LeFebvre
45 * AUTHOR: Christos Zoulas <christos@ee.cornell.edu>
46 * Steven Wallace <swallace@freebsd.org>
47 * Wolfram Schneider <wosch@FreeBSD.org>
52 #include <sys/types.h>
53 #include <sys/signal.h>
54 #include <sys/param.h>
63 #include <sys/errno.h>
64 #include <sys/sysctl.h>
65 #include <sys/dkstat.h>
70 #include <sys/vmmeter.h>
71 #include <sys/resource.h>
72 #include <sys/rtprio.h>
81 #include <osreldate.h> /* for changes in kernel structures */
90 extern char* printable
__P((char *));
91 int swapmode
__P((int *retavail
, int *retfree
));
93 static int namelength
;
96 * Versions prior to 5.x do not track threads in kinfo_proc, so we
97 * simply do not display any information about them.
98 * Versions 5.x, 6.x, and 7.x track threads but the data reported
99 * as runtime for each thread is actually per-process and is just
100 * duplicated across all threads. It would be very wrong to show
101 * this data individually for each thread. Therefore we will show
102 * a THR column (number of threads) but not provide any sort of
103 * per-thread display. We distinguish between these three ways of
104 * handling threads as follows: HAS_THREADS indicates that the
105 * system has and tracks kernel threads (a THR column will appear
106 * in the display). HAS_SHOWTHREADS indicates that the system
107 * reports correct per-thread information and we will provide a
108 * per-thread display (the 'H' and 't' command) upon request.
109 * HAS_SHOWTHREADS implies HAS_THREADS.
112 /* HAS_THREADS for anything 5.x and up */
117 /* HAS_SHOWTHREADS for anything 8.x and up */
119 #define HAS_SHOWTHREADS
122 /* get_process_info passes back a handle. This is what it looks like: */
126 struct kinfo_proc
**next_proc
; /* points to next valid proc pointer */
127 int remaining
; /* number of pointers remaining */
130 /* declarations for load_avg */
134 * Macros to access process information:
135 * In versions 4.x and earlier the kinfo_proc structure was a collection of
136 * substructures (kp_proc and kp_eproc). Starting with 5.0 kinfo_proc was
137 * redesigned and "flattene" so that most of the information was available
138 * in a single structure. We use macros to access the various types of
139 * information and define these macros according to the OS revision. The
140 * names PP, EP, and VP are due to the fact that information was originally
141 * contained in the different substructures. We retain these names in the
142 * code for backward compatibility. These macros use ANSI concatenation.
145 * VP: vm (virtual memory information)
148 * PPCPU: where we store calculated cpu% data
149 * SPPTR: where we store pointer to extra calculated data
150 * SP: access to the extra calculated data pointed to by SPPTR
153 #define PP(pp, field) ((pp)->kp_proc . p_##field)
154 #define EP(pp, field) ((pp)->kp_eproc . e_##field)
155 #define VP(pp, field) ((pp)->kp_eproc.e_vm . vm_##field)
156 #define PRUID(pp) ((pp)->kp_eproc.e_pcred.p_ruid)
158 #define PP(pp, field) ((pp)->ki_##field)
159 #define EP(pp, field) ((pp)->ki_##field)
160 #define VP(pp, field) ((pp)->ki_##field)
161 #define PRUID(pp) ((pp)->ki_ruid)
162 #define RP(pp, field) ((pp)->ki_rusage.ru_##field)
163 #define PPCPU(pp) ((pp)->ki_sparelongs[0])
164 #define SPPTR(pp) ((pp)->ki_spareptrs[0])
165 #define SP(pp, field) (((struct save_proc *)((pp)->ki_spareptrs[0]))->sp_##field)
168 /* what we consider to be process size: */
170 #define PROCSIZE(pp) (VP((pp), map.size) / 1024)
172 #define PROCSIZE(pp) (((pp)->ki_size) / 1024)
175 /* calculate a per-second rate using milliseconds */
176 #define per_second(n, msec) (((n) * 1000) / (msec))
178 /* process state names for the "STATE" column of the display */
179 /* the extra nulls in the string "run" are for adding a slash and
180 the processor number when needed */
182 char *state_abbrev
[] =
184 "?", "START", "RUN", "SLEEP", "STOP", "ZOMB", "WAIT", "LOCK"
191 /* these are for dealing with sysctl-based data */
198 static struct sysctl_mib mibs
[] = {
199 { "vm.stats.sys.v_swtch" },
201 { "vm.stats.sys.v_trap" },
203 { "vm.stats.sys.v_intr" },
205 { "vm.stats.sys.v_soft" },
207 { "vm.stats.vm.v_forks" },
209 { "vm.stats.vm.v_vforks" },
211 { "vm.stats.vm.v_rforks" },
213 { "vm.stats.vm.v_vm_faults" },
214 #define V_VM_FAULTS 7
215 { "vm.stats.vm.v_swapin" },
217 { "vm.stats.vm.v_swapout" },
219 { "vm.stats.vm.v_tfree" },
221 { "vm.stats.vm.v_vnodein" },
223 { "vm.stats.vm.v_vnodeout" },
224 #define V_VNODEOUT 12
225 { "vm.stats.vm.v_active_count" },
226 #define V_ACTIVE_COUNT 13
227 { "vm.stats.vm.v_inactive_count" },
228 #define V_INACTIVE_COUNT 14
229 { "vm.stats.vm.v_wire_count" },
230 #define V_WIRE_COUNT 15
231 { "vm.stats.vm.v_cache_count" },
232 #define V_CACHE_COUNT 16
233 { "vm.stats.vm.v_free_count" },
234 #define V_FREE_COUNT 17
235 { "vm.stats.vm.v_swappgsin" },
236 #define V_SWAPPGSIN 18
237 { "vm.stats.vm.v_swappgsout" },
238 #define V_SWAPPGSOUT 19
240 #define VFS_BUFSPACE 20
243 #ifdef HAS_SHOWTHREADS
246 { "kern.proc.proc" },
253 /* these are for calculating cpu state percentages */
255 static long cp_time
[CPUSTATES
];
256 static long cp_old
[CPUSTATES
];
257 static long cp_diff
[CPUSTATES
];
259 /* these are for detailing the process states */
261 int process_states
[8];
262 char *procstatenames
[] = {
263 "", " starting, ", " running, ", " sleeping, ", " stopped, ", " zombie, ",
264 " waiting, ", " locked, ",
268 /* these are for detailing the cpu states */
270 int cpu_states
[CPUSTATES
];
271 char *cpustatenames
[] = {
272 "user", "nice", "system", "interrupt", "idle", NULL
275 /* these are for detailing the kernel information */
278 char *kernelnames
[] = {
279 " ctxsw, ", " trap, ", " intr, ", " soft, ", " fork, ",
280 " flt, ", " pgin, ", " pgout, ", " fr",
284 /* these are for detailing the memory statistics */
286 long memory_stats
[7];
287 char *memorynames
[] = {
288 "K Active, ", "K Inact, ", "K Wired, ", "K Cache, ", "K Buf, ", "K Free",
293 char *swapnames
[] = {
295 "K Total, ", "K Used, ", "K Free, ", "% Inuse, ", "K In, ", "K Out",
301 * pbase points to the array that holds the kinfo_proc structures. pref
302 * (pronounced p-ref) points to an array of kinfo_proc pointers and is where
303 * we build up a list of processes we wish to display. Both pbase and pref are
304 * potentially resized on every call to get_process_info. psize is the number
305 * of procs for which we currently have space allocated. pref_len is the number
306 * of valid pointers in pref (this is used by proc_owner). We start psize off
307 * at -1 to ensure that space gets allocated on the first call to
311 static int psize
= -1;
313 static struct kinfo_proc
*pbase
= NULL
;
314 static struct kinfo_proc
**pref
= NULL
;
316 /* this structure retains information from the proc array between samples */
319 u_int64_t sp_runtime
;
339 int (*format
)(char *, int, struct kinfo_proc
*);
342 /* these are for getting the memory statistics */
344 static int pagesize
; /* kept from getpagesize */
345 static int pageshift
; /* log base 2 of the pagesize */
347 /* define pagetok in terms of pageshift */
349 #define pagetok(size) ((size) << pageshift)
351 /* things that we track between updates */
352 static u_int ctxsws
= 0;
353 static u_int traps
= 0;
354 static u_int intrs
= 0;
355 static u_int softs
= 0;
356 static u_int64_t forks
= 0;
357 static u_int pfaults
;
359 static u_int pageout
;
361 static int swappgsin
= -1;
362 static int swappgsout
= -1;
363 extern struct timeval timeout
;
364 static struct timeval lasttime
= { 0, 0 };
365 static long elapsed_time
;
366 static long elapsed_msecs
;
368 /* things that we track during an update */
369 static long total_io
;
370 static int show_fullcmd
;
371 static struct handle handle
;
372 static int username_length
;
373 static int show_usernames
;
374 static int display_mode
;
375 static int *display_fields
;
376 #ifdef HAS_SHOWTHREADS
377 static int show_threads
= 0;
381 /* sorting orders. first is default */
382 char *ordernames
[] = {
383 "cpu", "size", "res", "time", "pri", "io", "pid", NULL
386 /* compare routines */
387 int proc_compare(), compare_size(), compare_res(), compare_time(),
388 compare_prio(), compare_io(), compare_pid();
390 int (*proc_compares
[])() = {
401 /* swap related calculations */
403 static int mib_swapinfo
[16];
404 static int *mib_swapinfo_idx
;
405 static int mib_swapinfo_size
= 0;
413 m
= sizeof(mib_swapinfo
) / sizeof(mib_swapinfo
[0]);
414 if (sysctlnametomib("vm.swap_info", mib_swapinfo
, &m
) != -1)
416 mib_swapinfo_size
= m
+ 1;
417 mib_swapinfo_idx
= &(mib_swapinfo
[m
]);
422 swap_getdata(long long *retavail
, long long *retfree
)
432 if (mib_swapinfo_size
> 0)
434 *mib_swapinfo_idx
= 0;
435 while (size
= sizeof(xsw
),
436 sysctl(mib_swapinfo
, mib_swapinfo_size
, &xsw
, &size
, NULL
, 0) != -1)
438 dprintf("swap_getdata: swaparea %d: nblks %d, used %d\n",
439 n
, xsw
.xsw_nblks
, xsw
.xsw_used
);
440 total
+= (long long)xsw
.xsw_nblks
;
441 used
+= (long long)xsw
.xsw_used
;
442 *mib_swapinfo_idx
= ++n
;
445 *retavail
= pagetok(total
);
446 *retfree
= pagetok(total
) - pagetok(used
);
450 n
= (int)((double)used
* 100.0 / (double)total
);
463 dprintf("swap_getdata: avail %lld, free %lld, %d%%\n",
464 *retavail
, *retfree
, n
);
469 * getkval(offset, ptr, size) - get a value out of the kernel.
470 * "offset" is the byte offset into the kernel for the desired value,
471 * "ptr" points to a buffer into which the value is retrieved,
472 * "size" is the size of the buffer (and the object to retrieve).
473 * Return 0 on success, -1 on any kind of failure.
477 getkval(unsigned long offset
, int *ptr
, int size
)
482 if (kvm_read(kd
, offset
, (char *) ptr
, size
) == size
)
494 struct sysctl_mib
*mp
;
498 while (mp
->name
!= NULL
)
501 if (sysctlnametomib(mp
->name
, mp
->mib
, &len
) == -1)
503 message_error(" sysctlnametomib: %s", strerror(errno
));
513 get_sysctl(int idx
, void *v
, size_t l
)
516 struct sysctl_mib
*m
;
521 if (sysctl(m
->mib
, m
->miblen
, v
, &len
, NULL
, 0) == -1)
523 message_error(" sysctl: %s", strerror(errno
));
530 get_sysctlsize(int idx
)
534 struct sysctl_mib
*m
;
537 if (sysctl(m
->mib
, m
->miblen
, NULL
, &len
, NULL
, 0) == -1)
539 message_error(" sysctl (size): %s", strerror(errno
));
546 fmt_pid(char *buf
, int sz
, struct kinfo_proc
*pp
)
549 return snprintf(buf
, sz
, "%6d", PP(pp
, pid
));
553 fmt_username(char *buf
, int sz
, struct kinfo_proc
*pp
)
556 return snprintf(buf
, sz
, "%-*.*s",
557 username_length
, username_length
, username(PRUID(pp
)));
561 fmt_uid(char *buf
, int sz
, struct kinfo_proc
*pp
)
564 return snprintf(buf
, sz
, "%6d", PRUID(pp
));
568 fmt_thr(char *buf
, int sz
, struct kinfo_proc
*pp
)
571 return snprintf(buf
, sz
, "%3d", PP(pp
, numthreads
));
575 fmt_pri(char *buf
, int sz
, struct kinfo_proc
*pp
)
579 return snprintf(buf
, sz
, "%3d", PP(pp
, priority
));
581 return snprintf(buf
, sz
, "%3d", PP(pp
, pri
.pri_level
));
586 fmt_nice(char *buf
, int sz
, struct kinfo_proc
*pp
)
589 return snprintf(buf
, sz
, "%4d", PP(pp
, nice
) - NZERO
);
593 fmt_size(char *buf
, int sz
, struct kinfo_proc
*pp
)
596 return snprintf(buf
, sz
, "%5s", format_k(PROCSIZE(pp
)));
600 fmt_res(char *buf
, int sz
, struct kinfo_proc
*pp
)
603 return snprintf(buf
, sz
, "%5s", format_k(pagetok(VP(pp
, rssize
))));
607 fmt_state(char *buf
, int sz
, struct kinfo_proc
*pp
)
613 state
= PP(pp
, stat
);
617 if (smpmode
&& PP(pp
, oncpu
) != 0xff)
618 sprintf(status
, "CPU%d", PP(pp
, oncpu
));
620 strcpy(status
, "RUN");
624 if (EP(pp
, wmesg
) != NULL
) {
625 sprintf(status
, "%.6s", EP(pp
, wmesg
));
630 if (state
>= 0 && state
< NUM_STATES
)
631 sprintf(status
, "%.6s", state_abbrev
[(unsigned char) state
]);
633 sprintf(status
, "?%-5d", state
);
637 return snprintf(buf
, sz
, "%-6.6s", status
);
641 fmt_flags(char *buf
, int sz
, struct kinfo_proc
*pp
)
650 if (PP(pp
, nice
) < NZERO
)
652 else if (PP(pp
, nice
) > NZERO
)
656 if (flag
& P_WEXIT
&& PP(pp
, stat
) != SZOMB
)
660 if (flag
& P_SYSTEM
|| PP(pp
, lock
) > 0)
662 if (PP(pp
, kiflag
) & KI_SLEADER
)
664 if (flag
& P_CONTROLT
)
670 return snprintf(buf
, sz
, "%-3.3s", chrs
);
674 fmt_c(char *buf
, int sz
, struct kinfo_proc
*pp
)
677 return snprintf(buf
, sz
, "%1x", PP(pp
, lastcpu
));
681 fmt_time(char *buf
, int sz
, struct kinfo_proc
*pp
)
684 return snprintf(buf
, sz
, "%6s",
685 format_time((PP(pp
, runtime
) + 500000) / 1000000));
689 fmt_cpu(char *buf
, int sz
, struct kinfo_proc
*pp
)
692 return snprintf(buf
, sz
, "%5.2f%%", (double)PPCPU(pp
) / 100.0);
696 fmt_command(char *buf
, int sz
, struct kinfo_proc
*pp
)
706 inmem
= (PP(pp
, flag
) & P_INMEM
);
708 inmem
= (PP(pp
, sflag
) & PS_INMEM
);
711 if (show_fullcmd
&& inmem
)
713 /* get the pargs structure */
714 if (getkval((unsigned long)PP(pp
, args
), (int *)&pargs
, sizeof(pargs
)) != -1)
716 /* determine workable length */
717 if ((len
= pargs
.ar_length
) >= MAX_COLS
)
722 /* get the string from that */
723 if (len
> 0 && getkval((unsigned long)PP(pp
, args
) +
724 sizeof(pargs
.ar_ref
) +
725 sizeof(pargs
.ar_length
),
726 (int *)cmd
, len
) != -1)
728 /* successfull retrieval: now convert nulls in to spaces */
739 /* null terminate cmd */
742 /* format cmd as our answer */
743 return snprintf(buf
, sz
, "%s", cmd
);
748 /* for anything else we just display comm */
749 return snprintf(buf
, sz
, inmem
? "%s" : "<%s>", printable(PP(pp
, comm
)));
753 fmt_vcsw(char *buf
, int sz
, struct kinfo_proc
*pp
)
756 return snprintf(buf
, sz
, "%6ld", per_second(SP(pp
, vcsw
), elapsed_msecs
));
760 fmt_ivcsw(char *buf
, int sz
, struct kinfo_proc
*pp
)
763 return snprintf(buf
, sz
, "%6ld", per_second(SP(pp
, ivcsw
), elapsed_msecs
));
767 fmt_read(char *buf
, int sz
, struct kinfo_proc
*pp
)
770 return snprintf(buf
, sz
, "%6ld", per_second(SP(pp
, inblock
), elapsed_msecs
));
774 fmt_write(char *buf
, int sz
, struct kinfo_proc
*pp
)
777 return snprintf(buf
, sz
, "%6ld", per_second(SP(pp
, oublock
), elapsed_msecs
));
781 fmt_fault(char *buf
, int sz
, struct kinfo_proc
*pp
)
784 return snprintf(buf
, sz
, "%6ld", per_second(SP(pp
, majflt
), elapsed_msecs
));
788 fmt_iototal(char *buf
, int sz
, struct kinfo_proc
*pp
)
791 return snprintf(buf
, sz
, "%6ld", per_second(SP(pp
, totalio
), elapsed_msecs
));
795 fmt_iopct(char *buf
, int sz
, struct kinfo_proc
*pp
)
798 return snprintf(buf
, sz
, "%6.2f", (SP(pp
, totalio
) * 100.) / total_io
);
802 struct proc_field proc_field
[] = {
803 { "PID", 6, 1, 0, fmt_pid
},
804 { "USERNAME", 8, 0, 0, fmt_username
},
805 #define FIELD_USERNAME 1
806 { "UID", 6, 1, 0, fmt_uid
},
808 { "THR", 3, 1, 0, fmt_thr
},
809 { "PRI", 3, 1, 0, fmt_pri
},
810 { "NICE", 4, 1, 0, fmt_nice
},
811 { "SIZE", 5, 1, 0, fmt_size
},
812 { "RES", 5, 1, 0, fmt_res
},
813 { "STATE", 6, 0, 0, fmt_state
},
814 { "FLG", 3, 0, 84, fmt_flags
},
815 { "C", 1, 0, 0, fmt_c
},
816 { "TIME", 6, 1, 0, fmt_time
},
817 { "CPU", 6, 1, 0, fmt_cpu
},
818 { "COMMAND", 7, 0, 0, fmt_command
},
819 { "VCSW", 6, 1, 0, fmt_vcsw
},
820 { "IVCSW", 6, 1, 0, fmt_ivcsw
},
821 { "READ", 6, 1, 0, fmt_read
},
822 { "WRITE", 6, 1, 0, fmt_write
},
823 { "FAULT", 6, 1, 0, fmt_fault
},
824 { "TOTAL", 6, 1, 0, fmt_iototal
},
825 { "PERCENT", 7, 1, 0, fmt_iopct
},
826 { NULL
, 0, 0, 0, NULL
}
828 #define MAX_FIELDS 24
830 static int mode0_display
[MAX_FIELDS
];
831 static int mode0thr_display
[MAX_FIELDS
];
832 static int mode1_display
[MAX_FIELDS
];
835 field_index(char *col
)
838 struct proc_field
*fp
;
842 while (fp
->name
!= NULL
)
844 if (strcmp(col
, fp
->name
) == 0)
856 field_subst(int *fp
, int old
, int new)
870 machine_init(struct statics
*statics
)
877 struct timeval boottime
;
879 len
= sizeof(smpmode
);
880 if ((sysctlbyname("machdep.smp_active", &smpmode
, &len
, NULL
, 0) < 0 &&
881 sysctlbyname("smp.smp_active", &smpmode
, &len
, NULL
, 0) < 0) ||
882 len
!= sizeof(smpmode
))
886 smpmode
= smpmode
!= 0;
888 /* kvm_open the active kernel: its okay if this fails */
889 kd
= kvm_open(NULL
, NULL
, NULL
, O_RDONLY
, NULL
);
892 len
= sizeof(boottime
);
893 if (sysctlbyname("kern.boottime", &boottime
, &len
, NULL
, 0) == -1)
895 /* we have no boottime to report */
896 boottime
.tv_sec
= -1;
902 /* get the page size with "getpagesize" and calculate pageshift from it */
903 i
= pagesize
= getpagesize();
911 /* translate sysctl paths to mibs for faster access */
914 /* initialize swap stuff */
917 /* create the hash table that remembers proc data */
918 procs
= hash_create(2039);
920 /* we only need the amount of log(2)1024 for our conversion */
921 pageshift
-= LOG1024
;
923 /* fill in the statics information */
924 statics
->procstate_names
= procstatenames
;
925 statics
->cpustate_names
= cpustatenames
;
926 statics
->memory_names
= memorynames
;
927 statics
->kernel_names
= kernelnames
;
928 statics
->boottime
= boottime
.tv_sec
;
929 statics
->swap_names
= swapnames
;
930 statics
->order_names
= ordernames
;
931 statics
->flags
.warmup
= 1;
932 statics
->modemax
= 2;
933 #ifdef HAS_SHOWTHREADS
934 statics
->flags
.threads
= 1;
937 /* we need kvm descriptor in order to show full commands */
938 statics
->flags
.fullcmds
= kd
!= NULL
;
940 /* set up the display indices for mode0 */
942 *ip
++ = field_index("PID");
943 *ip
++ = field_index("USERNAME");
945 *ip
++ = field_index("THR");
947 *ip
++ = field_index("PRI");
948 *ip
++ = field_index("NICE");
949 *ip
++ = field_index("SIZE");
950 *ip
++ = field_index("RES");
951 *ip
++ = field_index("STATE");
952 *ip
++ = field_index("FLG");
954 *ip
++ = field_index("C");
955 *ip
++ = field_index("TIME");
956 *ip
++ = field_index("CPU");
957 *ip
++ = field_index("COMMAND");
960 #ifdef HAS_SHOWTHREADS
961 /* set up the display indices for mode0 showing threads */
962 ip
= mode0thr_display
;
963 *ip
++ = field_index("PID");
964 *ip
++ = field_index("USERNAME");
965 *ip
++ = field_index("PRI");
966 *ip
++ = field_index("NICE");
967 *ip
++ = field_index("SIZE");
968 *ip
++ = field_index("RES");
969 *ip
++ = field_index("STATE");
970 *ip
++ = field_index("FLG");
972 *ip
++ = field_index("C");
973 *ip
++ = field_index("TIME");
974 *ip
++ = field_index("CPU");
975 *ip
++ = field_index("COMMAND");
979 /* set up the display indices for mode1 */
981 *ip
++ = field_index("PID");
982 *ip
++ = field_index("USERNAME");
983 *ip
++ = field_index("VCSW");
984 *ip
++ = field_index("IVCSW");
985 *ip
++ = field_index("READ");
986 *ip
++ = field_index("WRITE");
987 *ip
++ = field_index("FAULT");
988 *ip
++ = field_index("TOTAL");
989 *ip
++ = field_index("PERCENT");
990 *ip
++ = field_index("COMMAND");
997 char *format_header(char *uname_field
)
1004 get_vm_sum(struct vmmeter
*sum
)
1007 #define GET_VM_STAT(v, s) (void)get_sysctl(v, &(sum->s), sizeof(sum->s))
1009 GET_VM_STAT(V_SWTCH
, v_swtch
);
1010 GET_VM_STAT(V_TRAP
, v_trap
);
1011 GET_VM_STAT(V_INTR
, v_intr
);
1012 GET_VM_STAT(V_SOFT
, v_soft
);
1013 GET_VM_STAT(V_VFORKS
, v_vforks
);
1014 GET_VM_STAT(V_FORKS
, v_forks
);
1015 GET_VM_STAT(V_RFORKS
, v_rforks
);
1016 GET_VM_STAT(V_VM_FAULTS
, v_vm_faults
);
1017 GET_VM_STAT(V_SWAPIN
, v_swapin
);
1018 GET_VM_STAT(V_SWAPOUT
, v_swapout
);
1019 GET_VM_STAT(V_TFREE
, v_tfree
);
1020 GET_VM_STAT(V_VNODEIN
, v_vnodein
);
1021 GET_VM_STAT(V_VNODEOUT
, v_vnodeout
);
1022 GET_VM_STAT(V_ACTIVE_COUNT
, v_active_count
);
1023 GET_VM_STAT(V_INACTIVE_COUNT
, v_inactive_count
);
1024 GET_VM_STAT(V_WIRE_COUNT
, v_wire_count
);
1025 GET_VM_STAT(V_CACHE_COUNT
, v_cache_count
);
1026 GET_VM_STAT(V_FREE_COUNT
, v_free_count
);
1027 GET_VM_STAT(V_SWAPPGSIN
, v_swappgsin
);
1028 GET_VM_STAT(V_SWAPPGSOUT
, v_swappgsout
);
1032 get_system_info(struct system_info
*si
)
1036 struct timeval thistime
;
1037 struct timeval timediff
;
1039 /* timestamp and time difference */
1040 gettimeofday(&thistime
, 0);
1041 timersub(&thistime
, &lasttime
, &timediff
);
1042 elapsed_time
= timediff
.tv_sec
* 1000000 + timediff
.tv_usec
;
1043 elapsed_msecs
= timediff
.tv_sec
* 1000 + timediff
.tv_usec
/ 1000;
1045 /* get the load averages */
1046 if (getloadavg(si
->load_avg
, NUM_AVERAGES
) == -1)
1048 /* failed: fill in with zeroes */
1049 (void) memset(si
->load_avg
, 0, sizeof(si
->load_avg
));
1052 /* get the cp_time array */
1053 (void)get_sysctl(K_CP_TIME
, &cp_time
, sizeof(cp_time
));
1055 /* convert cp_time counts to percentages */
1056 total
= percentages(CPUSTATES
, cpu_states
, cp_time
, cp_old
, cp_diff
);
1058 /* sum memory & swap statistics */
1061 static unsigned int swap_delay
= 0;
1062 static long long swapavail
= 0;
1063 static long long swapfree
= 0;
1064 static int bufspace
= 0;
1070 (void) get_sysctl(VFS_BUFSPACE
, &bufspace
, sizeof(bufspace
));
1073 dprintf("kernel: swtch %d, trap %d, intr %d, soft %d, vforks %d\n",
1074 sum
.v_swtch
, sum
.v_trap
, sum
.v_intr
, sum
.v_soft
, sum
.v_vforks
);
1075 kernel_stats
[0] = per_second(sum
.v_swtch
- ctxsws
, elapsed_msecs
);
1076 kernel_stats
[1] = per_second(sum
.v_trap
- traps
, elapsed_msecs
);
1077 kernel_stats
[2] = per_second(sum
.v_intr
- intrs
, elapsed_msecs
);
1078 kernel_stats
[3] = per_second(sum
.v_soft
- softs
, elapsed_msecs
);
1079 kernel_stats
[4] = per_second(sum
.v_vforks
+ sum
.v_forks
+
1080 sum
.v_rforks
- forks
, elapsed_msecs
);
1081 kernel_stats
[5] = per_second(sum
.v_vm_faults
- pfaults
, elapsed_msecs
);
1082 kernel_stats
[6] = per_second(sum
.v_swapin
+ sum
.v_vnodein
- pagein
, elapsed_msecs
);
1083 kernel_stats
[7] = per_second(sum
.v_swapout
+ sum
.v_vnodeout
- pageout
, elapsed_msecs
);
1084 kernel_stats
[8] = per_second(sum
.v_tfree
- tfreed
, elapsed_msecs
);
1085 ctxsws
= sum
.v_swtch
;
1089 forks
= (u_int64_t
)sum
.v_vforks
+ sum
.v_forks
+ sum
.v_rforks
;
1090 pfaults
= sum
.v_vm_faults
;
1091 pagein
= sum
.v_swapin
+ sum
.v_vnodein
;
1092 pageout
= sum
.v_swapout
+ sum
.v_vnodeout
;
1093 tfreed
= sum
.v_tfree
;
1095 /* convert memory stats to Kbytes */
1096 memory_stats
[0] = pagetok(sum
.v_active_count
);
1097 memory_stats
[1] = pagetok(sum
.v_inactive_count
);
1098 memory_stats
[2] = pagetok(sum
.v_wire_count
);
1099 memory_stats
[3] = pagetok(sum
.v_cache_count
);
1100 memory_stats
[4] = bufspace
/ 1024;
1101 memory_stats
[5] = pagetok(sum
.v_free_count
);
1102 memory_stats
[6] = -1;
1104 /* first interval */
1111 /* compute differences between old and new swap statistic */
1114 swap_stats
[4] = pagetok(sum
.v_swappgsin
- swappgsin
);
1115 swap_stats
[5] = pagetok(sum
.v_swappgsout
- swappgsout
);
1118 swappgsin
= sum
.v_swappgsin
;
1119 swappgsout
= sum
.v_swappgsout
;
1121 /* call CPU heavy swap_getdata() only for changes */
1122 if (swap_stats
[4] > 0 || swap_stats
[5] > 0 || swap_delay
== 0)
1124 swap_stats
[3] = swap_getdata(&swapavail
, &swapfree
);
1125 swap_stats
[0] = swapavail
;
1126 swap_stats
[1] = swapavail
- swapfree
;
1127 swap_stats
[2] = swapfree
;
1133 /* set arrays and strings */
1134 si
->cpustates
= cpu_states
;
1135 si
->kernel
= kernel_stats
;
1136 si
->memory
= memory_stats
;
1137 si
->swap
= swap_stats
;
1141 lasttime
= thistime
;
1145 get_process_info(struct system_info
*si
,
1146 struct process_select
*sel
,
1153 struct kinfo_proc
**prefp
;
1154 struct kinfo_proc
*pp
;
1155 struct kinfo_proc
*prev_pp
= NULL
;
1156 struct save_proc
*savep
;
1162 /* these are copied out of sel for speed */
1169 /* get proc table size and give it a boost */
1170 nproc
= (int)get_sysctlsize(K_PROC
) / sizeof(struct kinfo_proc
);
1171 nproc
+= nproc
>> 4;
1172 size
= nproc
* sizeof(struct kinfo_proc
);
1173 dprintf("get_process_info: nproc %d, psize %d, size %d\n", nproc
, psize
, size
);
1175 /* make sure we have enough space allocated */
1178 /* reallocate both pbase and pref */
1179 pbase
= (struct kinfo_proc
*)realloc(pbase
, size
);
1180 pref
= (struct kinfo_proc
**)realloc(pref
,
1181 sizeof(struct kinfo_proc
*) * nproc
);
1185 /* make sure we got the space we asked for */
1186 if (pref
== NULL
|| pbase
== NULL
)
1188 /* abandon all hope */
1189 message_error(" Out of memory!");
1196 /* get all process information (threads, too) */
1199 nproc
= get_sysctl(K_PROC
, pbase
, size
);
1206 nproc
/= sizeof(struct kinfo_proc
);
1210 /* get a pointer to the states summary array */
1211 si
->procstates
= process_states
;
1213 /* set up flags which define what we are going to select */
1214 show_idle
= sel
->idle
;
1216 show_system
= sel
->system
;
1217 show_uid
= sel
->uid
!= -1;
1218 show_fullcmd
= sel
->fullcmd
;
1219 show_command
= sel
->command
;
1220 show_usernames
= sel
->usernames
;
1221 display_mode
= sel
->mode
;
1222 #ifdef HAS_SHOWTHREADS
1223 show_threads
= sel
->threads
;
1226 /* count up process states and get pointers to interesting procs */
1230 memset((char *)process_states
, 0, sizeof(process_states
));
1232 for (pp
= pbase
, i
= 0; i
< nproc
; pp
++, i
++)
1235 * Place pointers to each valid proc structure in pref[].
1236 * Process slots that are actually in use have a non-zero
1237 * status field. Processes with P_SYSTEM set are system
1238 * processes---these get ignored unless show_sysprocs is set.
1241 if (PP(pp
, stat
) != 0)
1243 #ifdef HAS_SHOWTHREADS
1250 /* is this just a thread? */
1251 is_thread
= (prev_pp
!= NULL
&& PP(prev_pp
, pid
) == pid
);
1253 /* count this process and its state */
1254 /* only count threads if we are showing them */
1255 if (show_threads
|| !is_thread
)
1258 process_states
[(unsigned char) PP(pp
, stat
)]++;
1261 /* grab old data from hash */
1262 if ((savep
= hash_lookup_lwpid(procs
, tid
)) != NULL
)
1264 /* verify that this is not a new or different thread */
1265 /* (freebsd reuses thread ids fairly quickly) */
1266 /* pids must match and time can't have gone backwards */
1267 if (pid
!= savep
->sp_pid
|| PP(pp
, runtime
) < savep
->sp_runtime
)
1269 /* not the same thread -- reuse the save_proc structure */
1270 memset(savep
, 0, sizeof(struct save_proc
));
1271 savep
->sp_pid
= pid
;
1276 /* havent seen this one before */
1277 savep
= (struct save_proc
*)calloc(1, sizeof(struct save_proc
));
1278 savep
->sp_pid
= pid
;
1279 hash_add_lwpid(procs
, tid
, savep
);
1282 #else /* !HAS_SHOWTHREADS */
1284 process_states
[(unsigned char) PP(pp
, stat
)]++;
1286 /* grab old data from hash */
1287 if ((savep
= hash_lookup_pid(procs
, pid
)) == NULL
)
1289 /* havent seen this one before */
1290 savep
= (struct save_proc
*)calloc(1, sizeof(struct save_proc
));
1291 savep
->sp_pid
= pid
;
1292 hash_add_pid(procs
, pid
, savep
);
1296 /* save the pointer to the sp struct */
1297 SPPTR(pp
) = (void *)savep
;
1299 /* calculate %cpu */
1300 PPCPU(pp
) = ((PP(pp
, runtime
) - savep
->sp_runtime
) * 10000) /
1302 dprintf("%d (%d): runtime %lld, saved_pid %d, saved_runtime %lld, elapsed_time %d, ppcpu %d\n",
1303 pid
, PP(pp
, tid
), PP(pp
, runtime
), savep
->sp_pid
, savep
->sp_runtime
,
1304 elapsed_time
, PPCPU(pp
));
1306 /* calculate io differences */
1308 savep
->sp_vcsw
= (RP(pp
, nvcsw
) - savep
->sp_old_nvcsw
);
1309 savep
->sp_ivcsw
= (RP(pp
, nivcsw
) - savep
->sp_old_nivcsw
);
1310 proc_io
+= (savep
->sp_inblock
= (RP(pp
, inblock
) - savep
->sp_old_inblock
));
1311 proc_io
+= (savep
->sp_oublock
= (RP(pp
, oublock
) - savep
->sp_old_oublock
));
1312 proc_io
+= (savep
->sp_majflt
= (RP(pp
, majflt
) - savep
->sp_old_majflt
));
1313 total_io
+= proc_io
;
1314 savep
->sp_totalio
= proc_io
;
1316 /* save data for next time */
1317 savep
->sp_runtime
= PP(pp
, runtime
);
1318 savep
->sp_old_nvcsw
= RP(pp
, nvcsw
);
1319 savep
->sp_old_nivcsw
= RP(pp
, nivcsw
);
1320 savep
->sp_old_inblock
= RP(pp
, inblock
);
1321 savep
->sp_old_oublock
= RP(pp
, oublock
);
1322 savep
->sp_old_majflt
= RP(pp
, majflt
);
1324 /* is this one selected for viewing? */
1325 if ((PP(pp
, stat
) != SZOMB
) &&
1326 (show_system
|| ((PP(pp
, flag
) & P_SYSTEM
) == 0)) &&
1327 (show_idle
|| (PP(pp
, pctcpu
) != 0) ||
1328 (PP(pp
, stat
) == SRUN
)) &&
1329 (!show_uid
|| PRUID(pp
) == (uid_t
)sel
->uid
) &&
1330 (show_command
== NULL
||
1331 strcasestr(PP(pp
, comm
), show_command
) != NULL
))
1333 #ifdef HAS_SHOWTHREADS
1334 /* yes, but make sure it isn't just a thread */
1335 if (show_threads
|| !is_thread
)
1337 /* we will be showing this thread */
1343 /* we will not be showing this thread, but we need to roll
1344 up its cpu usage in to its process */
1345 PP(prev_pp
, pctcpu
) += PP(pp
, pctcpu
);
1347 #else /* !HAS_SHOWTHREADS */
1348 /* we will be showing this process */
1357 dprintf("total_io: %d\n", total_io
);
1358 if (total_io
== 0) total_io
= 1;
1360 /* if requested, sort the "interesting" processes */
1361 if (active_procs
> 1)
1363 qsort((char *)pref
, active_procs
, sizeof(struct kinfo_proc
*),
1364 proc_compares
[compare_index
]);
1367 /* remember active and total counts */
1368 si
->p_total
= total_procs
;
1369 si
->p_active
= pref_len
= active_procs
;
1371 /* pass back a handle */
1372 handle
.next_proc
= pref
;
1373 handle
.remaining
= active_procs
;
1374 return((caddr_t
)&handle
);
1377 static char p_header
[MAX_COLS
];
1380 format_process_header(struct process_select
*sel
, caddr_t handle
, int count
)
1388 struct kinfo_proc
**kip
;
1389 struct proc_field
*fp
;
1391 /* check for null handle */
1397 /* remember how many columns there are on the display */
1398 cols
= display_columns();
1400 /* mode & threads dictate format */
1401 fi
= display_fields
=
1403 (sel
->threads
== 0 ? mode0_display
: mode0thr_display
) :
1406 /* set username field correctly */
1407 if (!sel
->usernames
)
1410 field_subst(fi
, FIELD_USERNAME
, FIELD_UID
);
1414 /* display usernames */
1415 field_subst(fi
, FIELD_UID
, FIELD_USERNAME
);
1417 /* we also need to determine the longest username for column width */
1418 /* calculate namelength from first "count" processes */
1419 kip
= ((struct handle
*)handle
)->next_proc
;
1420 n
= ((struct handle
*)handle
)->remaining
;
1426 w
= strlen(username(PRUID(*kip
)));
1427 if (w
> namelength
) namelength
= w
;
1430 dprintf("format_process_header: namelength %d\n", namelength
);
1432 /* place it in bounds */
1438 /* set the column width */
1439 proc_field
[FIELD_USERNAME
].width
= username_length
= namelength
;
1442 /* walk thru fields and construct header */
1443 /* are we worried about overflow??? */
1447 fp
= &(proc_field
[*fi
++]);
1448 if (fp
->min_screenwidth
<= cols
)
1450 p
+= sprintf(p
, fp
->rjust
? "%*s" : "%-*s", fp
->width
, fp
->name
);
1459 static char fmt
[MAX_COLS
]; /* static area where result is built */
1462 format_next_process(caddr_t handle
, char *(*get_userid
)(int))
1465 struct kinfo_proc
*pp
;
1467 struct proc_field
*fp
;
1475 /* find and remember the next proc structure */
1476 hp
= (struct handle
*)handle
;
1477 pp
= *(hp
->next_proc
++);
1480 /* mode & threads dictate format */
1481 fi
= display_fields
;
1483 /* screen width is a consideration, too */
1484 cols
= display_columns();
1486 /* build output by field */
1489 while ((i
= *fi
++) != -1)
1491 fp
= &(proc_field
[i
]);
1492 if (len
> 0 && fp
->min_screenwidth
<= cols
)
1494 x
= (*(fp
->format
))(p
, len
, pp
);
1497 dprintf("format_next_process: formatter overflow: x %d, len %d, p %08x => %08x, fmt %08x - %08x\n",
1498 x
, len
, p
, p
+ len
, fmt
, fmt
+ sizeof(fmt
));
1512 /* return the result */
1516 /* comparison routines for qsort */
1519 * proc_compare - comparison function for "qsort"
1520 * Compares the resource consumption of two processes using five
1521 * distinct keys. The keys (in descending order of importance) are:
1522 * percent cpu, cpu ticks, state, resident set size, total virtual
1523 * memory usage. The process states are ordered as follows (from least
1524 * to most important): WAIT, zombie, sleep, stop, start, run. The
1525 * array declaration below maps a process state index into a number
1526 * that reflects this ordering.
1529 static unsigned char sorted_state
[] =
1533 1, /* ABANDONED (WAIT) */
1541 #define ORDERKEY_PCTCPU \
1542 if (lresult = (long) PPCPU(p2) - (long) PPCPU(p1), \
1543 (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)
1545 #define ORDERKEY_CPTICKS \
1546 if ((result = PP(p2, runtime) > PP(p1, runtime) ? 1 : \
1547 PP(p2, runtime) < PP(p1, runtime) ? -1 : 0) == 0)
1549 #define ORDERKEY_STATE \
1550 if ((result = sorted_state[(unsigned char) PP(p2, stat)] - \
1551 sorted_state[(unsigned char) PP(p1, stat)]) == 0)
1554 #define ORDERKEY_PRIO \
1555 if ((result = PP(p2, priority) - PP(p1, priority)) == 0)
1557 #define ORDERKEY_PRIO \
1558 if ((result = PP(p2, pri.pri_level) - PP(p1, pri.pri_level)) == 0)
1561 #define ORDERKEY_RSSIZE \
1562 if ((result = VP(p2, rssize) - VP(p1, rssize)) == 0)
1564 #define ORDERKEY_MEM \
1565 if ( (result = PROCSIZE(p2) - PROCSIZE(p1)) == 0 )
1567 #define ORDERKEY_IO \
1568 if ( (result = SP(p2, totalio) - SP(p1, totalio)) == 0)
1570 #define ORDERKEY_PID \
1571 if ( (result = PP(p1, pid) - PP(p2, pid)) == 0)
1573 /* compare_cpu - the comparison function for sorting by cpu percentage */
1576 proc_compare(struct proc
**pp1
, struct proc
**pp2
)
1579 struct kinfo_proc
*p1
;
1580 struct kinfo_proc
*p2
;
1584 /* remove one level of indirection */
1585 p1
= *(struct kinfo_proc
**) pp1
;
1586 p2
= *(struct kinfo_proc
**) pp2
;
1599 /* compare_size - the comparison function for sorting by total memory usage */
1602 compare_size(struct proc
**pp1
, struct proc
**pp2
)
1605 struct kinfo_proc
*p1
;
1606 struct kinfo_proc
*p2
;
1610 /* remove one level of indirection */
1611 p1
= *(struct kinfo_proc
**) pp1
;
1612 p2
= *(struct kinfo_proc
**) pp2
;
1625 /* compare_res - the comparison function for sorting by resident set size */
1628 compare_res(struct proc
**pp1
, struct proc
**pp2
)
1631 struct kinfo_proc
*p1
;
1632 struct kinfo_proc
*p2
;
1636 /* remove one level of indirection */
1637 p1
= *(struct kinfo_proc
**) pp1
;
1638 p2
= *(struct kinfo_proc
**) pp2
;
1651 /* compare_time - the comparison function for sorting by total cpu time */
1654 compare_time(struct proc
**pp1
, struct proc
**pp2
)
1657 struct kinfo_proc
*p1
;
1658 struct kinfo_proc
*p2
;
1662 /* remove one level of indirection */
1663 p1
= *(struct kinfo_proc
**) pp1
;
1664 p2
= *(struct kinfo_proc
**) pp2
;
1677 /* compare_prio - the comparison function for sorting by priority */
1680 compare_prio(struct proc
**pp1
, struct proc
**pp2
)
1683 struct kinfo_proc
*p1
;
1684 struct kinfo_proc
*p2
;
1688 /* remove one level of indirection */
1689 p1
= *(struct kinfo_proc
**) pp1
;
1690 p2
= *(struct kinfo_proc
**) pp2
;
1703 /* compare_io - the comparison function for sorting by io count */
1706 compare_io(struct proc
**pp1
, struct proc
**pp2
)
1709 struct kinfo_proc
*p1
;
1710 struct kinfo_proc
*p2
;
1714 /* remove one level of indirection */
1715 p1
= *(struct kinfo_proc
**) pp1
;
1716 p2
= *(struct kinfo_proc
**) pp2
;
1730 /* compare_pid - the comparison function for sorting by process id */
1733 compare_pid(struct proc
**pp1
, struct proc
**pp2
)
1736 struct kinfo_proc
*p1
;
1737 struct kinfo_proc
*p2
;
1740 /* remove one level of indirection */
1741 p1
= *(struct kinfo_proc
**) pp1
;
1742 p2
= *(struct kinfo_proc
**) pp2
;
1751 * proc_owner(pid) - returns the uid that owns process "pid", or -1 if
1752 * the process does not exist.
1753 * It is EXTREMLY IMPORTANT that this function work correctly.
1754 * If top runs setuid root (as in SVR4), then this function
1755 * is the only thing that stands in the way of a serious
1756 * security problem. It validates requests for the "kill"
1757 * and "renice" commands.
1765 struct kinfo_proc
**prefp
;
1766 struct kinfo_proc
*pp
;
1773 if (PP(pp
, pid
) == (pid_t
)pid
)
1775 return((int)PRUID(pp
));