summaryrefslogtreecommitdiff
path: root/libps
diff options
context:
space:
mode:
Diffstat (limited to 'libps')
-rw-r--r--libps/spec.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/libps/spec.c b/libps/spec.c
index 626e0e7d..7d62313f 100644
--- a/libps/spec.c
+++ b/libps/spec.c
@@ -640,23 +640,42 @@ ps_emit_tty_name(proc_stat_t ps, ps_getter_t getter,
return ps_write_field(name, width, stream, count);
}
+struct state_shadow
+{
+ /* If any states in STATES are set, the states in shadow are suppressed. */
+ int states;
+ int shadow;
+};
+
+struct state_shadow state_shadows[] = {
+ /* Don't show sleeping thread if one is running, or the process is stopped.*/
+ { PSTAT_STATE_T_RUN | PSTAT_STATE_P_STOP,
+ PSTAT_STATE_T_SLEEP | PSTAT_STATE_T_IDLE | PSTAT_STATE_T_WAIT },
+ /* Only show the longest sleep. */
+ { PSTAT_STATE_T_IDLE, PSTAT_STATE_T_SLEEP | PSTAT_STATE_T_WAIT },
+ { PSTAT_STATE_T_SLEEP, PSTAT_STATE_T_WAIT },
+ /* Turn off the per-thread stop bits when the process is stopped, as
+ they're expected. */
+ { PSTAT_STATE_P_STOP, PSTAT_STATE_T_HALT | PSTAT_STATE_T_UNCLEAN },
+ { 0 }
+};
+
error_t
ps_emit_state(proc_stat_t ps, ps_getter_t getter,
int width, FILE *stream, unsigned *count)
{
char *tags;
- int state = G(getter, int)(ps);
+ int raw_state = G(getter, int)(ps);
+ int state = raw_state;
char buf[20], *p = buf;
+ struct state_shadow *shadow = state_shadows;
- /* turn off seemingly bogus or annoying flags */
- state &= ~PSTAT_STATE_SWAPPED;
-
- /* If any thread is running, don't mention sleeping or idle threads --
- presumably *some* work is getting done... */
- if (state & (PSTAT_STATE_RUNNING | PSTAT_STATE_STOPPED))
- state &= ~(PSTAT_STATE_SLEEPING | PSTAT_STATE_IDLE);
- if (state & PSTAT_STATE_IDLE)
- state &= ~PSTAT_STATE_SLEEPING;
+ while (shadow->states)
+ {
+ if (raw_state & shadow->states)
+ state &= ~shadow->shadow;
+ shadow++;
+ }
for (tags = proc_stat_state_tags
; state != 0 && *tags != '\0'