From owner-freebsd-current@FreeBSD.ORG Wed Apr 13 13:26:08 2005 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6B6B816A4CE; Wed, 13 Apr 2005 13:26:08 +0000 (GMT) Received: from kane.otenet.gr (kane.otenet.gr [195.170.0.27]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3BBCF43D2F; Wed, 13 Apr 2005 13:26:07 +0000 (GMT) (envelope-from keramida@freebsd.org) Received: from orion.daedalusnetworks.priv (aris.bedc.ondsl.gr [62.103.39.226])j3DDP38B024465; Wed, 13 Apr 2005 16:25:03 +0300 Received: from orion.daedalusnetworks.priv (orion [127.0.0.1]) j3DDQ4Cl039104; Wed, 13 Apr 2005 16:26:04 +0300 (EEST) (envelope-from keramida@freebsd.org) Received: (from keramida@localhost)j3DDQ4Z6039103; Wed, 13 Apr 2005 16:26:04 +0300 (EEST) (envelope-from keramida@freebsd.org) Date: Wed, 13 Apr 2005 16:26:04 +0300 From: Giorgos Keramidas To: Jiawei Ye Message-ID: <20050413132603.GA39006@orion.daedalusnetworks.priv> References: <425CC7F8.3030803@samsco.org> <425CD009.6040208@freebsd.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: cc: freebsd-current@freebsd.org cc: David Xu Subject: Re: How does one know how many thread a process owns? X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Apr 2005 13:26:08 -0000 On 2005-04-13 17:15, Jiawei Ye wrote: > On 4/13/05, David Xu wrote: > > I believe he wants to see total threads number in a process. add a column > > to top to display total kernel threads in per-process, p_numthreads in proc > > structure is what you need . :) > > > > David Xu > > Exactly what I want. Is is possible to modify our top? Can you try the following patch? I've added a THR column when top displays only one line per process. So when the "display each thread separately" mode is off, you should see something like this: % last pid: 39064; load averages: 0.08, 0.05, 0.32 up 0+02:00:58 16:22:00 % 69 processes: 1 running, 65 sleeping, 3 stopped % CPU states: % user, % nice, % system, % interrupt, % idle % Mem: 117M Active, 211M Inact, 77M Wired, 14M Cache, 54M Buf, 11M Free % Swap: 1535M Total, 4K Used, 1535M Free % % PID USERNAME THR PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND % 662 keramida 1 96 0 84584K 29864K select 1:08 0.00% 0.00% Xorg % 16554 keramida 4 20 0 50136K 38240K kserel 0:40 0.00% 0.00% mozilla-bin % 700 keramida 1 96 0 6012K 4440K select 0:25 0.00% 0.00% xterm-static % 711 root 1 96 0 3368K 2864K select 0:13 0.00% 0.00% screen % 718 keramida 1 96 0 5348K 3772K select 0:10 0.00% 0.00% xterm-static % 691 keramida 1 96 0 6896K 4920K select 0:09 0.00% 0.00% wmaker The sprintf() calls near the end of format_next_process() are duplicated, which is ugly as hell, but I couldn't find a good way to avoid the code duplication. If people don't have a problem with constantly displaying this column, even when no threads are used, this will be even easier to do without the extra clutter. Then, we can add a sort function to order by number of threads and then I think we're pretty much done :-) %%% Index: contrib/top/top.c =================================================================== RCS file: /home/ncvs/src/contrib/top/top.c,v retrieving revision 1.15 diff -u -r1.15 top.c --- contrib/top/top.c 16 Aug 2004 07:51:21 -0000 1.15 +++ contrib/top/top.c 13 Apr 2005 12:56:10 -0000 @@ -84,6 +84,7 @@ static int max_topn; /* maximum displayable processes */ /* miscellaneous things */ +struct process_select ps; char *myname = "top"; jmp_buf jmp_int; @@ -179,7 +180,6 @@ char *iptr; char no_command = 1; struct timeval timeout; - struct process_select ps; #ifdef ORDER char *order_name = NULL; int order_index = 0; @@ -987,8 +987,10 @@ case CMD_thrtog: ps.thread = !ps.thread; new_message(MT_standout | MT_delayed, - " %sisplaying threads.", - ps.thread ? "D" : "Not d"); + "Displaying threads %s", + ps.thread ? "separately" : "as a count"); + header_text = format_header(uname_field); + reset_display(); putchar('\r'); break; case CMD_viewtog: Index: usr.bin/top/machine.c =================================================================== RCS file: /home/ncvs/src/usr.bin/top/machine.c,v retrieving revision 1.69 diff -u -r1.69 machine.c --- usr.bin/top/machine.c 4 Apr 2005 21:19:48 -0000 1.69 +++ usr.bin/top/machine.c 13 Apr 2005 13:18:45 -0000 @@ -55,6 +55,7 @@ #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var)) +extern struct process_select ps; extern char* printable(char *); int swapmode(int *retavail, int *retfree); static int smpmode; @@ -101,18 +102,25 @@ #define io_Proc_format \ "%5d %-*.*s %6ld %6ld %6ld %6ld %6ld %6ld %6.2f%% %.*s" +static char smp_header_thr[] = + " PID %-*.*s THR PRI NICE SIZE RES STATE C TIME WCPU CPU COMMAND"; static char smp_header[] = - " PID %-*.*s PRI NICE SIZE RES STATE C TIME WCPU CPU COMMAND"; + " PID %-*.*s " "PRI NICE SIZE RES STATE C TIME WCPU CPU COMMAND"; +#define smp_Proc_format_thr \ + "%5d %-*.*s %3d %3d %4d%7s %6s %-6.6s %1x%7s %5.2f%% %5.2f%% %.*s" #define smp_Proc_format \ - "%5d %-*.*s %3d %4d%7s %6s %-6.6s %1x%7s %5.2f%% %5.2f%% %.*s" + "%5d %-*.*s %s%3d %4d%7s %6s %-6.6s %1x%7s %5.2f%% %5.2f%% %.*s" +static char up_header_thr[] = + " PID %-*.*s THR PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; static char up_header[] = - " PID %-*.*s PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; + " PID %-*.*s " "PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; +#define up_Proc_format_thr \ + "%5d %-*.*s %3d %3d %4d%7s %6s %-6.6s%.0d%7s %5.2f%% %5.2f%% %.*s" #define up_Proc_format \ - "%5d %-*.*s %3d %4d%7s %6s %-6.6s%.0d%7s %5.2f%% %5.2f%% %.*s" - + "%5d %-*.*s %s%3d %4d%7s %6s %-6.6s%.0d%7s %5.2f%% %5.2f%% %.*s" /* process state names for the "STATE" column of the display */ @@ -286,7 +294,15 @@ switch (displaymode) { case DISP_CPU: - prehead = smpmode ? smp_header : up_header; + /* + * The logic of picking the right header format seems reverse + * here because we only want to display a THR column when + * "thread mode" is off (and threads are not listed as + * separate lines). + */ + prehead = smpmode ? + (ps.thread ? smp_header : smp_header_thr) : + (ps.thread ? up_header : up_header_thr); break; case DISP_IO: prehead = io_header; @@ -646,6 +662,7 @@ int state; struct rusage ru, *rup; long p_tot, s_tot; + char *proc_fmt; /* find and remember the next proc structure */ hp = (struct handle *)handle; @@ -737,12 +754,48 @@ printable(pp->ki_comm)); return (fmt); } + /* format this entry */ - sprintf(fmt, - smpmode ? smp_Proc_format : up_Proc_format, + proc_fmt = smpmode ? + (ps.thread ? smp_Proc_format : smp_Proc_format_thr) : + (ps.thread ? up_Proc_format : up_Proc_format_thr); + + if (ps.thread) { + sprintf(fmt, proc_fmt, + pp->ki_pid, + namelength, namelength, + (*get_userid)(pp->ki_ruid), + "", + pp->ki_pri.pri_level - PZERO, + + /* + * normal time -> nice value -20 - +20 + * real time 0 - 31 -> nice value -52 - -21 + * idle time 0 - 31 -> nice value +21 - +52 + */ + (pp->ki_pri.pri_class == PRI_TIMESHARE ? + pp->ki_nice - NZERO : + (PRI_IS_REALTIME(pp->ki_pri.pri_class) ? + (PRIO_MIN - 1 - (PRI_MAX_REALTIME - pp->ki_pri.pri_level)) : + (PRIO_MAX + 1 + pp->ki_pri.pri_level - PRI_MIN_IDLE))), + format_k2(PROCSIZE(pp)), + format_k2(pagetok(pp->ki_rssize)), + status, + smpmode ? pp->ki_lastcpu : 0, + format_time(cputime), + 100.0 * weighted_cpu(pct, pp), + 100.0 * pct, + screen_width > cmdlengthdelta ? + screen_width - cmdlengthdelta : + 0, + printable(pp->ki_comm)); + return (fmt); + } + sprintf(fmt, proc_fmt, pp->ki_pid, namelength, namelength, (*get_userid)(pp->ki_ruid), + pp->ki_numthreads, pp->ki_pri.pri_level - PZERO, /* %%%