Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

346 lines
9.7 KiB
C

static char sccsid[] = "@(#)94 1.15 src/bos/kernel/db/POWER/thread.c, sysdb, bos41J, 9512A_all 3/20/95 15:02:55";
/*
* COMPONENT_NAME: (SYSDB) Kernel Debugger
*
* FUNCTIONS: pr_thread, disp_thread, print_t_flags
*
* ORIGINS: 27, 83
*
*
* IBM CONFIDENTIAL -- (IBM Confidential Restricted when
* combined with the aggregated modules for this product)
* SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1993, 1995
* All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
/*
* LEVEL 1, 5 Years Bull Confidential Information
*/
#ifdef _THREADS
#include <sys/types.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/pri.h>
#include <sys/buf.h>
#include <sys/systm.h>
#include <sys/sched.h>
#include "debaddr.h" /* Address structure */
#include "parse.h" /* Parser structure. */
#include "pr_proc.h" /* declares for this file */
#include "debvars.h" /* for addressing seg reg */
#define DEF_STORAGE 1
#include "add_cmd.h" /* shared buf for cntrl blk display */
/*
* EXTERNAL PROCEDURES CALLED:
*/
extern struct user *read_uarea(); /* copys the uarea into a buffer */
extern int debpg(); /* prompt user to continue */
extern ulong g_kxsrval; /* kernel extension seg reg value */
/*
* NAME: pr_thread
*
* FUNCTION: Provide a formatted display of Thread Table area.
* If user has supplied a PID (in arg1) print only
* slots of threads belonging to that process.
* If user has supplied a TID (in arg1) print a long
* listing of only that slot.
*
* RETURN VALUE: none.
*/
void
pr_thread(ps)
struct parse_out *ps;
{
register int i,screen;
struct thread *tb = (struct thread *) (cbbuf + sizeof(struct user));
/* above leaves space for read_uarea to use buffer */
int mode = 0;
clrdsp(); /* clear the screen */
#ifdef Debug
jr_debug();
#endif /* Debug */
if ((ps->num_tok > 0) && (ps->token[1].tflags & HEX_VALID))
/* if argument is a tid, then this is a long listing */
if (MAYBE_TID(ps->token[1].hv)) {
mode = 2;
printf(" ST TID PID CPUID POLICY PRI CPU");
}
/* if argument is a pid, then this is a restricted listing */
else {
mode = 1;
printf("SLT ST TID PID CPUID POLICY PRI CPU");
}
else
/* if there is no valid argument, then this is a short listing */
printf("SLT ST TID PID CPUID POLICY PRI CPU");
/* print the rest of the header */
printf(" EVENT PROCNAME FLAGS\n");
/* Loop retrieving each thread table slot and printing it */
screen = 1;
for(i=0;i<NTHREAD;i++) {
if(!pre_get_put_data(&thread[i], 0/*read*/, (char *)tb,
g_kxsrval, VIRT, sizeof(struct thread))){
#ifdef Debug
printf("Rest of Thread Table paged out.\n");
#endif /* Debug */
return;
}
#ifdef Debug
if(DBG_LVL)
printf("&thread[%d]=0x%x \n",i,&thread[i]);
#endif /* Debug */
switch(mode) {
case 2 :
/* print out single slot, long listing */
if(ps->token[1].hv==tb->t_tid) {
disp_thread(tb,-1);
return;
}
break;
case 1 :
/* or print out only slots belonging to a process */
if(tb->t_state!=TSNONE)
if(ps->token[1].hv==tb->t_procp->p_pid) {
disp_thread(tb,i);
/* give user one screen at a time */
if(!(screen++%20))
if(debpg() == FALSE)
return;
}
break;
case 0 :
/* or print out all slots */
if(tb->t_state!=TSNONE) {
disp_thread(tb,i);
/* give user one screen at a time */
if(!(screen++%20))
if(debpg() == FALSE)
return;
}
break;
}
}
}
/*
* Function: Print a thread table slot. If slot = -1 print long
* listing of that slot.
*
* Returns: nothing.
*/
disp_thread(t,slot)
struct thread *t; /* thread table pointer */
{
char *cp;
int i,paged;
struct user *user_area;
#ifdef RunFlag
if(run && t->t_state != TSRUN)
return;
#endif
switch(t->t_state) {
case TSNONE: cp = " "; break;
case TSIDL: cp = "i"; break;
case TSRUN: cp = "r"; break;
case TSSLEEP: cp = "s"; break;
case TSSWAP: cp = "o"; break;
case TSSTOP: cp = "t"; break;
case TSZOMB: cp = "z"; break;
default: cp = "?"; break;
}
if(slot == -1)
printf(" %s", cp);
else
printf("%3d%s%s", slot,
curthread->t_tid == t->t_tid ? "*" : " ", cp);
printf(" %8x %8x ", t->t_tid, t->t_procp->p_pid);
if (t->t_cpuid == PROCESSOR_CLASS_ANY)
printf(" ANY ");
else
printf("%4x ", t->t_cpuid);
switch(t->t_policy) {
case SCHED_OTHER: printf(" OTHER"); break;
case SCHED_FIFO: printf(" FIFO"); break;
case SCHED_RR: printf("RD-ROB"); break;
default: printf(" ?"); break;
}
printf(" %3x %3x", t->t_pri & PMASK,
(t->t_cpu < T_CPU_MAX) ? t->t_cpu : T_CPU_MAX);
t->t_wchan == 0 ? printf(" ") : printf(" %08x", t->t_wchan);
/* Get command name */
if(t->t_procp->p_stat == SNONE)
cp = " ";
else if(t->t_procp->p_stat == SZOMB)
cp = "ZOMBIE";
else if(!t->t_procp->p_pid) /* pid 0 is swapper */
cp = "swapper";
else {
/* copy the uarea using Get_from_memory() */
if((int)(user_area=read_uarea(t->t_procp->p_adspace,&paged))<0)
cp = "<unknown>";
else
cp = user_area->U_comm;
}
if(!t->t_procp->p_pid) /* just to make it all fit on 1 line */
printf(" %s ", cp);
else
printf(" %s ", cp);
printf(" 0x%08x\n",t->t_flags); /* now print t_flags */
/* end of short (whole thread table) listing */
if(slot != -1)
return;
/* else do a long listing */
/* Main thread link pointers */
printf("\nLinks: *procp:0x%08x *uthreadp:0x%08x *userp:0x%08x\n",
t->t_procp, t->t_uthreadp, t->t_userp);
printf(" *prevthread:0x%08x *nextthread:0x%08x\n",
t->t_prevthread, t->t_nextthread);
printf(" *wchan1(real):0x%08x *wchan2(VMM):0x%08x\n",
t->t_wchan1,t->t_wchan2);
printf(" wchan1sid:0x%08x wchan1offset:0x%08x\n",
t->t_wchan1sid,t->t_wchan1offset);
printf(" *slist:0x%08x *swchan:0x%08x \n",
t->t_slist,t->t_swchan);
/* Dispatch fields */
printf("Dispatch Fields: *prior:0x%08x *next:0x%08x\n",
t->t_prior,t->t_next);
printf(" polevel:0x%08x ticks:0x%04x *synch:0x%08x result:0x%08x\n",
t->t_polevel, t->t_ticks, t->t_synch, t->t_result);
printf(" *eventlst:0x%08x *wchan(hashed):0x%08x suspend:0x%04x\n",
t->t_eventlist,t->t_wchan,t->t_suspend);
printf(" t_wevent:0x%08x t_pevent:0x%08x",t->t_wevent, t->t_pevent);
printf(" thread waiting for: %s%s%s%s%s%s%s%s%s%s%s%s\n",
/* be sure number of "%s" entries */
/* matches number of expressions below */
t->t_wtype == TNOWAIT ? " nothing " : "",
t->t_wtype == TWEVENT ? " event(s) " : "",
t->t_wtype == TWLOCK ? " serial lock " : "",
t->t_wtype == TWLOCKREAD ? " serial read lock " : "",
t->t_wtype == TWTIMER ? " timer " : "",
t->t_wtype == TWCPU ? " cpu (ready) " : "",
t->t_wtype == TWPGIN ? " page in " : "",
t->t_wtype == TWPGOUT ? "page out" : "",
t->t_wtype == TWPLOCK ? " physical lock " : "",
t->t_wtype == TWFREEF ? " free page frame " : "",
t->t_wtype == TWMEM ? " memory " : "",
t->t_wtype == TWUEXCEPT ? " user exception " : "");
/* Scheduler info */
printf("Scheduler Fields: cpuid:");
if (t->t_cpuid == PROCESSOR_CLASS_ANY)
printf(" ANY");
else
printf("0x%04x", t->t_cpuid);
printf(" scpuid:");
if (t->t_scpuid == PROCESSOR_CLASS_ANY)
printf(" ANY");
else
printf("0x%04x", t->t_scpuid);
printf(" pri:%3u", t->t_pri);
printf(" sav_pri:%3u\n", t->t_sav_pri);
printf(" policy:");
switch(t->t_policy) {
case SCHED_OTHER: printf(" OTHER"); break;
case SCHED_FIFO: printf(" FIFO"); break;
case SCHED_RR: printf("RD-ROB"); break;
default: printf(" ?"); break;
}
printf(" lpri:%3u wpri:%3u", t->t_lockpri, t->t_wakepri);
printf(" time:0x%02x\n", t->t_time);
/* Misc */
printf("Misc: t_lockcount:0x%08x t_ulock:0x%08x\n",
t->t_lockcount, t->t_ulock);
printf(" t_dispct:0x%08x t_fpuct:0x%08x t_graphics:0x%08x\n",
t->t_dispct, t->t_fpuct, t->t_graphics);
printf(" t_stackp:0x%08x t_boosted:0x%08x t_lockowner:0x%08x\n",
t->t_stackp, t->t_boosted, t->t_lockowner);
/* Signal Fields */
printf("Signal Information: cursig:0x%02x\n", t->t_cursig);
printf(" pending:hi 0x%08x,lo 0x%08x sigmask:hi 0x%08x,lo 0x%08x\n",
t->t_sig.hisigs, t->t_sig.losigs,
t->t_sigmask.hisigs, t->t_sigmask.losigs);
printf(" *scp: 0x%08x\n", t->t_scp);
print_t_flags(t);
} /* end disp_thread */
print_t_flags(t)
struct thread *t;
{
unsigned int flags;
flags = t->t_flags;
printf(" t_flags:");
if (flags & TTERM) printf(" TERM");
if (flags & TSUSP) printf(" SUSP");
if (flags & TSIGAVAIL) printf(" SIGAVAIL");
flags &= ~(TTERM | TSUSP | TSIGAVAIL);
if (flags & TLOCAL) printf(" LOCAL");
if (flags & TASSERTSIG) printf(" ASSERTSIG");
if (flags & TTRCSIG) printf(" TRCSIG");
flags &= ~(TLOCAL | TASSERTSIG | TTRCSIG );
if (flags & TOMASK) printf(" OMASK");
if (flags & TWAKEONSIG) printf(" WAKEONSIG");
flags &= ~(TOMASK | TWAKEONSIG);
if (flags & TKTHREAD) printf (" KTHREAD");
if (flags & TFUNNELLED) printf (" FUNNELLED");
if (flags & TSETSTATE) printf(" SETSTATE");
flags &= ~(TKTHREAD | TFUNNELLED | TSETSTATE );
if (flags & TPMSTOP) printf (" PMSTOP");
if (flags & TPMREQSTOP) printf (" PMREQSTOP");
if (flags & TBOOSTING) printf (" BOOSTING");
flags &= ~(TPMSTOP | TPMREQSTOP | TBOOSTING);
if (flags) printf(" unknown: 0x%x",flags);
printf("\n");
flags = t->t_atomic;
printf(" t_atomic:");
if (flags & TSIGDELIVERY) printf(" SIGDELIVERY");
if (flags & TSELECT) printf(" SELECT");
flags &= ~(TSIGDELIVERY | TSELECT );
if (flags) printf(" unknown: 0x%x",flags);
printf("\n");
}
#endif