FreeBSD/sys/kern/tty_info.c
/*
 * Report on state of foreground process group.
 */
Report on state of foreground process group.
Report on state of foreground process group .
void
tty_info(struct tty *tp)
{
	struct timeval rtime, utime, stime;
	struct proc *p, *ppick;
	struct thread *td, *tdpick;
	const char *stateprefix, *state;
	long rss;
	int load, pctcpu;
	pid_t pid;
	char comm[MAXCOMLEN + 1];
	struct rusage ru;
	tty_lock_assert(tp, MA_OWNED);
	if (tty_checkoutq(tp) == 0)
		return;
	load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
	ttyprintf(tp, "%sload: %d.%02d ", tp->t_column == 0 ? "" : "\n",
	    load / 100, load % 100);
	if (tp->t_session == NULL) {
		ttyprintf(tp, "not a controlling terminal\n");
		return;
	}
	if (tp->t_pgrp == NULL) {
		ttyprintf(tp, "no foreground process group\n");
		return;
	}
	PGRP_LOCK(tp->t_pgrp);
	if (LIST_EMPTY(&tp->t_pgrp->pg_members)) {
		PGRP_UNLOCK(tp->t_pgrp);
		ttyprintf(tp, "empty foreground process group\n");
		return;
	}
	p = NULL;
	LIST_FOREACH(ppick, &tp->t_pgrp->pg_members, p_pglist)
		if (proc_compare(p, ppick))
			p = ppick;
	PROC_LOCK(p);
	PGRP_UNLOCK(tp->t_pgrp);
	td = NULL;
	FOREACH_THREAD_IN_PROC(p, tdpick)
		if (thread_compare(td, tdpick))
			td = tdpick;
	stateprefix = "";
	thread_lock(td);
	if (TD_IS_RUNNING(td))
		state = "running";
	else if (TD_ON_RUNQ(td) || TD_CAN_RUN(td))
		state = "runnable";
	else if (TD_IS_SLEEPING(td)) {
		if (TD_ON_SLEEPQ(td))
			state = td->td_wmesg;
		else
			state = "sleeping without queue";
	} else if (TD_ON_LOCK(td)) {
		state = td->td_lockname;
		stateprefix = "*";
	} else if (TD_IS_SUSPENDED(td))
		state = "suspended";
	else if (TD_AWAITING_INTR(td))
		state = "intrwait";
	else if (p->p_state == PRS_ZOMBIE)
		state = "zombie";
	else
		state = "unknown";
	pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT;
	thread_unlock(td);
	if (p->p_state == PRS_NEW || p->p_state == PRS_ZOMBIE)
		rss = 0;
	else
		rss = pgtok(vmspace_resident_count(p->p_vmspace));
	microuptime(&rtime);
	timevalsub(&rtime, &p->p_stats->p_start);
	rufetchcalc(p, &ru, &utime, &stime);
	pid = p->p_pid;
	strlcpy(comm, p->p_comm, sizeof comm);
	PROC_UNLOCK(p);
	ttyprintf(tp,
	    " cmd: %s %d [%s%s] %ld.%02ldr %ld.%02ldu %ld.%02lds %d%% %ldk\n",
	    comm, pid, stateprefix, state,
	    (long)rtime.tv_sec, rtime.tv_usec / 10000,
	    (long)utime.tv_sec, utime.tv_usec / 10000,
	    (long)stime.tv_sec, stime.tv_usec / 10000,
	    pctcpu / 100, rss);
}
void tty_info ( struct tty * tp ) { struct timeval rtime , utime , stime ; struct proc * p , * ppick ; struct thread * td , * tdpick ; const char * stateprefix , * state ; long rss ; int load , pctcpu ; pid_t pid ; char comm [ MAXCOMLEN + 1 ] ; struct rusage ru ; tty_lock_assert ( tp , MA_OWNED ) ; if ( tty_checkoutq ( tp ) == 0 ) return ; load = ( averunnable . ldavg [ 0 ] * 100 + FSCALE / 2 ) >> FSHIFT ; ttyprintf ( tp , " " , tp -> t_column == 0 ? " " : " \n " , load / 100 , load % 100 ) ; if ( tp -> t_session == NULL ) { ttyprintf ( tp , " \n " ) ; return ; } if ( tp -> t_pgrp == NULL ) { ttyprintf ( tp , " \n " ) ; return ; } PGRP_LOCK ( tp -> t_pgrp ) ; if ( LIST_EMPTY ( & tp -> t_pgrp -> pg_members ) ) { PGRP_UNLOCK ( tp -> t_pgrp ) ; ttyprintf ( tp , " \n " ) ; return ; } p = NULL ; LIST_FOREACH ( ppick , & tp -> t_pgrp -> pg_members , p_pglist ) if ( proc_compare ( p , ppick ) ) p = ppick ; PROC_LOCK ( p ) ; PGRP_UNLOCK ( tp -> t_pgrp ) ; td = NULL ; FOREACH_THREAD_IN_PROC ( p , tdpick ) if ( thread_compare ( td , tdpick ) ) td = tdpick ; stateprefix = " " ; thread_lock ( td ) ; if ( TD_IS_RUNNING ( td ) ) state = " " ; else if ( TD_ON_RUNQ ( td ) || TD_CAN_RUN ( td ) ) state = " " ; else if ( TD_IS_SLEEPING ( td ) ) { if ( TD_ON_SLEEPQ ( td ) ) state = td -> td_wmesg ; else state = " " ; } else if ( TD_ON_LOCK ( td ) ) { state = td -> td_lockname ; stateprefix = " " ; } else if ( TD_IS_SUSPENDED ( td ) ) state = " " ; else if ( TD_AWAITING_INTR ( td ) ) state = " " ; else if ( p -> p_state == PRS_ZOMBIE ) state = " " ; else state = " " ; pctcpu = ( sched_pctcpu ( td ) * 10000 + FSCALE / 2 ) >> FSHIFT ; thread_unlock ( td ) ; if ( p -> p_state == PRS_NEW || p -> p_state == PRS_ZOMBIE ) rss = 0 ; else rss = pgtok ( vmspace_resident_count ( p -> p_vmspace ) ) ; microuptime ( & rtime ) ; timevalsub ( & rtime , & p -> p_stats -> p_start ) ; rufetchcalc ( p , & ru , & utime , & stime ) ; pid = p -> p_pid ; strlcpy ( comm , p -> p_comm , sizeof comm ) ; PROC_UNLOCK ( p ) ; ttyprintf ( tp , " \n " , comm , pid , stateprefix , state , ( long ) rtime . tv_sec , rtime . tv_usec / 10000 , ( long ) utime . tv_sec , utime . tv_usec / 10000 , ( long ) stime . tv_sec , stime . tv_usec / 10000 , pctcpu / 100 , rss ) ; }
Report on state of foreground process group.
Report on state of foreground process group .
/* Print load average. */ /*
	 * Pick the most interesting process and copy some of its
	 * state for printing later.  This operation could rely on stale
	 * data as we can't hold the proc slock or thread locks over the
	 * whole list. However, we're guaranteed not to reference an exited
	 * thread or proc since we hold the tty locked.
	 */ /* XXX: If we're sleeping, are we ever not in a queue? */ /* Print command, pid, state, rtime, utime, stime, %cpu, and rss. */