From 9bbaa0b3d21a5472536849fa073d98ca577fc6fa Mon Sep 17 00:00:00 2001 From: Craig Small Date: Thu, 14 Apr 2011 07:08:14 +1000 Subject: [PATCH] several bug fixes, enhancements and formatting The documentation portion of the patch addresses the following: README.top . corrected a minor typo . updated to reflect current patch level top.1 . fixed potentially misinterpreted Me/ME strings . added '.Bd -literal' directives for indented fixed-width font . some comments changed from \# to .\" to avoid man2html problems The source portion of the patch addresses the following: Buglets . header/task output length now consistent . fixed 2 obscure horizontal scrolling bugs . fixed potential bug regarding 'help' and 'current' window . messages and prompts are now also sensitive to terminal width . normalized buffer names/sizes now accommodate any SCREENMAX changes Features . made %CPU and 'i' mode handling more efficient . for input the Up/Dn arrows keys act as alternatives to Ins/Del keys . an optional USE_X_COLHDR define eliminates ALL 'x' toggle overhead . an optional ZAP_SUSEONLY define was added for Werner's modifications Cosmetic . defines and format for optional end-of-job reports standardized --- README.top | 36 +++++- top.1 | 209 +++++++++++++++++++--------------- top.c | 325 ++++++++++++++++++++++++++++++++++------------------- top.h | 91 ++++++++++----- 4 files changed, 419 insertions(+), 242 deletions(-) diff --git a/README.top b/README.top index 871bf98b..b6c9142a 100644 --- a/README.top +++ b/README.top @@ -1,3 +1,6 @@ +This file summarizes changes to the top program and supporting documentation +introduced on March 31, 2011. + Contents: DOCUMENT Changes INTERNAL Improvements @@ -15,7 +18,8 @@ DOCUMENT Changes ========================================================= - a new section "2. SUMMARY Display" added for symmetry with Fields - nine new fields were added to section "3a. DESCRIPTIONS of Fields" - a new section "3b. MANAGING Fields" replaced the obsolete section - "2b. SELECTING and ORDERING Columns" section + "2b. SELECTING and ORDERING Columns" + - section "5c. SCROLLING a Window" was added for that new feature . I don't know when the explanations for CODE and DATA were changed to show 'virtual' memory, but I think there's a reason their alternate @@ -25,9 +29,16 @@ DOCUMENT Changes ========================================================= . And as I indicated in a previous email, the former string identifier 'ME' was restored as were the 'h' key/command conventions (vs. ). + Oops, the 'h' key/command conventions remain restored, but subsequent + testing revealed problems with the .ME string identifier. Thus, it was + changed to .WE (along with the companion .Me/.We id). + . Also previously mentioned, the 'man2html' program translates top.1 to - html with perfect fidelity. I take that to mean there should be no - problems with the top.1 source on most other platforms. + HTML with near perfect fidelity. I take that to mean there should be + no problems with the top.1 source on most other platforms. + + To further improve translation to HTML, several .Bd and .Ed macros + were added to preserve literal (fixed width) spacing. INTERNAL Improvements ==================================================== @@ -41,11 +52,18 @@ INTERNAL Improvements ==================================================== . The column highlighting costs for sort field visibility were virtually eliminated. + An optional define (USE_X_COLHDR) can be enabled to completely + eliminate any costs associated with the 'x' command toggle. + . The management of the HST_t structures, used for %cpu calculations, was optimized with a hashing scheme. Thus the need for a qsort then a binary search in each frame was completely eliminated. - . This far more capable new-top executable is 33% smaller. + An optional define can restore the former qsort/bsearch approach but + with an internal inlined binary search function offering substantially + better performance than the old top. + + . This far more capable new-top executable is no larger than old top. . The above combine to produce substantially improved performance whose details are documented below under BENCHMARKS. @@ -58,7 +76,7 @@ EXTERNAL Improvements ==================================================== This function is dependent on cursor motion keys and should a device not have the customary arrow keys, alternatives are provided and - documented under section '3b. MANAGING Fields'. + documented under "Operation" near the beginning of the man page. . The following new fields have been added: Group Id @@ -71,6 +89,14 @@ EXTERNAL Improvements ==================================================== Session Id Tty Process Group Id + . Scrolling keys now allow one to move the view of any window vertically + or horizontally to reveal any desired task or column. Previously, only + some tasks were viewable even with reversible, selectable sort columns. + + Each of the four windows is capable of maintaining its own scrolled + coordinates and an optional toggle ('C') displays a message aiding + navigation within the available tasks and displayable fields. + . User interactive line oriented input now provides for true line editing supported by these new keys: Left/Right arrow keys, Delete key, Backspace and diff --git a/top.1 b/top.1 index 771a680f..91c0623b 100644 --- a/top.1 +++ b/top.1 @@ -30,19 +30,19 @@ \# ** we use single quote char (') alot, so change the no-break ctrl char .c2 ` . -\# Our own Bullet style(s) ------------------------------ +\# Our own Bullet style(s) -------------------------- .de jBu .IP "o" 3 .. . -\# Commonly used strings (for consistency) --------------- -\# - our em-dashes +\# Commonly used strings (for consistency) ---------- +\# - our em-dashes .ds Em \fR\ \--\ \fR .ds EM \fB\ \--\ \fR -\# - these 2 are for chuckles, makes great grammar -.ds Me top -.ds ME \fBtop\fR -\# - other misc strs for consistent usage/emphasis +\# - our program name (makes great grammer) +.ds We top +.ds WE \fBtop\fR +\# - other misc strs for consistent usage .ds F \fIOff\fR .ds O \fIOn\fR . @@ -70,36 +70,36 @@ .ds TD task display .ds TT \fBtasks\fR or\fB threads\fR .ds TW task window -\# Reference to the various widths/sizes ------------- -\# the max screen width limit +\# Reference to the various widths/sizes ------------ +\# - the max screen width limit .ds WX 512 -\# the header width w/ all fields +\# - the header width w/ all fields .ds WF approximately 200 -\# max room for the command column +\# - max room for the command column .ds WC 300+ -\# pid monitoring limit +\# - pid monitoring limit .ds WP 20 -\# Xref's that depend on/mention other stuff --------- +\# Xref's that depend on/mention other stuff -------- .ds Xa see .ds XC See the .ds Xc see the .ds XT See topic .ds Xt see topic . -\# Document ///////////////////////////////////////////////////////////// +.\" Document ///////////////////////////////////////////////////////////// .\" ---------------------------------------------------------------------- -.TH TOP 1 "February 2011" "Linux" "Linux User's Manual" +.TH TOP 1 "April 2011" "Linux" "Linux User's Manual" .\" ---------------------------------------------------------------------- .\" ---------------------------------------------------------------------- .SH NAME .\" ---------------------------------------------------------------------- -top \- display Linux processes +\*(We \- display Linux processes .\" ---------------------------------------------------------------------- .SH SYNOPSIS .\" ---------------------------------------------------------------------- -\*(ME \-\fBhv\fR | \-\fBbcHisS\fR \-\fBd\fI delay\fR \-\fBn\fI limit\fR +\*(WE \-\fBhv\fR | \-\fBbcHisS\fR \-\fBd\fI delay\fR \-\fBn\fI limit\fR \-\fBu\fR|\fBU\fI user\fR | \-\fBp\fI pid\fR [,\fIpid\fR ...] The traditional switches '-' and whitespace are optional. @@ -108,7 +108,7 @@ The traditional switches '-' and whitespace are optional. .\" ---------------------------------------------------------------------- .SH DESCRIPTION .\" ---------------------------------------------------------------------- -The \*(ME program provides a dynamic real-time view of a running system. +The \*(WE program provides a dynamic real-time view of a running system. It can display\fB system\fR summary information as well as a list of \*(TT currently being managed by the Linux kernel. The types of system summary information shown and the types, order and @@ -118,9 +118,9 @@ and that configuration can be made persistent across restarts. The program provides a limited interactive interface for process manipulation as well as a much more extensive interface for personal configuration \*(Em encompassing every aspect of its operation. -And while \*(ME is referred to throughout this document, you are free +And while \*(WE is referred to throughout this document, you are free to name the program anything you wish. -That new name, possibly an alias, will then be reflected on \*(Me's +That new name, possibly an alias, will then be reflected on \*(We's display and used when reading and writing a \*(CF. @@ -131,6 +131,8 @@ display and used when reading and writing a \*(CF. .SS Documentation .\" ---------------------------------------------------------------------- The remaining Table of Contents + +.Bd -literal 1. COMMAND\-LINE Options 2. SUMMARY Display a. UPTIME and LOAD Averages @@ -156,19 +158,21 @@ The remaining Table of Contents b. Bouncing Windows c. The Big Bird Window 8. BUGS, 9. HISTORY Former top, 10. AUTHOR, 11. SEE Also +.Ed .\" ...................................................................... .SS Operation .\" ---------------------------------------------------------------------- -When operating \*(Me, the two most important keys are the help ('h' or '?') +When operating \*(We, the two most important keys are the help ('h' or '?') key and quit ('q') key. Alternatively, you could simply use the traditional interrupt key ('^C') when you're done. -Some of \*(Me's screens or functions require the use of cursor motion +Some of \*(We's screens or functions require the use of cursor motion keys like the standard \*(KAs plus the Home, End, PgUp and PgDn keys. If your terminal or emulator does not provide those keys, the following keys are accepted for compatibility: +.Bd -literal -compact \fI key equivalents \fR Up alt +\fB \\ \fR or alt +\fB k \fR Down alt +\fB / \fR or alt +\fB j \fR @@ -178,8 +182,9 @@ keys are accepted for compatibility: PgDn alt +\fB Down \fR Home alt +\fB Left \fR End alt +\fB Right \fR +.Ed -When you start \*(Me for the first time, you'll be presented with these +When you start \*(We for the first time, you'll be presented with these traditional screen elements: 1) Summary Area; 2) Fields/Columns Header; 3) Task Area. These areas will be explored in the sections that follow. @@ -187,7 +192,7 @@ There is also an Input/Message line between the Summary Area and Columns Header which needs no further explanation. .PP -\*(NT the width of \*(Me's display will be limited to \*(WX positions. +\*(NT the width of \*(We's display will be limited to \*(WX positions. Displaying all fields requires \*(WF characters. The remaining width is used for the 'COMMAND' column which can display the program name or a complete command line, reflecting path and arguments. @@ -200,6 +205,7 @@ Even so, items shown with an \*(AK could be overridden through the command-line. All are explained in detail in the sections that follow. +.Bd -literal \fIGlobal-defaults\fR 'A' - Alt display Off (full-screen) * 'd' - Delay time 3.0 seconds @@ -224,12 +230,13 @@ All are explained in detail in the sections that follow. 'x' - Column hilite Off (no, sort field) 'y' - Row hilite On\ \ (yes, running tasks) 'z' - color/mono Off (no, colors) +.Ed .\" ---------------------------------------------------------------------- .SH 1. COMMAND-LINE Options .\" ---------------------------------------------------------------------- -The command-line syntax for \*(Me consists of: +The command-line syntax for \*(We consists of: \-\fBhv\fR | \-\fBbcHisS\fR \-\fBd\fI delay\fR \-\fBn\fI limit\fR \-\fBu\fR|\fBU\fI user\fR | \-\fBp\fI pid\fR [,\fIpid\fR ...] @@ -243,15 +250,15 @@ Show library version and the usage prompt, then quit. .TP 5 \-\fBb\fR :\fI Batch-mode\fR operation \fR -Starts \*(Me in 'Batch mode', which could be useful for sending output -from \*(Me to other programs or to a file. -In this mode, \*(Me will not accept input and runs until the iterations +Starts \*(We in 'Batch mode', which could be useful for sending output +from \*(We to other programs or to a file. +In this mode, \*(We will not accept input and runs until the iterations limit you've set with the '-n' \*(CO or until killed. .TP 5 \-\fBc\fR :\fI Command-line/Program-name\fR toggle \fR -Starts \*(Me with the last remembered 'c' state reversed. -Thus, if \*(Me was displaying command lines, now that field will show program +Starts \*(We with the last remembered 'c' state reversed. +Thus, if \*(We was displaying command lines, now that field will show program names, and visa versa. \*(XC 'c' \*(CI for additional information. @@ -262,19 +269,19 @@ value in one's personal \*(CF or the startup default. Later this can be changed with the 'd' or 's' \*(CIs. Fractional seconds are honored, but a negative number is not allowed. -In all cases, however, such changes are prohibited if \*(Me is running +In all cases, however, such changes are prohibited if \*(We is running in 'Secure mode', except for root (unless the 's' \*(CO was used). For additional information on 'Secure mode' \*(Xt 6a. SYSTEM Configuration File. .TP 5 \-\fBH\fR :\fI Threads-mode\fR operation \fR -Instructs \*(Me to display individual threads. +Instructs \*(We to display individual threads. Without this \*(CO a summation of all threads in each process is shown. Later this can be changed with the 'H' \*(CI. .TP 5 \-\fBi\fR :\fI Idle-process\fR toggle \fR -Starts \*(Me with the last remembered 'i' state reversed. +Starts \*(We with the last remembered 'i' state reversed. When this toggle is \*F, tasks that have not used any \*(PU since the last update will not be displayed. For additional information regarding this toggle @@ -282,7 +289,7 @@ For additional information regarding this toggle .TP 5 \-\fBn\fR :\fI Number-of-iterations\fR limit as:\fB\ \ -n number \fR -Specifies the maximum number of iterations, or frames, \*(Me should +Specifies the maximum number of iterations, or frames, \*(We should produce before ending. .TP 5 @@ -293,20 +300,20 @@ list with up to \*(WP pids. Co-mingling both approaches is permitted. This is a \*(CO only and should you wish to return to normal operation, -it is not necessary to quit and and restart \*(Me \*(Em just issue any +it is not necessary to quit and and restart \*(We \*(Em just issue any of these \*(CIs: '=', 'u' or 'U'. The 'p', 'u' and 'U' \*(COs are mutually exclusive. .TP 5 \-\fBs\fR :\fI Secure-mode\fR operation \fR -Starts \*(Me with secure mode forced, even for root. +Starts \*(We with secure mode forced, even for root. This mode is far better controlled through the system \*(CF (\*(Xt 6. FILES). .TP 5 \-\fBS\fR :\fI Cumulative-time\fR toggle \fR -Starts \*(Me with the last remembered 'S' state reversed. +Starts \*(We with the last remembered 'S' state reversed. When 'Cumulative time' mode is \*O, each process is listed with the \*(Pu time that it and its dead children have used. \*(XC 'S' \*(CI for additional information regarding this mode. @@ -332,10 +339,12 @@ these provisions. .SS 2a. UPTIME and LOAD Averages .\" ---------------------------------------------------------------------- This portion consists of a single line containing: +.Bd -literal -compact \fBprogram\fR or\fB window\fR name, depending on display mode current time and length of time since last boot total number of users system load avg over the last 1, 5 and 15 minutes +.Ed .\" ...................................................................... .SS 2b. TASK and CPU States @@ -347,18 +356,22 @@ state percentages. Line 1 shows total\fB tasks\fR or\fB threads\fR, depending on the state of the Threads-mode toggle. That total is further classified as: +.Bd -literal -compact running; sleeping; stopped; zombie +.Ed Line 2 shows \*(PU state percentages based on the interval since the last refresh. Where two labels are shown below, those for more recent kernel versions are shown first. - \fBus\fR,\fB user\fR : time running un-niced user processes - \fBsy\fR,\fB system\fR : time running kernel processes - \fBni\fR,\fB nice\fR : time running niced user processes +.Bd -literal -compact + \fBus\fR,\fB user\fR : time running un-niced user processes + \fBsy\fR,\fB system\fR : time running kernel processes + \fBni\fR,\fB nice\fR : time running niced user processes \fBwa\fR,\fB IO-wait\fR : time waiting for I/O completion \fBhi\fR : time spent servicing hardware interrupts \fBsi\fR : time spent servicing software interrupts \fBst\fR : time stolen from this vm by the hypervisor +.Ed .\" ...................................................................... .SS 2c. MEMORY Usage @@ -379,7 +392,7 @@ Line 2 reflects \*(MV, classified as: .\" ...................................................................... .SS 3a. DESCRIPTIONS of Fields .\" ---------------------------------------------------------------------- -Listed below are \*(Me's available process fields (columns). +Listed below are \*(We's available process fields (columns). They are shown in alphabetical order. You may customize their position and whether or not they are displayable with the 'f' or 'F' (Fields Management) \*(CIs. @@ -404,7 +417,7 @@ a \*(CO and an \*(CI. When you've chosen to display command lines, processes without a command line (like kernel threads) will be shown with only the program name in brackets, as in this example: - \fR[ mdrecoveryd ] + \fR[ mdrecoveryd ] Either form of display is subject to potential truncation if it's too long to fit in this field's current width. @@ -420,7 +433,7 @@ of program names into command lines. 3.\fB %CPU \*(Em \*(PU Usage \fR The task's share of the elapsed \*(PU time since the last screen update, expressed as a percentage of total \*(PU time. -In a true SMP environment, if 'Irix mode' is \*F, \*(Me will operate +In a true SMP environment, if 'Irix mode' is \*F, \*(We will operate in 'Solaris mode' where a task's \*(Pu usage will be divided by the total number of \*(PUs. You toggle 'Irix/Solaris' modes with the 'I' \*(CI. @@ -488,7 +501,7 @@ The number of threads associated with a process. A number representing the last used processor. In a true SMP environment this will likely change frequently since the kernel intentionally uses weak affinity. -Also, the very act of running \*(Me may break this weak affinity and cause more +Also, the very act of running \*(We may break this weak affinity and cause more processes to change \*(PUs more often (because of the extra demand for \*(Pu time). @@ -543,7 +556,7 @@ The status of the task which can be one of: Tasks shown as running should be more properly thought of as 'ready to run' \*(Em their task_struct is simply represented on the Linux run-queue. Even without a true SMP machine, you may see numerous tasks in this state -depending on \*(Me's delay interval and nice value. +depending on \*(We's delay interval and nice value. .TP 4 23.\fB SHR \*(Em Shared Memory Size (kb) \fR @@ -626,9 +639,9 @@ field will show the name or the address of the kernel function in which the task is currently sleeping. Running tasks will display a dash ('-') in this column. -\*(NT By displaying this field, \*(Me's own working set will be increased by +\*(NT By displaying this field, \*(We's own working set will be increased by over 700Kb. -Your only means of reducing that overhead will be to stop and restart \*(Me. +Your only means of reducing that overhead will be to stop and restart \*(We. .\" ...................................................................... .SS 3b. MANAGING Fields @@ -669,7 +682,7 @@ windows and the '\fBq\fR' or <\fBEsc\fR> keys exit Fields Management. The Fields Management screen can also be used to change the \*(CG in either \*(FM or \*(AM. Whatever was targeted when 'q' or was pressed will be made current -as you return to the \*(Me display. +as you return to the \*(We display. \*(XT 5. ALTERNATE\-DISPLAY Provisions and the 'g' \*(CI for insight into \*(CWs and \*(FGs. @@ -688,6 +701,7 @@ Listed below is a brief index of commands within categories. Some commands appear more than once \*(Em their meaning or scope may vary depending on the context in which they are issued. +.Bd -literal 4a.\fI Global-Commands \fR ?, =, A, B, d, g, h, H, I, k, q, r, s, W, Z 4b.\fI Summary-Area-Commands \fR @@ -703,6 +717,7 @@ depending on the context in which they are issued. -, _, =, +, A, a, g, G, w 5c.\fI Scrolling-a-Window \fR C, Up, Dn, Left, Right, PgUp, PgDn, Home, End +.Ed .\" ...................................................................... .SS 4a. GLOBAL Commands @@ -711,14 +726,14 @@ The global \*(CIs are\fB always\fR available\fR in both \*(FM and \*(AM. However, some of these \*(CIs are\fB not available\fR when running in 'Secure mode'. -If you wish to know in advance whether or not your \*(Me has been +If you wish to know in advance whether or not your \*(We has been secured, simply ask for help and view the system summary on the second line. .TP 7 \ \ \<\fBEnter\fR> or <\fBSpace\fR> :\fIRefresh-Display \fR These commands do nothing, they are simply ignored. -However, they will awaken \*(Me and following receipt of any input +However, they will awaken \*(We and following receipt of any input the entire display will be repainted. Use either of these keys if you have a large delay interval and wish @@ -728,7 +743,7 @@ to see current status, \ \ \'\fB?\fR\' | \'\fBh\fR\' :\fIHelp \fR There are two help levels available. The first will provide a reminder of all the basic \*(CIs. -If \*(Me is\fI secured\fR, that screen will be abbreviated. +If \*(We is\fI secured\fR, that screen will be abbreviated. Typing 'h' or '?' on that help screen will take you to help for those \*(CIs applicable to \*(AM. @@ -762,7 +777,7 @@ alters\fB both\fR the \*(SA and \*(TA for the \*(CW. While it is intended primarily for use with dumb terminals, it can be applied anytime. -\*(NT When this toggle is \*O and \*(Me is operating in monochrome mode, +\*(NT When this toggle is \*O and \*(We is operating in monochrome mode, the\fB entire display\fR will appear as normal text. Thus, unless the 'x' and/or 'y' toggles are using reverse for emphasis, there will be no visual confirmation that they are even on. @@ -774,7 +789,7 @@ display updates. Fractional seconds are honored, but a negative number is not allowed. Entering 0 causes (nearly) continuous updates, with an unsatisfactory -display as the system and tty driver try to keep up with \*(Me's demands. +display as the system and tty driver try to keep up with \*(We's demands. The delay value is inversely proportional to system loading, so set it with care. @@ -792,7 +807,7 @@ experimenting with \*(AM. \ \ \'\fBH\fR\' :\fIThreads-mode\fR toggle \fR When this toggle is \*O, individual threads will be displayed for all processes in all visible \*(TWs. -Otherwise, \*(Me displays a summation of all threads in each process. +Otherwise, \*(We displays a summation of all threads in each process. .TP 7 \ \ \'\fBI\fR\' :\fIIrix/Solaris-Mode\fR toggle \fR @@ -808,8 +823,8 @@ However, you can send any signal, via number or name. If you wish to abort the kill process, do one of the following depending on your progress: - 1) at the pid prompt, just press - 2) at the signal prompt, type 0 + 1) at the pid prompt, just press + 2) at the signal prompt, type 0 .TP 7 \ \ \'\fBq\fR\' :\fIQuit \fR @@ -825,7 +840,7 @@ favorably by the kernel. \ \ \'\fBW\fR\' :\fIWrite-the-Configuration-File \fR This will save all of your options and toggles plus the current display mode and delay time. -By issuing this command just before quitting \*(Me, you will be able +By issuing this command just before quitting \*(We, you will be able restart later in exactly that same state. .TP 7 @@ -857,7 +872,7 @@ when operating in \*(FM or the \*(CW name when operating in \*(AM. .TP 7 \ \ \'\fBt\fR\' :\fITask/Cpu-States\fR toggle \fR This command affects from 2 to many \*(SA lines, depending on the state -of the '1' toggle and whether or not \*(Me is running under true SMP. +of the '1' toggle and whether or not \*(We is running under true SMP. This portion of the \*(SA is also influenced by the 'H' \*(CI toggle, as reflected in the total label which shows either 'Tasks' or 'Threads'. @@ -912,8 +927,8 @@ Changes highlighting for the current sort field. If you forget which field is being sorted this command can serve as a quick visual reminder, providing the sort field is being displayed. The sort field might\fI not\fR be visible because: - 1) there is insufficient\fI Screen Width \fR - 2) the 'f' \*(CI turned it \*F + 1) there is insufficient\fI Screen Width \fR + 2) the 'f' \*(CI turned it \*F .TP 7 \ \ \'\fBy\fR\' :\fIRow-Highlight\fR toggle \fR @@ -1011,17 +1026,19 @@ simply decrease the size of the \*(TD(s) above it. .B SORTING\fR of \*(TW .br .in +2 -For compatibility, this \*(Me supports most of the former \*(Me sort keys. -Since this is primarily a service to former \*(Me users, these commands do +For compatibility, this \*(We supports most of the former \*(We sort keys. +Since this is primarily a service to former \*(We users, these commands do not appear on any help screen. +.Bd -literal -compact \fI command sorted-field supported \fR A start time (non-display) \fB No \fR M %MEM Yes N PID Yes P %CPU Yes T TIME+ Yes +.Ed -Before using any of the following sort provisions, \*(Me suggests that you +Before using any of the following sort provisions, \*(We suggests that you temporarily turn on column highlighting using the 'x' \*(CI. That will help ensure that the actual sort environment matches your intent. @@ -1053,7 +1070,7 @@ the current sort field is visible. These keys display a separate screen where you can change which field is used as the sort column, among other functions. This can be a convenient way to simply verify the current sort field, -when running \*(Me with column highlighting turned \*F. +when running \*(We with column highlighting turned \*F. .TP 7 \ \ \'\fBR\fR\' :\fIReverse/Normal-Sort-Field\fR toggle \fR @@ -1070,10 +1087,11 @@ Thus, the TTY and WCHAN fields will violate strict ASCII collating sequence. .\" ---------------------------------------------------------------------- When you issue the 'Z' \*(CI, you will be presented with a separate screen. That screen can be used to change the colors in just the \*(CW or -in all four windows before returning to the \*(Me display. +in all four windows before returning to the \*(We display. .P -.B Available \*(CIs +The following \*(CIs are available. +.Bd -literal -compact \fB4\fR upper case letters to select a\fB target \fR \fB8\fR numbers to select a\fB color \fR normal toggles available \fR @@ -1084,6 +1102,7 @@ in all four windows before returning to the \*(Me display. 'a'/'w' :apply, then go to next/prior :apply and exit 'q' :abandon current changes and exit +.Ed If your use 'a' or 'w' to cycle the targeted window, you will have applied the color scheme that was displayed when you left that window. @@ -1093,7 +1112,7 @@ colors or turn colors \*F completely with the 'z' toggle. The Color Mapping screen can also be used to change the \*(CG in either \*(FM or \*(AM. Whatever was targeted when 'q' or was pressed will be made current -as you return to the \*(Me display. +as you return to the \*(We display. .\" ---------------------------------------------------------------------- @@ -1200,9 +1219,11 @@ It does not require that the window name be visible .IP "*" 3 The \*(CIs shown with an \*(AK have use beyond \*(AM. +.Bd -literal -compact \'=', 'A', 'g' are always available \'a', 'w' act the same with color mapping \ and fields management +.Ed .\" ...................................................................... .SS 5c. SCROLLING a Window @@ -1254,7 +1275,9 @@ display element. Toggle an informational message which is displayed whenever the message line is not otherwise being used. - "\fBscroll coordinates: y = n/n (tasks), x = n/n (fields)\fR" +.Bd -literal + "\fBscroll coordinates: y = n/n (tasks), x = n/n (fields)\fR" +.Ed The coordinates shown as \fBn\fR/\fBn\fR are relative to the upper left corner of the \*(CW. @@ -1288,21 +1311,25 @@ available in \*(AM if the \*(CW's \*(TD has been toggled \*F. The presence of this file will influence which version of the 'help' screen is shown to an ordinary user. More importantly, it will limit what ordinary users are allowed -to do when \*(Me is running. +to do when \*(We is running. They will not be able to issue the following commands. +.Bd -literal -compact k Kill a task r Renice a task d or s Change delay/sleep interval +.Ed -The system \*(CF is\fB not\fR created by \*(Me. +The system \*(CF is\fB not\fR created by \*(We. Rather, you create this file manually and place it in the \fI/etc \fR directory. Its name must be 'toprc' and must have no leading '.' (period). It must have only two lines. Here is an example of the contents of\fI /etc/toprc\fR: +.Bd -literal -compact s # line 1: 'secure' mode switch 5.0 # line 2: 'delay'\ \ interval in seconds +.Ed .\" ...................................................................... .SS 6b. PERSONAL Configuration File @@ -1311,29 +1338,31 @@ This file is written as '$HOME/.your-name-4-top' + 'rc'. Use the 'W' \*(CI to create it or update it. Here is the general layout: +.Bd -literal -compact global # line 1: the program name/alias notation " # line 2: id,altscr,irixps,delay,curwin per ea # line a: winname,fieldscur window # line b: winflags,sortindx,maxtasks " # line c: summclr,msgsclr,headclr,taskclr +.Ed -If the $HOME variable is not present, \*(Me will try to write the +If the $HOME variable is not present, \*(We will try to write the personal \*(CF to the current directory, subject to permissions. .\" ---------------------------------------------------------------------- .SH 7. STUPID TRICKS Sampler .\" ---------------------------------------------------------------------- -Many of these 'tricks' work best when you give \*(Me a scheduling boost. +Many of these 'tricks' work best when you give \*(We a scheduling boost. So plan on starting him with a nice value of -10, assuming you've got the authority. .\" ...................................................................... .SS 7a. Kernel Magic .\" ---------------------------------------------------------------------- -\# sorry, just can't help it -- don't ya love the sound of this? -For these stupid tricks, \*(Me needs \*(FM. -\# ( apparently AM static was a potential concern ) +.\" sorry, just can't help it -- don't ya love the sound of this? +For these stupid tricks, \*(We needs \*(FM. +.\" ( apparently AM static was a potential concern ) .jBu The user interface, through prompts and help, intentionally implies @@ -1344,6 +1373,7 @@ seconds or less. For this experiment, under x-windows open an xterm and maximize it. Then do the following: +.Bd -literal -compact . provide a scheduling boost and tiny delay via: nice -n -10 top -d.09 . keep sorted column highlighting \*F so as to @@ -1352,12 +1382,13 @@ Then do the following: . try various sort columns (TIME/MEM work well), and normal or reverse sorts to bring the most active processes into view +.Ed What you'll see is a very busy Linux doing what he's always done for you, but there was no program available to illustrate this. .jBu -Under an xterm using 'white-on-black' colors, on \*(Me's Color Mapping screen +Under an xterm using 'white-on-black' colors, on \*(We's Color Mapping screen set the task color to black and be sure that task highlighting is set to bold, not reverse. Then set the delay interval to around .3 seconds. @@ -1371,21 +1402,21 @@ Start this new version then type 'T' (a secret key, \*(Xt 4c. Task Area Commands, SORTING) followed by 'W' and 'q'. Finally, restart the program with -d0 (zero delay). -Your display will be refreshed at three times the rate of the former \*(Me, +Your display will be refreshed at three times the rate of the former \*(We, a 300% speed advantage. -As \*(Me climbs the TIME ladder, be as patient as you can while speculating -on whether or not \*(Me will ever reach the \*(Me. +As \*(We climbs the TIME ladder, be as patient as you can while speculating +on whether or not \*(We will ever reach the \*(We. .\" ...................................................................... .SS 7b. Bouncing Windows .\" ---------------------------------------------------------------------- -For these stupid tricks, \*(Me needs \*(AM. +For these stupid tricks, \*(We needs \*(AM. .jBu With 3 or 4 \*(TDs visible, pick any window other than the last and turn idle processes \*F using the 'i' \*(CT. Depending on where you applied 'i', sometimes several \*(TDs are bouncing and -sometimes it's like an accordion, as \*(Me tries his best to allocate space. +sometimes it's like an accordion, as \*(We tries his best to allocate space. .jBu Set each window's summary lines differently: one with no memory ('m'); another @@ -1412,7 +1443,7 @@ When they've all been displaced, toggle between all visible/invisible windows using the '_' \*(CT. Then ponder this: .br - is \*(Me fibbing or telling honestly your imposed truth? + is \*(We fibbing or telling honestly your imposed truth? .PP .\" ---------------------------------------------------------------------- @@ -1450,9 +1481,9 @@ This entirely new and enhanced replacement was written by: With invaluable help from: Craig Small, -\# Craig Small. -\# Craig Small, -\# Craig Small, +.\" Craig Small. +.\" Craig Small, +.\" Craig Small, Albert Cahalan, .ig @@ -1497,8 +1528,8 @@ A copy of the license is included in the section entitled \(dqGNU Free Documentation License\(dq. .. . -\# end: active doc |||||||||||||||||||||||||||||||||||||||||||||||||||||| -\# ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +.\" end: active doc |||||||||||||||||||||||||||||||||||||||||||||||||||||| +.\" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| .ig .\" ---------------------------------------------------------------------- @@ -1856,5 +1887,5 @@ to permit their use in free software. .IP "" .PP .. -\# end: gfdl license |||||||||||||||||||||||||||||||||||||||||||||||||||| -\# ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +.\" end: gfdl license |||||||||||||||||||||||||||||||||||||||||||||||||||| +.\" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| diff --git a/top.c b/top.c index d275019a..e7a492d3 100644 --- a/top.c +++ b/top.c @@ -76,7 +76,7 @@ static unsigned Pg2K_shft = 0; /* SMP, Irix/Solaris mode, Linux 2.5.xx support */ /* (assume no IO-wait stats, overridden if linux 2.5.41) */ static int Cpu_tot; -static double Cpu_pmax = 99.9; // for %CPU display (may be changed!) +static float Cpu_pmax = 99.9; // for %CPU display (may later change!) static const char *Cpu_States_fmts = STATES_line2x4; /* Specific process id monitoring support */ @@ -217,6 +217,10 @@ SCB_NUM1(FL2, min_flt) SCB_NUMx(GID, egid) SCB_STRS(GRP, egroup) SCB_NUMx(NCE, nice) +#ifdef ZAP_SUSEONLY +SCB_NUM1(OOA, oom_adj) +SCB_NUM1(OOM, oom_score) +#endif SCB_NUMx(PGD, pgrp) SCB_NUMx(PID, tid) SCB_NUMx(PPD, ppid) @@ -327,7 +331,7 @@ static void bye_bye (const char *str) { } fflush(stdout); -#ifdef ATEOJ_STDRPT +#ifdef ATEOJ_RPTSTD { proc_t *p; if (!str) { fprintf(stderr, "\n%s's Summary report:" @@ -338,6 +342,7 @@ static void bye_bye (const char *str) { "\n\t sizeof(CPU_t) = %u, sizeof(HST_t) = %u (%u HST_t's/Page), HHist_siz = %u" "\n\t sizeof(proc_t) = %u, sizeof(proc_t.cmd) = %u" "\n\t Frames_libflags = %08lX" + "\n\t SCREENMAX = %u, ROWMINSIZ = %u, ROWMAXSIZ = %u" "\n\tTerminal: %s" "\n\t device = %s, ncurses = v%s" "\n\t max_colors = %d, max_pairs = %d" @@ -369,6 +374,7 @@ static void bye_bye (const char *str) { , (unsigned) sizeof(CPU_t), (unsigned)sizeof(HST_t), Page_size / (unsigned)sizeof(HST_t), HHist_siz , (unsigned)sizeof(*p), (unsigned)sizeof(p->cmd) , (long)Frames_libflags + , (unsigned)SCREENMAX, (unsigned)ROWMINSIZ, (unsigned)ROWMAXSIZ #ifdef PRETENDNOCAP , "dumb" #else @@ -391,81 +397,82 @@ static void bye_bye (const char *str) { ); } } -#endif // end: ATEOJ_STDRPT +#endif // end: ATEOJ_RPTSTD #ifndef OFF_HST_HASH -#ifdef ATEOJ_HSHRPT -{ int i, j, pop, total_occupied, maxdepth, maxdepth_sav, numdepth - , cross_foot, sz = HHASH_SIZ * (unsigned)sizeof(int); - int depths[HHASH_SIZ]; +#ifdef ATEOJ_RPTHSH + if (!str) { + int i, j, pop, total_occupied, maxdepth, maxdepth_sav, numdepth + , cross_foot, sz = HHASH_SIZ * (unsigned)sizeof(int); + int depths[HHASH_SIZ]; - for (i = 0, total_occupied = 0, maxdepth = 0; i < HHASH_SIZ; i++) { - int V = PHash_new[i]; - j = 0; - if (-1 < V) { - ++total_occupied; - while (-1 < V) { - V = PHist_new[V].lnk; - if (-1 < V) j++; + for (i = 0, total_occupied = 0, maxdepth = 0; i < HHASH_SIZ; i++) { + int V = PHash_new[i]; + j = 0; + if (-1 < V) { + ++total_occupied; + while (-1 < V) { + V = PHist_new[V].lnk; + if (-1 < V) j++; + } + } + depths[i] = j; + if (maxdepth < j) maxdepth = j; + } + maxdepth_sav = maxdepth; + + fprintf(stderr, + "\n%s's Supplementary HASH report:" + "\n\tTwo Tables providing for %d entries each + 1 extra for 'empty' image" + "\n\t%dk (%d bytes) per table, %d total bytes (including 'empty' image)" + "\n\tResults from latest hash (PHash_new + PHist_new)..." + "\n" + "\n\tTotal hashed = %d" + "\n\tLevel-0 hash entries = %d (%d%% occupied)" + "\n\tMax Depth = %d" + "\n\n" + , __func__ + , HHASH_SIZ, sz / 1024, sz, sz * 3 + , Frame_maxtask + , total_occupied, (total_occupied * 100) / HHASH_SIZ + , maxdepth + 1); + + if (total_occupied) { + for (pop = total_occupied, cross_foot = 0; maxdepth; maxdepth--) { + for (i = 0, numdepth = 0; i < HHASH_SIZ; i++) + if (depths[i] == maxdepth) ++numdepth; + fprintf(stderr, + "\t %5d (%3d%%) hash table entries at depth %d\n" + , numdepth, (numdepth * 100) / total_occupied, maxdepth + 1); + pop -= numdepth; + cross_foot += numdepth; + if (0 == pop && cross_foot == total_occupied) break; + } + if (pop) { + fprintf(stderr, "\t %5d (%3d%%) unchained hash table entries\n" + , pop, (pop * 100) / total_occupied); + cross_foot += pop; + } + fprintf(stderr, + "\t -----\n" + "\t %5d total entries occupied\n", cross_foot); + + if (maxdepth_sav) { + fprintf(stderr, "PIDs at max depth: "); + for (i = 0; i < HHASH_SIZ; i++) + if (depths[i] == maxdepth_sav) { + j = PHash_new[i]; + fprintf(stderr, "\n\tpos %4d: %05d", i, PHist_new[j].pid); + while (-1 < j) { + j = PHist_new[j].lnk; + if (-1 < j) fprintf(stderr, ", %05d", PHist_new[j].pid); + } + } + fprintf(stderr, "\n"); } } - depths[i] = j; - if (maxdepth < j) maxdepth = j; } - maxdepth_sav = maxdepth; - - fprintf(stderr, - "\n%s's Supplementary HASH report:" - "\n\tTwo Tables providing for %d entries each + 1 extra for 'empty' image" - "\n\t%dk (%d bytes) per table, %d total bytes (including 'empty' image)" - "\n\tResults from latest hash (PHash_new + PHist_new)..." - "\n" - "\n\tTotal hashed = %d" - "\n\tLevel-0 hash entries = %d (%d%% occupied)" - "\n\tMax Depth = %d" - "\n\n" - , __func__ - , HHASH_SIZ, sz / 1024, sz, sz * 3 - , Frame_maxtask - , total_occupied, (total_occupied * 100) / HHASH_SIZ - , maxdepth + 1); - - if (total_occupied) { - for (pop = total_occupied, cross_foot = 0; maxdepth; maxdepth--) { - for (i = 0, numdepth = 0; i < HHASH_SIZ; i++) - if (depths[i] == maxdepth) ++numdepth; - fprintf(stderr, - "\t %5d (%3d%%) hash table entries at depth %d\n" - , numdepth, (numdepth * 100) / total_occupied, maxdepth + 1); - pop -= numdepth; - cross_foot += numdepth; - if (0 == pop && cross_foot == total_occupied) break; - } - if (pop) { - fprintf(stderr, "\t %5d (%3d%%) unchained hash table entries\n" - , pop, (pop * 100) / total_occupied); - cross_foot += pop; - } - fprintf(stderr, - "\t -----\n" - "\t %5d total entries occupied\n\n", cross_foot); - - if (maxdepth_sav) { - fprintf(stderr, "PIDs at max depth: "); - for (i = 0; i < HHASH_SIZ; i++) - if (depths[i] == maxdepth_sav) { - j = PHash_new[i]; - fprintf(stderr, "\n\tpos %4d: %05d", i, PHist_new[j].pid); - while (-1 < j) { - j = PHist_new[j].lnk; - if (-1 < j) fprintf(stderr, ", %05d", PHist_new[j].pid); - } - } - fprintf(stderr, "\n\n"); - } - } -} -#endif // end: ATEOJ_HSHRPT +#endif // end: ATEOJ_RPTHSH #endif // end: OFF_HST_HASH if (str) { @@ -634,9 +641,10 @@ static void msg_save (const char *fmts, ...) { /* * Show an error message (caller may include '\a' for sound) */ static void show_msg (const char *str) { - PUTT("%s%s %s %s%s" + PUTT("%s%s %.*s %s%s" , tg2(0, Msg_row) , Curwin->capclr_msg + , Screen_cols - 2 , str , Caps_off , Cap_clr_eol); @@ -649,9 +657,10 @@ static void show_msg (const char *str) { /* * Show an input prompt + larger cursor (if possible) */ static int show_pmt (const char *str) { - PUTT("%s%s%s: %s%s%s" + PUTT("%s%s%.*s: %s%s%s" , tg2(0, Msg_row) , Curwin->capclr_pmt + , Screen_cols - 2 , str , Cap_curs_huge , Caps_off @@ -665,13 +674,13 @@ static int show_pmt (const char *str) { /* * Show a special coordinate message, in support of scrolling */ static inline void show_scroll (void) { - char tmp[MEDBUFSIZ]; + char tmp[SMLBUFSIZ]; snprintf(tmp, sizeof(tmp) , "scroll coordinates: y = %d/%d (tasks), x = %d/%d (fields)" , Curwin->begtask + 1, Frame_maxtask , Curwin->begpflg + 1, Curwin->totpflgs); - PUTT("%s%s %s%s", tg2(0, Msg_row), Caps_off, tmp, Cap_clr_eol); + PUTT("%s%s %.*s%s", tg2(0, Msg_row), Caps_off, Screen_cols - 2, tmp, Cap_clr_eol); putp(tg2(0, Msg_row)); } // end: show_scroll @@ -713,7 +722,9 @@ static void show_special (int interact, const char *glob) { | capclr_rowhigh, = \07, | | capclr_rownorm }; = \10 [octal!] | +------------------------------------------------------+ */ - char lin[BIGBUFSIZ], row[ROWBUFSIZ], tmp[MEDBUFSIZ]; + /* ( pssst, after adding the termcap transitions, row may ) + ( exceed 300+ bytes, even in an 80x24 terminal window! ) */ + char tmp[SMLBUFSIZ], lin[MEDBUFSIZ], row[LRGBUFSIZ]; char *rp, *cap, *lin_end, *sub_beg, *sub_end; int room; @@ -847,7 +858,7 @@ static int keyin (int init) { { "\033\\",kbd_UP }, { "\033/", kbd_DOWN }, { "\033>", kbd_RIGHT }, { "\033<", kbd_LEFT }, { "\033k", kbd_UP }, { "\033j", kbd_DOWN }, { "\033l", kbd_RIGHT }, { "\033h", kbd_LEFT } }; - char buf[ASKBUFSIZ], *pb; + char buf[SMLBUFSIZ], *pb; int i; if (init) { @@ -872,10 +883,9 @@ static int keyin (int init) { return 0; #undef tOk } + memset(buf, '\0', sizeof(buf)); - /* we'll force caller to think his/her/its job is done whenver - chin is interrupted by some signal */ - if (1 > chin(0, buf, sizeof(buf)-1)) return kbd_ESC; + if (1 > chin(0, buf, sizeof(buf)-1)) return 0; /* some emulators implement 'key repeat' too well and we get duplicate key sequences -- so we'll focus on the last escaped sequence, while @@ -941,14 +951,14 @@ static char *linein (const char *prompt) { case kbd_ENTER: break; case kbd_DEL: + case kbd_DOWN: sqzSTR break; case kbd_BKSP : if (0 < pos) { --pos; sqzSTR } break; case kbd_INS: - case kbd_UP: // the ins key may not be available, - case kbd_DOWN: // so we'll make use of some others + case kbd_UP: expSTR break; case kbd_LEFT: @@ -1227,6 +1237,12 @@ static FLD_t Fieldstab[] = { { "Flags ", "%08lX ", -1, -1, SF(FLG), L_stat, "Task Flags " } #else { "Flags ", "%08lx ", -1, -1, SF(FLG), L_stat, "Task Flags " } +#endif +#ifdef ZAP_SUSEONLY +#define L_oom PROC_FILLOOM + ,{ "Adj ", "%3d ", -1, -1, SF(OOA), L_oom, "oom_adjustment (2^X)" } + ,{ " Badness ", "%8d ", -1, -1, SF(OOM), L_oom, "oom_score (badness)" } +#undef L_oom #endif #undef SF }; @@ -1287,9 +1303,9 @@ static void adj_geometry (void) { between us and the great-beyond... */ if (Batch) { Screen_rows = MAXINT; - Pseudo_size = (sizeof(*Pseudo_screen) * ROWBUFSIZ); + Pseudo_size = (sizeof(*Pseudo_screen) * ROWMAXSIZ); } else - Pseudo_size = (sizeof(*Pseudo_screen) * ROWBUFSIZ) * Screen_rows; + Pseudo_size = (sizeof(*Pseudo_screen) * ROWMAXSIZ) * Screen_rows; // we'll only grow our Pseudo_screen, never shrink it if (pseudo_max < Pseudo_size) { @@ -1329,30 +1345,43 @@ static void calibrate_fields (void) { do { if (VIZISw(w)) { +#ifdef USE_X_COLHDR +#ifdef EQUCOLHDRYES + w->hdrcaplen = 0; +#endif +#endif // build window's pflgsall array, establish upper bounds for maxpflgs for (i = 0, w->totpflgs = 0; i < P_MAXPFLGS; i++) { if (FLDviz(w, i)) { f = FLDget(w, i); +#ifdef USE_X_COLHDR + w->pflgsall[w->totpflgs++] = f; +#else if (CHKw(w, Show_HICOLS) && f == w->rc.sortindx) { w->pflgsall[w->totpflgs++] = X_XON; w->pflgsall[w->totpflgs++] = f; w->pflgsall[w->totpflgs++] = X_XOF; } else w->pflgsall[w->totpflgs++] = f; +#endif } } /* build a preliminary columns header not to exceed screen width while accounting for a possible leading window number */ + w->maxcmdln = 0; *(s = w->columnhdr) = '\0'; if (Rc.mode_altscr) s = scat(s, " "); for (i = 0; i + w->begpflg < w->totpflgs; i++) { f = w->pflgsall[i + w->begpflg]; w->procflgs[i] = f; +#ifndef USE_X_COLHDR if (P_MAXPFLGS < f) continue; +#endif h = Fieldstab[f].head; // oops, won't fit -- we're outta here... - if (Screen_cols < ((int)(s - w->columnhdr) + (int)strlen(h))) break; + if (Screen_cols <= ((int)(s - w->columnhdr) + (int)strlen(h))) break; + if (P_CMD == f) w->maxcmdln = strlen(h) - 1; s = scat(s, h); } @@ -1360,20 +1389,22 @@ static void calibrate_fields (void) { heading via maxcmdln - it may be a fib if P_CMD wasn't encountered, but that's ok because it won't be displayed anyway */ w->maxpflgs = i; - w->maxcmdln = Screen_cols - (strlen(w->columnhdr) - strlen(Fieldstab[P_CMD].head)) - 1; + w->maxcmdln += Screen_cols - strlen(w->columnhdr) - 1; /* establish the field where all remaining fields would still fit within screen width, including a leading window number */ *(s = w->columnhdr) = '\0'; if (Rc.mode_altscr) s = scat(s, " "); - for (i = w->totpflgs - 1; 0 < i; i--) { + for (i = w->totpflgs - 1; -1 < i; i--) { f = w->pflgsall[i]; +#ifndef USE_X_COLHDR if (P_MAXPFLGS < f) continue; +#endif h = Fieldstab[f].head; - if (Screen_cols < ((int)(s - w->columnhdr) + (int)strlen(h))) break; + if (Screen_cols <= ((int)(s - w->columnhdr) + (int)strlen(h))) break; s = scat(s, h); + w->endpflg = i; } - w->endpflg = i ? i + 1 : i; /* finally, we can build the true run-time columns header, format the command column heading, if P_CMD is really being displayed, and @@ -1383,7 +1414,17 @@ static void calibrate_fields (void) { if (Rc.mode_altscr) s = scat(s, fmtmk("%d", w->winnum)); for (i = 0; i < w->maxpflgs; i++) { f = w->procflgs[i]; +#ifdef USE_X_COLHDR + if (CHKw(w, Show_HICOLS) && f == w->rc.sortindx) { + s = scat(s, fmtmk("%s%s", Caps_off, w->capclr_msg)); +#ifdef EQUCOLHDRYES + w->hdrcaplen += strlen(Caps_off) + strlen(w->capclr_msg); +#endif + } +#endif +#ifndef USE_X_COLHDR if (P_MAXPFLGS < f) continue; +#endif h = Fieldstab[f].head; if (P_WCH == f) needpsdb = 1; if (P_CMD == f) { @@ -1392,10 +1433,22 @@ static void calibrate_fields (void) { } else s = scat(s, h); Frames_libflags |= Fieldstab[w->procflgs[i]].lflg; +#ifdef USE_X_COLHDR + if (CHKw(w, Show_HICOLS) && f == w->rc.sortindx) { + s = scat(s, fmtmk("%s%s", Caps_off, w->capclr_hdr)); +#ifdef EQUCOLHDRYES + w->hdrcaplen += strlen(Caps_off) + strlen(w->capclr_hdr); +#endif + } +#endif } #ifdef EQUCOLHDRYES // prepare to even out column header lengths... +#ifdef USE_X_COLHDR + if (hdrmax + w->hdrcaplen < (x = strlen(w->columnhdr))) hdrmax = x - w->hdrcaplen; +#else if (hdrmax < (x = strlen(w->columnhdr))) hdrmax = x; +#endif #endif } // end: VIZISw(w) if (Rc.mode_altscr) w = w->next; @@ -1405,10 +1458,17 @@ static void calibrate_fields (void) { /* now we can finally even out column header lengths (we're assuming entire columnhdr was memset to '\0') */ if (Rc.mode_altscr && SCREENMAX > Screen_cols) - for (i = 0; i < GROUPSMAX; i++) - if (CHKw(&Winstk[i], Show_TASKON)) - if (hdrmax > (x = strlen(Winstk[i].columnhdr))) - memset(&Winstk[i].columnhdr[x], ' ', hdrmax - x); + for (i = 0; i < GROUPSMAX; i++) { + w = &Winstk[i]; + if (CHKw(w, Show_TASKON)) +#ifdef USE_X_COLHDR + if (hdrmax + w->hdrcaplen > (x = strlen(w->columnhdr))) + memset(&w->columnhdr[x], ' ', hdrmax + w->hdrcaplen - x); +#else + if (hdrmax > (x = strlen(w->columnhdr))) + memset(&w->columnhdr[x], ' ', hdrmax - x); +#endif + } #endif // do we need the kernel symbol table (and is it already open?) @@ -1466,11 +1526,11 @@ static void display_fields (int focus, int extend, const char *xtra) { , tg2((i / rmax) * cmax, (i % rmax) + yRSVD) , b ? '*' : ' ' , b ? w->cap_bold : Cap_norm - , i == focus ? Curwin->capclr_msg : "" + , i == focus ? w->capclr_msg : "" , p , Cap_norm , b ? w->cap_bold : "" - , (i == focus && extend) ? Curwin->capclr_msg : "" + , (i == focus && extend) ? w->capclr_msg : "" , Fieldstab[f].desc , Cap_norm); #ifdef FIELD_CURSOR @@ -1500,7 +1560,8 @@ static void display_fields (int focus, int extend, const char *xtra) { /* * Manage all fields aspects (order/toggle/sort), for all windows. */ static void fields_utility (void) { - #define swapEM { w->begpflg = 0; c = w->rc.fieldscur[i]; \ + #define unSCRL w->begpflg = 0; + #define swapEM { unSCRL; c = w->rc.fieldscur[i]; \ w->rc.fieldscur[i] = *p; *p = c; p = &w->rc.fieldscur[i]; } #define spewFI { f = w->rc.sortindx; t = strchr(w->rc.fieldscur, f + FLD_OFFSET); \ if (!t) t = strchr(w->rc.fieldscur, (f + FLD_OFFSET) | 0x80); \ @@ -1545,18 +1606,18 @@ static void fields_utility (void) { break; case kbd_HOME: case kbd_PGUP: - i = 0; + if (!p) i = 0; break; case kbd_END: case kbd_PGDN: - i = P_MAXPFLGS - 1; + if (!p) i = P_MAXPFLGS - 1; break; case kbd_SPACE: case 'd': - if (!p) FLDtog(w, i); + if (!p) { FLDtog(w, i); unSCRL } break; case 's': - if (!p) { w->rc.sortindx = f = FLDget(w, i); h = NULL; w->begpflg = 0; } + if (!p) { w->rc.sortindx = f = FLDget(w, i); h = NULL; unSCRL } break; case 'a': case 'w': @@ -1570,6 +1631,7 @@ static void fields_utility (void) { } } while ('q' != key && kbd_ESC != key); putp(Cap_curs_norm); + #undef unSCRL #undef swapEM #undef spewFI } // end: fields_utility @@ -1629,8 +1691,8 @@ static CPU_t *cpus_refresh (CPU_t *cpus) { int i; // *** hotplug_cpu_acclimated *** - if (smp_sav != smp_num_cpus) { - Cpu_tot = smp_sav = smp_num_cpus; + if (smp_sav != SMP_NUM_CPUS) { + Cpu_tot = smp_sav = SMP_NUM_CPUS; zap_fieldstab(); calibrate_fields(); if (fp) { fclose(fp); fp = NULL; } @@ -1937,9 +1999,9 @@ static void before (char *me) { // establish cpu particulars -- even bigger! #ifdef PRETEND4CPUS - smp_num_cpus = Cpu_tot = 4; + SMP_NUM_CPUS = Cpu_tot = 4; #else - Cpu_tot = smp_num_cpus; + Cpu_tot = SMP_NUM_CPUS; #endif if (linux_version_code > LINUX_VERSION(2, 5, 41)) Cpu_States_fmts = STATES_line2x5; @@ -1987,7 +2049,7 @@ static void configs_read (void) { RCF_t rcdef = DEF_RCFILE; #endif float tmp_delay = DEF_DELAY; - char fbuf[MEDBUFSIZ]; + char fbuf[LRGBUFSIZ]; FILE *fp; int i, x; char id; @@ -2552,7 +2614,6 @@ static void help_view (void) { } putp(Cap_curs_norm); - PSU_CLREOS(0); } // end: help_view @@ -2675,7 +2736,9 @@ static void keys_task (int ch) { while (p > w->procflgs && *p != w->rc.sortindx) --p; if (*p == w->rc.sortindx) { --p; +#ifndef USE_X_COLHDR if (P_MAXPFLGS < *p) --p; +#endif if (p >= w->procflgs) w->rc.sortindx = *p; } } @@ -2686,14 +2749,20 @@ static void keys_task (int ch) { while (p > w->procflgs && *p != w->rc.sortindx) --p; if (*p == w->rc.sortindx) { ++p; +#ifndef USE_X_COLHDR if (P_MAXPFLGS < *p) ++p; +#endif if (p < w->procflgs + w->maxpflgs) w->rc.sortindx = *p; } } break; case 'b': if (VIZCHKw(w)) { +#ifdef USE_X_COLHDR + if (!CHKw(w, Show_HIROWS)) +#else if (!CHKw(w, Show_HICOLS | Show_HIROWS)) +#endif show_msg("\aNothing to highlight!"); else { TOGw(w, Show_HIBOLD); @@ -2775,7 +2844,7 @@ static void keys_window (int ch) { break; case 'G': if (ALTCHKw) { - char tmp[ASKBUFSIZ]; + char tmp[SMLBUFSIZ]; STRLCPY(tmp, linein(fmtmk("Rename window '%s' to (1-3 chars)", w->rc.winname))) if (tmp[0]) win_names(w, tmp); } @@ -2786,6 +2855,14 @@ static void keys_window (int ch) { case kbd_DOWN: if (VIZCHKw(w)) if (w->begtask < Frame_maxtask - 1) w->begtask += 1; break; +#ifdef USE_X_COLHDR + case kbd_LEFT: + if (VIZCHKw(w)) if (0 < w->begpflg) w->begpflg -= 1; + break; + case kbd_RIGHT: + if (VIZCHKw(w)) if (w->begpflg + 1 < w->totpflgs) w->begpflg += 1; + break; +#else case kbd_LEFT: if (VIZCHKw(w)) if (0 < w->begpflg) { w->begpflg -= 1; @@ -2799,6 +2876,7 @@ static void keys_window (int ch) { else w->begpflg += 1; } break; +#endif case kbd_PGUP: if (VIZCHKw(w)) if (0 < w->begtask) { w->begtask -= (w->winlines - 1); @@ -2890,13 +2968,13 @@ static void do_key (int ch) { return; case 'q': // no return from this guy bye_bye(NULL); - case '?': - case 'h': // no need for rebuilds - help_view(); - return; case 'W': // no need for rebuilds file_writerc(); return; + case '?': // might need rebuilds, + case 'h': // if curwin is changed + help_view(); + break; case kbd_ENTER: // these two will have the effect of waking us case kbd_SPACE: // from 'select()' then refreshing the display break; @@ -3032,7 +3110,7 @@ static proc_t **summary_show (void) { Msg_row += 1; } else { int i; - char tmp[SMLBUFSIZ]; + char tmp[MEDBUFSIZ]; // display each cpu's states separately, screen height permitting... for (i = 0; i < Cpu_tot; i++) { snprintf(tmp, sizeof(tmp), "Cpu%-3d:", smpcpu[i].id); @@ -3075,7 +3153,7 @@ static void task_show (const WIN_t *q, const proc_t *p) { procs_refresh, that's the most frequent and costly part of top's job ! */ #define makeCOL(va...) snprintf(cbuf, sizeof(cbuf), f, ## va) #define pages2K(n) (unsigned long)( (n) << Pg2K_shft ) - char rbuf[ROWBUFSIZ], *rp; + char rbuf[ROWMINSIZ], *rp; int j, x; // we must begin a row with a possible window number in mind... @@ -3083,13 +3161,14 @@ static void task_show (const WIN_t *q, const proc_t *p) { if (Rc.mode_altscr) rp = scat(rp, " "); for (x = 0; x < q->maxpflgs; x++) { - char cbuf[ROWBUFSIZ]; + char cbuf[SCREENMAX]; FLG_t i = q->procflgs[x]; // support for our field/column const char *f = Fieldstab[i].fmts; // macro AND sometimes the fmt int s = Fieldstab[i].scale; // string must be altered ! int w = Fieldstab[i].width; switch (i) { +#ifndef USE_X_COLHDR // these 2 aren't real procflgs, they're used in column highlighting! case X_XON: case X_XOF: @@ -3098,8 +3177,9 @@ static void task_show (const WIN_t *q, const proc_t *p) { if (!('R' == p->state && CHKw(q, Show_HIROWS))) rp = scat(rp, X_XON == i ? q->capclr_rowhigh : q->capclr_rownorm); continue; +#endif case P_CMD: - { char tmp[ROWBUFSIZ]; + { char tmp[SCREENMAX]; unsigned flags; int whackable_int = q->maxcmdln; if (CHKw(q, Show_CMDLIN)) flags = ESC_DEFUNCT | ESC_BRACKETS | ESC_ARGS; @@ -3115,7 +3195,7 @@ static void task_show (const WIN_t *q, const proc_t *p) { makeCOL(p->processor); break; case P_CPU: - { float u = CPU_USED(p); + { float u = (float)p->pcpu * Frame_etscale; if (u > Cpu_pmax) u = Cpu_pmax; makeCOL(u); } @@ -3152,6 +3232,14 @@ static void task_show (const WIN_t *q, const proc_t *p) { case P_NCE: makeCOL((int)p->nice); break; +#ifdef ZAP_SUSEONLY + case P_OOA: + makeCOL((int)p->oom_adj); + break; + case P_OOM: + makeCOL((long)p->oom_score); + break; +#endif case P_PGD: makeCOL(p->pgrp); break; @@ -3259,7 +3347,7 @@ static int window_show (proc_t **ppt, WIN_t *q, int wmax) { /* the isBUSY macro determines if a task is 'active' -- it returns true if some cpu was used since the last sample. ( actual 'running' tasks will be a subset of those selected ) */ - #define isBUSY(x) (0 < CPU_USED(x)) + #define isBUSY(x) (0 < x->pcpu) #define winMIN(a,b) ((a < b) ? a : b) int i, lwin; @@ -3425,7 +3513,6 @@ int main (int dont_care_argc, char **argv) { for (;;) { struct timeval tv; - fd_set fs; frame_make(); @@ -3439,6 +3526,8 @@ int main (int dont_care_argc, char **argv) { if (Batch) select(0, NULL, NULL, NULL, &tv); else { + fd_set fs; + FD_ZERO(&fs); FD_SET(STDIN_FILENO, &fs); if (0 < select(STDIN_FILENO + 1, &fs, NULL, NULL, &tv)) diff --git a/top.h b/top.h index e3fb3076..defd7561 100644 --- a/top.h +++ b/top.h @@ -20,8 +20,8 @@ #define _Itop /* Development/Debugging defines ----------------------------------- */ -//#define ATEOJ_HSHRPT /* report on hash specifics, at end-of-job */ -//#define ATEOJ_STDRPT /* report a bunch of stuff, at end-of-job */ +//#define ATEOJ_RPTHSH /* report on hash specifics, at end-of-job */ +//#define ATEOJ_RPTSTD /* report on misc stuff, at end-of-job */ //#define CASEUP_HEXES /* show any hex values in upper case */ //#define CASEUP_SUFIX /* show time/mem/cnts suffix in upper case */ //#define EQUCOLHDRYES /* yes, do equalize column header lengths */ @@ -37,6 +37,20 @@ //#define STRCMPNOCASE /* use strcasecmp vs. strcmp when sorting */ //#define TERMIOS_ONLY /* just limp along with native input only */ //#define TTYGETENVYES /* environ vars can override tty col/row */ +//#define USE_X_COLHDR /* emphasize header vs. whole col, for 'x' */ +//#define ZAP_SUSEONLY /* enable the SuSE specific modifications */ + + +/*###### Notes, etc. ###################################################*/ + + /* The following conventions are used to identify areas where + adaptations for hotplugging are to be found ... + *** hotplug_cpu_acclimated *** + *** hotplug_mem_acclimated *** + ( hopefully libproc will also be supportive of our efforts ) */ + + /* And there are still some of these lurking here and there... + FIXME - blah, blah... */ #ifdef PRETEND2_5_X @@ -49,17 +63,14 @@ #define STRSORTCMP strcmp #endif - -/*###### Notes #########################################################*/ - - /* The following conventions are used to identify areas where - adaptations for hotplugging are to be found ... - *** hotplug_cpu_acclimated *** - *** hotplug_mem_acclimated *** - ( hopefully libproc will also be supportive of our efforts ) */ - - /* And there are still some of these lurking here and there... - FIXME - blah, blah... */ +#ifdef ZAP_SUSEONLY + /* FIXME: perhaps making this a function in the suse version of + sysinfo.c was a prelude to hotpluggable updates -- unfortunately, + the return value is invariant as currently implemented! */ +#define SMP_NUM_CPUS smp_num_cpus() +#else +#define SMP_NUM_CPUS smp_num_cpus +#endif /*###### Some Miscellaneous constants ##################################*/ @@ -78,24 +89,23 @@ #ifdef RESIZE_LIMIT #define SCRCOLMIN 16 #define SCRROWMIN 8 -#else -#define SCRROWMIN 1 #endif #define SCREENMAX 512 /* the above might seem pretty stingy, until you consider that with every one of top's fields displayed it's less than 200 bytes of column header -- so SCREENMAX provides for all fields plus a 300+ byte command line */ #define CAPBUFSIZ 32 -#define ASKBUFSIZ 32 #define CLRBUFSIZ 64 #define PFLAGSSIZ 64 -#define SMLBUFSIZ 64 +#define SMLBUFSIZ 128 #define MEDBUFSIZ 256 +#define LRGBUFSIZ 512 #define OURPATHSZ 1024 #define BIGBUFSIZ 2048 - // in addition to the actual display data, our row might have to accomodate - // many termcap/color transitions - this ensures we'll have room for both */ -#define ROWBUFSIZ SCREENMAX * 2 + /* in addition to the actual display data, our row might have to accomodate + many termcap/color transitions - these definitions ensure we have room */ +#define ROWMINSIZ ( SCREENMAX + 4 * (CAPBUFSIZ + CLRBUFSIZ) ) +#define ROWMAXSIZ ( SCREENMAX + 16 * (CAPBUFSIZ + CLRBUFSIZ) ) // support for keyboard stuff (cursor motion keystrokes, mostly) #define kbd_ENTER '\n' @@ -127,8 +137,16 @@ enum pflag { P_MEM, P_VRT, P_SWP, P_RES, P_COD, P_DAT, P_SHR, P_FL1, P_FL2, P_DRT, P_STA, P_CMD, P_WCH, P_FLG, +#ifdef ZAP_SUSEONLY + P_OOA, P_OOM, +#endif +#ifdef USE_X_COLHDR + // not really pflags, used with tbl indexing + P_MAXPFLGS +#else // not really pflags, used with tbl indexing & col highlighting P_MAXPFLGS, X_XON, X_XOF +#endif }; /* The scaling 'type' used with scale_num() -- this is how @@ -216,7 +234,7 @@ typedef struct CPU_t { // 'Show_' & 'Qsrt_' flags are for task display in a visible window #define Show_COLORS 0x000800 // 'z' - show in color (vs. mono) #define Show_HIBOLD 0x000400 // 'b' - rows and/or cols bold (vs. reverse) -#define Show_HICOLS 0x000200 // 'x' - show sort column highlighted +#define Show_HICOLS 0x000200 // 'x' - show sort column emphasized #define Show_HIROWS 0x000100 // 'y' - show running tasks highlighted #define Show_CMDLIN 0x000080 // 'c' - show cmdline vs. name #define Show_CTIMES 0x000040 // 'S' - show times as cumulative @@ -288,7 +306,14 @@ typedef struct WIN_t { int usrseluid, // validated uid for 'u/U' select usrseltyp; // basis for matching above uid char grpname [GRPNAMSIZ], // window number:name, printable +#ifdef USE_X_COLHDR + columnhdr [ROWMINSIZ]; // column headings for procflgs +#ifdef EQUCOLHDRYES + int hdrcaplen; // xtra length of caps strings +#endif +#else columnhdr [SCREENMAX]; // column headings for procflgs +#endif char *captab [CAPTABMAX]; // captab needed by show_special() struct WIN_t *next, // next window in window stack *prev; // prior window in window stack @@ -322,11 +347,8 @@ typedef struct WIN_t { ( and assuming callers don't need the string length returned ) */ #define STRLCPY(dst,src) { strncpy(dst, src, sizeof(dst)); dst[sizeof(dst) - 1] = '\0'; } - /* Used by task_show() and window_show() to calculate CPU % used */ -#define CPU_USED(p) ((float)p->pcpu * Frame_etscale) - /* Used to clear all or part of our Pseudo_screen */ -#define PSU_CLREOS(y) memset(&Pseudo_screen[ROWBUFSIZ*y], '\0', Pseudo_size-(ROWBUFSIZ*y)) +#define PSU_CLREOS(y) memset(&Pseudo_screen[ROWMAXSIZ*y], '\0', Pseudo_size-(ROWMAXSIZ*y)) /* Used as return arguments in *some* of the sort callbacks */ #define SORT_lt ( Frame_srtflg > 0 ? 1 : -1 ) @@ -364,7 +386,7 @@ typedef struct WIN_t { . may contain ANY valid terminfo escape sequences . need NOT represent an entire screen row */ #define PUTT(fmt,arg...) do { \ - char _str[ROWBUFSIZ]; \ + char _str[ROWMAXSIZ]; \ snprintf(_str, sizeof(_str), fmt, ## arg); \ putp(_str); \ } while (0) @@ -375,11 +397,11 @@ typedef struct WIN_t { . assumed to represent a complete screen ROW . subject to optimization, thus MAY be discarded */ #define PUFF(fmt,arg...) do { \ - char _str[ROWBUFSIZ]; \ + char _str[ROWMAXSIZ]; \ snprintf(_str, sizeof(_str), fmt, ## arg); \ if (Batch) putp(_str); \ else { \ - char *_ptr = &Pseudo_screen[Pseudo_row * ROWBUFSIZ]; \ + char *_ptr = &Pseudo_screen[Pseudo_row * ROWMAXSIZ]; \ if (Pseudo_row + 1 < Screen_rows) ++Pseudo_row; \ if (!strcmp(_ptr, _str)) putp("\n"); \ else { \ @@ -501,6 +523,10 @@ typedef struct WIN_t { " 'd' or toggles display, 's' sets sort. Use 'q' or to end! " \ "" +#ifdef ZAP_SUSEONLY + /* w/ 2 extra lines, no room for additional text on 24x80 terminal */ +#define FIELDS_notes NULL +#else /* Extra explanatory text which could accompany the Fields display. note: the newlines cannot actually be used, they just serve as substring delimiters for the 'display_fields' routine. */ @@ -512,6 +538,7 @@ typedef struct WIN_t { /* no room in FIELDS_notes, sacrificed w/ 35 fields displayed .... */ /* " If a sort field is not displayed,\n" */ /* " the '<' & '>' keys are inactive.\n" */ +#endif #define FIELDS_flags \ "Flags field:\n" \ @@ -595,9 +622,13 @@ typedef struct WIN_t { /*###### For Piece of mind #############################################*/ /* just sanity check(s)... */ -#if defined(ATEOJ_HSHRPT) && defined(OFF_HST_HASH) -# error "Hey, 'ATEOJ_HSHRPT' conflicts with 'OFF_HST_HASH'" +#if defined(ATEOJ_RPTHSH) && defined(OFF_HST_HASH) +# error 'ATEOJ_RPTHSH' conflicts with 'OFF_HST_HASH' #endif +#if defined(PRETEND4CPUS) && defined (ZAP_SUSEONLY) +# error 'PRETEND4CPUS' conflicts with 'ZAP_SUSEONLY' +#endif + /*###### Some Prototypes (ha!) #########################################*/