taskShow.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:21k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* taskShow.c - task show routines */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02e,27mar02,pai  Added code to display Streaming SIMD Registers (SPR 74103).
  8. 02d,16oct01,jn   use symFindSymbol for symbol lookup (SPR #7453)
  9. 02c,19nov01,aeg  added display of VxWorks events information.
  10. 02b,09nov01,dee  add CPU_FAMILY==COLDFIRE
  11. 02a,11oct01,cjj  removed Am29k support
  12. 01z,13jul01,kab  Cleanup for merge to mainline
  13. 01y,03apr01,kab  Added _WRS_ALTIVEC_SUPPORT
  14. 01x,14mar01,pcs  Added code to recognize VX_ALTIVEC_TASK.
  15. 01w,18dec00,pes  Correct compiler warnings
  16. 01w,03mar00,zl   merged SH support into T2
  17. 01v,17mar99,jdi  doc: updated w/ info about proj facility (SPR 25727).
  18. 01u,29jul96,jmb  Merged patch from ease (mem) for HPSIM
  19. 01t,24jun96,sbs  made windview instrumentation conditionally compiled
  20. 01s,06oct95,jdi  changed Debugging .pG's to .tG "Shell".
  21. 01r,14mar95,jdi  doc tweak for taskShow().
  22. 01q,11feb95,jdi  format repairs.
  23. 01p,04feb94,cd   taskRegsShow calls taskArchRegsShow for CPU_FAMILY==MIPS
  24.  retrofitted 01o history
  25. 01o,27dec93,cd   taskShow calls taskArchRegsShow for CPU_FAMILY==MIPS
  26. 01o,02dec93,pad  added AM29XXX family support.
  27. 01q,20jul94,ms   added taskRegShow() hook.
  28. 01p,03may94,ms   fixed low order PC bits in taskShow for VxSim HP
  29. 01o,20aug93,gae  fixed pcReg definition for vxsim on hppa.
  30. 01o,20sep94,rhp  doc: describe fields in taskShow() TCB display,
  31.                  result of taskStatusString() (SPR#2394).
  32. 01o,16jan94,c_s  taskShowInit () now initializes instrumented class.
  33. 01n,25feb93,jdi  doc: fixed example output of taskShow().
  34. 01m,04feb93,jdi  fixed mangen problem in taskShow().
  35. 01l,03feb93,jdi  amended library description.
  36. 01k,03feb93,jdi  changed INCLUDE_SHOW_RTNS to ...ROUTINES.
  37. 01j,02feb93,jdi  documentation tweak.
  38. 01i,25nov92,jdi  documentation cleanup.
  39. 01h,19aug92,smb  another tweak to the printf formatting.
  40. 01g,02aug92,jcf  added parameter to _func_excInfoShow.
  41. 01f,30jul92,smb  changed format for printf to avoid zero padding.
  42. 01e,28jul92,jcf  changed taskShowInit to call taskLibInit.
  43. 01d,27jul92,jcf  included errnoLib.h.
  44. 01c,12jul92,jcf  tuned register format string.
  45. 01b,08jul92,jwt  modified taskRegsFmt for CPU_FAMILY == SPARC.
  46. 01a,15jun92,jcf  extracted from v1k taskLib.c.
  47. */
  48. /*
  49. DESCRIPTION
  50. This library provides routines to show task-related information,
  51. such as register values, task status, etc.
  52. The taskShowInit() routine links the task show facility into the VxWorks
  53. system.  It is called automatically when this show facility is configured
  54. into VxWorks using either of the following methods:
  55. .iP
  56. If you use the configuration header files, define
  57. INCLUDE_SHOW_ROUTINES in config.h.
  58. .iP
  59. If you use the Tornado project facility, select INCLUDE_TASK_SHOW.
  60. .LP
  61. Task information is crucial as a debugging aid and user-interface
  62. convenience during the development cycle of an application.  The routines
  63. taskInfoGet(), taskShow(), taskRegsShow(), and taskStatusString() are used
  64. to display task information.
  65. The chief drawback of using task information is that tasks may
  66. change their state between the time the information is gathered and the
  67. time it is utilized.  Information provided by these routines should
  68. therefore be viewed as a snapshot of the system, and not relied upon
  69. unless the task is consigned to a known state, such as suspended.
  70. Task management and control routines are provided by taskLib.  Programmatic
  71. access to task information and debugging features is provided by taskInfo.
  72. INCLUDE FILES: taskLib.h
  73. SEE ALSO: taskLib, taskInfo, taskHookLib, taskVarLib, semLib, kernelLib,
  74. .pG "Basic OS, Target Shell,"
  75. .tG "Shell"
  76. */
  77. #include "vxWorks.h"
  78. #include "string.h"
  79. #include "regs.h"
  80. #include "stdio.h"
  81. #include "a_out.h"
  82. #include "sysSymTbl.h"
  83. #include "errnoLib.h"
  84. #include "taskArchLib.h"
  85. #include "intLib.h" /* intLock/intUnlock */
  86. #include "private/funcBindP.h"
  87. #include "private/taskLibP.h"
  88. #include "private/kernelLibP.h"
  89. #include "private/eventLibP.h" /* eventTaskShow () */
  90. #define MAX_DSP_TASKS 500 /* max tasks that can be displayed */
  91. /* globals */
  92. char *taskRegsFmt = "%-6s = %8x";
  93. VOIDFUNCPTR _func_taskRegsShowRtn;
  94. /* locals */
  95. LOCAL char infoHdr [] = "n
  96.   NAME        ENTRY       TID    PRI   STATUS      PC       SP     ERRNO  DELAYn
  97. ---------- ------------ -------- --- ---------- -------- -------- ------- -----n";
  98. /* forward declarations */
  99. LOCAL void taskSummary (TASK_DESC *pTd);
  100. #if (CPU_FAMILY==MIPS || CPU_FAMILY==COLDFIRE)
  101. IMPORT void taskArchRegsShow(REG_SET *pRegSet);
  102. #endif /* (CPU_FAMILY==MIPS) */
  103. /******************************************************************************
  104. *
  105. * taskShowInit - initialize the task show routine facility
  106. *
  107. * This routine links the task show routines into the VxWorks system.
  108. * It is called automatically when the task show facility is
  109. * configured into VxWorks using either of the following methods:
  110. * .iP
  111. * If you use the configuration header files, define
  112. * INCLUDE_SHOW_ROUTINES in config.h.
  113. * .iP
  114. * If you use the Tornado project facility, select INCLUDE_TASK_SHOW.
  115. *
  116. * RETURNS: N/A
  117. */
  118. void taskShowInit (void)
  119.     {
  120.     if (taskLibInit () == OK)
  121. { classShowConnect (taskClassId, (FUNCPTR)taskShow);
  122. #ifdef WV_INSTRUMENTATION
  123. classShowConnect (taskInstClassId, (FUNCPTR)taskShow);
  124. #endif
  125. }
  126.     }
  127. /*******************************************************************************
  128. *
  129. * taskInfoGet - get information about a task
  130. *
  131. * This routine fills in a specified task descriptor (TASK_DESC) for a
  132. * specified task.  The information in the task descriptor is, for the most
  133. * part, a copy of information kept in the task control block (WIND_TCB).
  134. * The TASK_DESC structure is useful for common information and avoids
  135. * dealing directly with the unwieldy WIND_TCB.
  136. *
  137. * NOTE
  138. * Examination of WIND_TCBs should be restricted to debugging aids.
  139. *
  140. * RETURNS: OK, or ERROR if the task ID is invalid.
  141. */
  142. STATUS taskInfoGet
  143.     (
  144.     int         tid,            /* ID of task for which to get info */
  145.     TASK_DESC   *pTaskDesc      /* task descriptor to be filled in */
  146.     )
  147.     {
  148.     int      key;
  149.     FAST char    *pStackHigh;
  150.     FAST TASK_DESC *pTd  = pTaskDesc;
  151.     WIND_TCB     *pTcb = taskTcb (tid);
  152.     if (pTcb == NULL) /* valid task ID? */
  153. return (ERROR);
  154.     /* gather the information */
  155. #if CPU_FAMILY==I960
  156.     if (tid != taskIdSelf ()) /* showing our current sp is not possible */
  157. taskRegsStackToTcb (pTcb);
  158. #endif /* CPU_FAMILY==I960 */
  159.     pTd->td_id = (int) pTcb; /* task ID */
  160.     pTd->td_name = pTcb->name; /* name of task */
  161.     pTd->td_priority = (int) pTcb->priority;  /* priority */
  162.     pTd->td_status = pTcb->status; /* task status*/
  163.     pTd->td_options = pTcb->options; /* task option bits */
  164.     pTd->td_entry = pTcb->entry; /* entry of task */
  165.     pTd->td_sp = (char *)((int)pTcb->regs.spReg); /* saved stack ptr */
  166.     pTd->td_pStackLimit = pTcb->pStackLimit; /* limit of stack */
  167.     pTd->td_pStackBase = pTcb->pStackBase; /* bottom of stack */
  168.     pTd->td_pStackEnd = pTcb->pStackEnd; /* end of the stack */
  169. #if (_STACK_DIR==_STACK_GROWS_DOWN)
  170.     if (pTcb->options & VX_NO_STACK_FILL)
  171. pStackHigh = pTcb->pStackLimit;
  172.     else
  173. for (pStackHigh = pTcb->pStackLimit;
  174.      *(UINT8 *)pStackHigh == 0xee; pStackHigh ++)
  175.     ;
  176. #else  /* _STACK_GROWS_UP */
  177.     if (pTcb->options & VX_NO_STACK_FILL)
  178. pStackHigh = pTcb->pStackLimit - 1;
  179.     else
  180. for (pStackHigh = pTcb->pStackLimit - 1;
  181.      *(UINT8 *)pStackHigh == 0xee; pStackHigh --)
  182.     ;
  183. #endif  /* _STACK_GROWS_UP */
  184.     pTd->td_stackSize   = (int)(pTcb->pStackLimit - pTcb->pStackBase) *
  185.   _STACK_DIR;
  186.     pTd->td_stackHigh = (int)(pStackHigh - pTcb->pStackBase) * _STACK_DIR;
  187.     pTd->td_stackMargin = (int)(pTcb->pStackLimit - pStackHigh) * _STACK_DIR;
  188.     pTd->td_stackCurrent= (int)(pTd->td_sp - pTcb->pStackBase) * _STACK_DIR;
  189.     pTd->td_errorStatus = errnoOfTaskGet (tid); /* most recent error */
  190.     /* if task is delayed, get the time to fire out of the task's tick node */
  191.     if (pTcb->status & WIND_DELAY)
  192. pTd->td_delay = Q_KEY (&tickQHead, &pTcb->tickNode, 1);
  193.     else
  194. pTd->td_delay = 0; /* not delayed */
  195.     /* copy the VxWorks events information */
  196.     key = intLock ();
  197.     pTd->td_events = pTcb->events;
  198.     intUnlock (key);
  199.     return (OK);
  200.     }
  201. /*******************************************************************************
  202. *
  203. * taskShow - display task information from TCBs
  204. *
  205. * This routine displays the contents of a task control block (TCB)
  206. * for a specified task.  If <level> is 1, it also displays task options
  207. * and registers.  If <level> is 2, it displays all tasks.
  208. *
  209. * The TCB display contains the following fields:
  210. *
  211. * .TS
  212. * tab(|);
  213. * lf3 lf3
  214. * l l .
  215. * Field  | Meaning
  216. * _
  217. * NAME   | Task name
  218. * ENTRY  | Symbol name or address where task began execution
  219. * TID    | Task ID
  220. * PRI    | Priority
  221. * STATUS | Task status, as formatted by taskStatusString()
  222. * PC     | Program counter
  223. * SP     | Stack pointer
  224. * ERRNO  | Most recent error code for this task
  225. * DELAY  | If task is delayed, number of clock ticks remaining in delay (0 otherwise)
  226. * .TE
  227. *
  228. * EXAMPLE:
  229. * The following example shows the TCB contents for the shell task:
  230. * .CS
  231. *   -> taskShow tShell, 1
  232. *     NAME        ENTRY    TID    PRI  STATUS      PC       SP    ERRNO  DELAY
  233. *   ---------- --------- -------- --- --------- -------- -------- ------ -----
  234. *   tShell     _shell     20efcac   1 READY      201dc90  20ef980      0     0
  235. *   stack: base 0x20efcac  end 0x20ed59c  size 9532   high 1452   margin 8080
  236. *   options: 0x1e
  237. *   VX_UNBREAKABLE      VX_DEALLOC_STACK    VX_FP_TASK         VX_STDIO
  238. *
  239. *   VxWorks Events
  240. *   --------------
  241. *   Events Pended on    : Not Pended
  242. *   Received Events     : 0x0
  243. *   Options             : N/A
  244. *   D0 =       0   D4 =       0   A0 =       0   A4 =        0
  245. *   D1 =       0   D5 =       0   A1 =       0   A5 =  203a084   SR =     3000
  246. *   D2 =       0   D6 =       0   A2 =       0   A6 =  20ef9a0   PC =  2038614
  247. *   D3 =       0   D7 =       0   A3 =       0   A7 =  20ef980
  248. *   value = 34536868 = 0x20efda4
  249. * .CE
  250. *
  251. * RETURNS: N/A
  252. *
  253. * SEE ALSO:
  254. * taskStatusString(),
  255. * .pG "Target Shell,"
  256. * windsh,
  257. * .tG "Shell"
  258. */
  259. STATUS taskShow
  260.     (
  261.     int tid, /* task ID */
  262.     int level /* 0 = summary, 1 = details, 2 = all tasks */
  263.     )
  264.     {
  265.     FAST int nTasks; /* number of task */
  266.     FAST int ix; /* index */
  267.     TASK_DESC td; /* task descriptor for task info */
  268.     WIND_TCB * pTcb; /* pointer to tasks tcb */
  269.     int idList[MAX_DSP_TASKS]; /* list of active IDs */
  270.     char optionsString[256]; /* task options string */
  271.     tid = taskIdDefault (tid); /* get default task */
  272.     switch (level)
  273. {
  274. case 0 : /* summarize a task */
  275.     {
  276.     if (taskInfoGet (tid, &td) != OK)
  277. {
  278. printErr ("Task not found.n");
  279. return (ERROR);
  280. }
  281.     printf (infoHdr);
  282.     taskSummary (&td);
  283.     break;
  284.     }
  285. case 1 : /* get task detail */
  286.     {
  287.     if (taskInfoGet (tid, &td) != OK)
  288. {
  289. printErr ("Task not found.n");
  290. return (ERROR);
  291. }
  292.     taskOptionsString (tid, optionsString); /* get options string */
  293.     /* Print the summary as in all_task_info, then all the regs. */
  294.     printf (infoHdr); /* banner */
  295.     taskSummary (&td);
  296.     printf ("nstack: base 0x%-6x  end 0x%-6x  size %-5d  ",
  297.     (int)td.td_pStackBase, (int)td.td_pStackEnd,
  298.     td.td_stackSize);
  299.     if (td.td_options & VX_NO_STACK_FILL)
  300. printf ("high %5s  margin %5sn", "???", "???");
  301.     else
  302. printf ("high %-5d  margin %-5dn", td.td_stackHigh,
  303.  td.td_stackMargin);
  304.     printf ("noptions: 0x%xn%sn", td.td_options, optionsString);
  305.     /* display VxWorks events information */
  306.     eventTaskShow (&td.td_events);
  307.     if (tid != taskIdSelf ()) /* no self exam */
  308. {
  309. taskRegsShow (tid);
  310. if (_func_fppTaskRegsShow != NULL) /* fp regs if attached*/
  311.     (* _func_fppTaskRegsShow) (tid);
  312. if (_func_dspTaskRegsShow != NULL) /* dsp regs if attached*/
  313.     (* _func_dspTaskRegsShow) (tid);
  314. #ifdef _WRS_ALTIVEC_SUPPORT
  315. if (_func_altivecTaskRegsShow != NULL) /* altivec regs if attached*/
  316.     (* _func_altivecTaskRegsShow) (tid);
  317. #endif /* _WRS_ALTIVEC_SUPPORT */
  318. #if (CPU_FAMILY==I80X86)
  319. if (_func_sseTaskRegsShow != NULL) /* SIMD regs if attached */
  320.     (* _func_sseTaskRegsShow) (tid);
  321. #endif /* (CPU_FAMILY==I80X86) */
  322. }
  323.     /* print exception info if any */
  324.     if ((_func_excInfoShow != NULL) && ((pTcb = taskTcb (tid)) != NULL))
  325. (* _func_excInfoShow) (&pTcb->excInfo, FALSE);
  326.     break;
  327.     }
  328. case 2 : /* summarize all tasks */
  329. default :
  330.     {
  331.     printf (infoHdr);
  332.     nTasks = taskIdListGet (idList, NELEMENTS (idList));
  333.     taskIdListSort (idList, nTasks);
  334.     for (ix = 0; ix < nTasks; ++ix)
  335. {
  336. if (taskInfoGet (idList [ix], &td) == OK)
  337.     taskSummary (&td);
  338. }
  339.     break;
  340.     }
  341. }
  342.     return (OK);
  343.     }
  344. /*******************************************************************************
  345. *
  346. * taskSummary - print task summary line
  347. *
  348. * This routine is used by i() and ti() to print each task's summary line.
  349. *
  350. * NOMANUAL
  351. */
  352. LOCAL void taskSummary
  353.     (
  354.     TASK_DESC *pTd /* task descriptor to summarize */
  355.     )
  356.     {
  357.     REG_SET   regSet; /* get task's regs into here */
  358.     char      statusString[10]; /* status string goes here   */
  359.     SYMBOL_ID symbolId;                 /* symbol identifier         */
  360.     char *    name;   /* ptr to sym tbl copy of name of main routine */
  361.     void *    value = NULL; /* symbol's actual value     */
  362.     taskStatusString (pTd->td_id, statusString);
  363.     /* Print the summary of the TCB */
  364.     printf ("%-11.11s", pTd->td_name); /* print the name of the task */
  365.     /* 
  366.      * Only check one symLib function pointer (for performance's sake). 
  367.      * All symLib functions are provided by the same library, by convention.    
  368.      */
  369.     if ((_func_symFindSymbol != (FUNCPTR) NULL) && 
  370. (sysSymTbl != NULL) && 
  371. ((* _func_symFindSymbol) (sysSymTbl, NULL, (char *)pTd->td_entry, 
  372.  N_EXT | N_TEXT, N_EXT | N_TEXT,
  373.  &symbolId) == OK))
  374. {
  375. (* _func_symNameGet) (symbolId, &name);
  376. (* _func_symValueGet) (symbolId, &value);
  377. }
  378.     if (pTd->td_entry == (FUNCPTR) value)
  379. printf ("%-12.12s", name);
  380.     else
  381. printf ("%-12x", (int)pTd->td_entry);
  382.     /* get task's registers;  if the tcb being printed is the
  383.      * calling task's tcb, then taskRegsGet will return garbage for pc,
  384.      * so we fudge it a little so it won't look bad.
  385.      */
  386.     taskRegsGet (pTd->td_id, &regSet);
  387.     printf (" %8x %3d %-10.10s %8x %8x %7x %5un",
  388.     pTd->td_id,
  389.     pTd->td_priority,
  390.     statusString,
  391.     ((taskIdSelf () == pTd->td_id) ? (int)taskSummary : (int)regSet.pc),
  392.     (int)regSet.spReg,
  393.     pTd->td_errorStatus,
  394.     pTd->td_delay);
  395.     }
  396. /******************************************************************************
  397. *
  398. * taskIdListSort - sort the ID list by priority
  399. *
  400. * This routine sorts the <idList> by task priority.
  401. *
  402. * NOMANUAL
  403. */
  404. void taskIdListSort
  405.     (
  406.     int idList[], /* id list to sort */
  407.     int nTasks /* number of tasks in id list */
  408.     )
  409.     {
  410.     FAST int temp;
  411.     int prevPri;
  412.     int curPri;
  413.     FAST int *pCurId;
  414.     BOOL change = TRUE;
  415.     FAST int *pEndId = &idList [nTasks];
  416.     if (nTasks == 0)
  417. return;
  418.     while (change)
  419. {
  420. change = FALSE;
  421. taskPriorityGet (idList[0], &prevPri);
  422. for (pCurId = &idList[1]; pCurId < pEndId; ++pCurId, prevPri = curPri)
  423.     {
  424.     taskPriorityGet (*pCurId, &curPri);
  425.     if (prevPri > curPri)
  426. {
  427. temp = *pCurId;
  428. *pCurId = *(pCurId - 1);
  429. *(pCurId - 1) = temp;
  430. change = TRUE;
  431. }
  432.     }
  433. }
  434.     }
  435. /*******************************************************************************
  436. *
  437. * taskRegsShow - display the contents of a task's registers
  438. *
  439. * This routine displays the register contents of a specified task
  440. * on standard output.
  441. *
  442. * EXAMPLE: The following example displays the register of the shell task 
  443. * (68000 family):
  444. * .CS 4
  445. * -> taskRegsShow (taskNameToId ("tShell"))
  446. *
  447. * d0     =        0   d1     =        0    d2    =    578fe    d3     =        1
  448. * d4     =   3e84e1   d5     =   3e8568    d6    =        0    d7     = ffffffff
  449. * a0     =        0   a1     =        0    a2    =    4f06c    a3     =    578d0
  450. * a4     =   3fffc4   a5     =        0    fp    =   3e844c    sp     =   3e842c
  451. * sr     =     3000   pc     =    4f0f2
  452. * value = 0 = 0x0
  453. * .CE
  454. *
  455. * RETURNS: N/A
  456. */
  457. void taskRegsShow
  458.     (
  459.     int tid             /* task ID */
  460.     )
  461.     {
  462. #if ((CPU_FAMILY != MIPS) && (CPU_FAMILY != COLDFIRE))
  463.     int ix;
  464.     int * pReg; /* points to register value */
  465. #endif /* (CPU_FAMILY != MIPS) && (CPU_FAMILY != COLDFIRE) */
  466.     REG_SET regSet; /* register set */
  467.     if (_func_taskRegsShowRtn != NULL)
  468.         {
  469.         (_func_taskRegsShowRtn) (tid);
  470.         return;
  471.         }
  472.     if (taskRegsGet (tid, &regSet) == ERROR)
  473. {
  474. printf ("taskRegsShow: invalid task id %#xn", tid);
  475. return;
  476. }
  477. #if (CPU_FAMILY==MIPS || CPU_FAMILY==COLDFIRE)
  478.     taskArchRegsShow (&regSet);
  479. #else
  480.     /* print out registers */
  481.     for (ix = 0; taskRegName[ix].regName != NULL; ix++)
  482. {
  483. if ((ix % 4) == 0)
  484.     printf ("n");
  485. else
  486.     printf ("%3s","");
  487. if (taskRegName[ix].regName[0] != EOS)
  488.     {
  489.     pReg = (int *) ((int)&regSet + taskRegName[ix].regOff);
  490.     printf (taskRegsFmt, taskRegName[ix].regName, *pReg);
  491.     }
  492. else
  493.     printf ("%17s", "");
  494. }
  495.     printf ("n");
  496. #endif
  497.     }
  498. /*******************************************************************************
  499. *
  500. * taskStatusString - get a task's status as a string
  501. *
  502. * This routine deciphers the WIND task status word in the TCB for a
  503. * specified task, and copies the appropriate string to <pString>.
  504. * The formatted string is one of the following:
  505. *
  506. * .TS
  507. * tab(|);
  508. * lf3 lf3
  509. * l l .
  510. * String   | Meaning
  511. * _
  512. * READY    | Task is not waiting for any resource other than the CPU.
  513. * PEND     | Task is blocked due to the unavailability of some resource.
  514. * DELAY    | Task is asleep for some duration.
  515. * SUSPEND  | Task is unavailable for execution (but not suspended, delayed, or pended).
  516. * DELAY+S  | Task is both delayed and suspended.
  517. * PEND+S   | Task is both pended and suspended.
  518. * PEND+T   | Task is pended with a timeout.
  519. * PEND+S+T | Task is pended with a timeout, and also suspended.
  520. * &...+I  | Task has inherited priority (+I may be appended to any string above).
  521. * DEAD     | Task no longer exists.
  522. * .TE
  523. *
  524. * EXAMPLE
  525. * .CS
  526. *     -> taskStatusString (taskNameToId ("tShell"), xx=malloc (10))
  527. *     new symbol "xx" added to symbol table.
  528. *     value = 0 = 0x0
  529. *     -> printf ("shell status = <%s>en", xx)
  530. *     shell status = <READY>
  531. *     value = 2 = 0x2
  532. * .CE
  533. *
  534. * RETURNS: OK, or ERROR if the task ID is invalid.
  535. */
  536. STATUS taskStatusString
  537.     (
  538.     int  tid,           /* task to get string for */
  539.     char *pString       /* where to return string */
  540.     )
  541.     {
  542.     WIND_TCB *pTcb = taskTcb (tid);
  543.     if (pTcb == NULL)
  544. return (ERROR);
  545.     switch (pTcb->status)
  546. {
  547. case WIND_READY: strcpy (pString, "READY");  break;
  548. case WIND_DELAY: strcpy (pString, "DELAY");  break;
  549. case WIND_DELAY |
  550.      WIND_SUSPEND: strcpy (pString, "DELAY+S");  break;
  551. case WIND_PEND: strcpy (pString, "PEND");   break;
  552. case WIND_PEND |
  553.      WIND_DELAY: strcpy (pString, "PEND+T");   break;
  554. case WIND_PEND |
  555.      WIND_SUSPEND: strcpy (pString, "PEND+S");   break;
  556. case WIND_PEND |
  557.      WIND_DELAY |
  558.      WIND_SUSPEND: strcpy (pString, "PEND+S+T");   break;
  559. case WIND_SUSPEND: strcpy (pString, "SUSPEND");  break;
  560. case WIND_DEAD: strcpy (pString, "DEAD");   break;
  561. default: /* unanticipated combination */
  562.     sprintf (pString, "0x%02x", pTcb->status);
  563.     return (ERROR);
  564. }
  565.     if (pTcb->priority != pTcb->priNormal)
  566. strcat (pString, "+I"); /* task's priority inherited */
  567.     return (OK);
  568.     }
  569. /*******************************************************************************
  570. *
  571. * taskOptionsString - get a task's options as a string
  572. *
  573. * This routine deciphers the WIND task options field in the TCB, for a
  574. * specified task, and copies the appropriate string to <pString>.
  575. *
  576. * RETURNS: OK, or ERROR if the task ID is invalid.
  577. *
  578. * NOMANUAL
  579. */
  580. STATUS taskOptionsString
  581.     (
  582.     int  tid,           /* task to get options string for */
  583.     char *pString       /* where to return string of options */
  584.     )
  585.     {
  586.     WIND_TCB *pTcb = taskTcb (tid);
  587.     if (pTcb == NULL)
  588. return (ERROR);
  589.     pString[0] = EOS; /* null terminate string */
  590.     if (pTcb->options & VX_SUPERVISOR_MODE)
  591. strcat (pString, "VX_SUPERVISOR_MODE  ");
  592.     if (pTcb->options & VX_UNBREAKABLE)
  593. strcat (pString, "VX_UNBREAKABLE      ");
  594.     if (pTcb->options & VX_DEALLOC_STACK)
  595. strcat (pString, "VX_DEALLOC_STACK    ");
  596.     if (pTcb->options & VX_FP_TASK)
  597. strcat (pString, "VX_FP_TASK          ");
  598.     if (pTcb->options & VX_DSP_TASK)
  599. strcat (pString, "VX_DSP_TASK         ");
  600. #ifdef _WRS_ALTIVEC_SUPPORT
  601.     if (pTcb->options & VX_ALTIVEC_TASK)
  602.         strcat (pString, "VX_ALTIVEC_TASK     ");
  603. #endif /* _WRS_ALTIVEC_SUPPORT */
  604.     if (pTcb->options & VX_STDIO)
  605. strcat (pString, "VX_STDIO            ");
  606.     if (pTcb->options & VX_ADA_DEBUG)
  607. strcat (pString, "VX_ADA_DEBUG        ");
  608.     if (pTcb->options & VX_FORTRAN)
  609. strcat (pString, "VX_FORTRAN          ");
  610.     if (pTcb->options & VX_PRIVATE_ENV)
  611. strcat (pString, "VX_PRIVATE_ENV      ");
  612.     if (pTcb->options & VX_NO_STACK_FILL)
  613. strcat (pString, "VX_NO_STACK_FILL    ");
  614.     return (OK);
  615.     }