I am using htop on osx and I can't seem to find out what a 'C' status in the 'S' status column means for a process status.
What does a C process status mean in htop?
I am using htop on osx and I can't seem to find out what a 'C' status in the 'S' status column means for a process status.
What does a C process status mean in htop?
htop author here. I am not aware of such status code in the htop codebase. Keep in mind that htop is written for Linux only, so there is no support for macOS/OSX. When I hear of people running it on OSX they are often using an outdated, unsupported fork (the latest version of htop is 2.0.1, including macOS support).
Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a process:
Source: man ps
I've got the same question recently. We can try to look it up in the htop sources:
process->state =
ProcessList_decodeState( p->p_stat == SZOMB ? SZOMB : ki->state );
static int
ProcessList_decodeState( int st ) {
switch ( st ) {
case SIDL:
return 'C';
case SRUN:
return 'R';
case SSLEEP:
return 'S';
case SSTOP:
return 'T';
case SZOMB:
return 'Z';
default:
return '?';
}
}
So we go to Unix definition of process states at /usr/include/sys/proc.h:
/* Status values. */
#define SIDL 1 /* Process being created by fork. */
#define SRUN 2 /* Currently runnable. */
#define SSLEEP 3 /* Sleeping on an address. */
#define SSTOP 4 /* Process debugging or suspension. */
#define SZOMB 5 /* Awaiting collection by parent. */
So, 'C' status is meant to be 'Process being created by fork'. What is it? According to old unix sources, it's a transient state that happens when there's not enough memory when forking a process and the parent needs to be swapped out.
What??
Back to htop source. Where do we get the ki->state
?
// For all threads in process:
error = thread_info( ki->thread_list[j], THREAD_BASIC_INFO,
( thread_info_t ) & ki->thval[j].tb,
&thread_info_count );
tstate = ProcessList_machStateOrder( ki->thval[j].tb.run_state,
ki->thval[j].tb.sleep_time );
if ( tstate < ki->state )
ki->state = tstate;
// Below...
static int
ProcessList_machStateOrder( int s, long sleep_time ) {
switch ( s ) {
case TH_STATE_RUNNING:
return 1;
case TH_STATE_UNINTERRUPTIBLE:
return 2;
case TH_STATE_WAITING:
return ( sleep_time > 20 ) ? 4 : 3;
case TH_STATE_STOPPED:
return 5;
case TH_STATE_HALTED:
return 6;
default:
return 7;
}
}
// In mach/thread_info.h:
#define TH_STATE_RUNNING 1 /* thread is running normally */
#define TH_STATE_STOPPED 2 /* thread is stopped */
#define TH_STATE_WAITING 3 /* thread is waiting normally */
#define TH_STATE_UNINTERRUPTIBLE 4 /* thread is in an uninterruptible wait */
#define TH_STATE_HALTED 5 /* thread is halted at a clean point */
We have the following (messed up) mapping:
Thread state | Mapped to | htop state| 'top' state | 'ps' state
----------------------------------------------------------------------------
TH_STATE_RUNNING | SIDL(1) | 'C' | running | 'R'
TH_STATE_UNINTERRUPTIBLE | SRUN(2) | 'R' | stuck | 'U'
TH_STATE_WAITING (short) | SSLEEP(3) | 'S' | sleeping | 'S'
TH_STATE_WAITING (long) | SSTOP(4) | 'T' | idle | 'I'
TH_STATE_STOPPED | SZOMB(5) | 'Z' | stopped | 'T'
So, the real answer is: 'C' means that the process is currently running.
How did it happen? Seems that the ki->state
handling was borrowed from ps
source and wasn't adjusted for Unix process codes.
Update: this bug is fixed. Yay open source!