home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CTASK22.ZIP / TSKSNAP.C < prev    next >
C/C++ Source or Header  |  1990-10-12  |  12KB  |  390 lines

  1. /*
  2.    --- Version 2.2 90-10-12 10:33 ---
  3.  
  4.    TSKSNAP.C - CTask State Snaphot
  5.  
  6.    Public Domain Software written by
  7.       Thomas Wagner
  8.       Ferrari electronic Gmbh
  9.       Beusselstrasse 27
  10.       D-1000 Berlin 21
  11.       Germany
  12.  
  13.    This file is new with Version 1.1
  14.    It has been changed to use the assembler printf routines in 
  15.    version 2.1.
  16. */
  17.  
  18. #include "tsk.h"
  19. #include "tsklocal.h"
  20. #include "tsksup.h"
  21. #include "tskprf.h"
  22. #include "tskdeb.h"
  23.  
  24. #include <stdarg.h>
  25.  
  26. #define DBPSP  0  /* If defined nonzero, the PSP info is displayed in place
  27.                      of stack-pointer and stack-bottom in dump_tasks. */
  28.  
  29. #define NOFILEIO 1  /* If defined nonzero, the routines using the standard
  30.                        I/O routines are not included in the compilation. */
  31.  
  32. #if (DOS)
  33.  
  34. local char *sn_state [] = { "*???*", "Stop", "Delay", "Wait", "Elig", "Run" };
  35. local char *sn_kind [] = { "*Undef*", "Task", "Flag", "Resource", "Counter",
  36.                            "Mailbox", "Pipe", "Wpipe", "Buffer" };
  37.  
  38. local int maxrow, row;
  39.  
  40. #if (CHECKING)
  41. local word Staticfunc stack_free (tcbptr task)
  42. {
  43.    word i;
  44.    byteptr ptr;
  45.  
  46.    ptr = task->stkbot;
  47.    for (i = 0; *ptr++ == (byte)i; i++)
  48.       ;
  49.    return i;
  50. }
  51. #endif
  52.  
  53. local int CStaticfunc xprintf (int handle, byteptr format, ...)
  54. {
  55.    va_list argptr;
  56.  
  57.    if (maxrow > 0 && row >= maxrow)
  58.       return -1;
  59.  
  60.    va_start (argptr, format);
  61.  
  62.    if (handle >= 0)
  63.       tsk_vfprintf (handle, format, argptr);
  64.    else if (handle == -1)
  65.       tsk_vprintf (format, argptr);
  66.    else
  67.       tsk_vrprintf (format, argptr);
  68.  
  69.    va_end (argptr);
  70.    return 0;
  71. }
  72.  
  73.  
  74. local int Staticfunc sn_wlist (int f, byteptr str, queheadptr list, int col)
  75. {
  76.    queptr curr;
  77.  
  78.    curr = list->first;
  79.    if (curr->kind & Q_HEAD)
  80.       return col;
  81.    if (col)
  82.       {
  83.       row++;
  84.       xprintf (f, "\n%31c", ' ');
  85.       }
  86.    col = 52;
  87.    xprintf (f, "%6Fs(%Fp):  ", (farptr)str, list);
  88.    while (!(curr->kind & Q_HEAD))
  89.       {
  90.       if (col >= 60)
  91.          {
  92.          row++;
  93.          xprintf (f, "\n%51c", ' ');
  94.          col = 52;
  95.          }
  96.       xprintf (f, "%-8Fs(%Fp) ", ((tcbptr)curr)->name.name, curr);
  97.       col += 20;
  98.       curr = curr->next;
  99.       }
  100.    return col;
  101. }
  102.  
  103.  
  104. local void Staticfunc dgroup (int f, gcbptr group)
  105. {
  106.    xprintf (f, ">> Group %-8Fs (%Fp), C:%-8Fs (%Fp), B:%Fp, L:%Fp\n",
  107.             group->namelist.name, group, 
  108.             group->creator->name.name, group->creator,
  109.             group->branch, group->level);
  110.    row++;
  111. }
  112.  
  113.  
  114. local void Staticfunc event_group (int f, gcbptr base)
  115. {
  116.    queptr curr;
  117.    int col;
  118.    flagptr fl;
  119.    counterptr ct;
  120.    resourceptr rs;
  121.    mailboxptr mb;
  122.    pipeptr pp;
  123.    wpipeptr wp;
  124.    bufferptr bp;
  125.    gcbptr group;
  126.  
  127.    for (group = base; group != LNULL; group = group->level)
  128.       {
  129.       dgroup (f, group);
  130.       for (curr = group->namelist.list.first; !(curr->kind & Q_HEAD); curr = curr->next)
  131.          if (curr->kind != TYP_TCB)
  132.             {
  133.             if (xprintf (f, "%-8Fs   %-8Fs  ", ((nameptr)curr)->name,
  134.                          (farptr)sn_kind [curr->kind]))
  135.                return;
  136.             switch (curr->kind)
  137.                {
  138.                case TYP_FLAG: fl = (flagptr) ((nameptr)curr)->strucp;
  139.                               xprintf (f, "%8Fs  ", (farptr)((fl->state) ? "Set" : "Clear"));
  140.                               col = sn_wlist (f, "Set", &fl->wait_set, 0);
  141.                               sn_wlist (f, "Clear", &fl->wait_clear, col);
  142.                               break;
  143.  
  144.                case TYP_COUNTER: ct = (counterptr) ((nameptr)curr)->strucp;
  145.                               xprintf (f, "%8ld  ", ct->state);
  146.                               col = sn_wlist (f, "Set", &ct->wait_set, 0);
  147.                               sn_wlist (f, "Clear", &ct->wait_clear, col);
  148.                               break;
  149.  
  150.                case TYP_RESOURCE: rs = (resourceptr) ((nameptr)curr)->strucp;
  151.                               if (rs->count)
  152.                                  {
  153.                                  xprintf (f, "%8u  ", rs->count);
  154.                                  xprintf (f, "Owner (%Fp):  ", (farptr)&rs->owner);
  155.                                  xprintf (f, "%-8Fs(%Fp) ", rs->owner->name.name, 
  156.                                                          rs->owner);
  157.                                  col = 70;
  158.                                  }
  159.                               else
  160.                                  {
  161.                                  xprintf (f, "    Free  ");
  162.                                  col = 0;
  163.                                  }
  164.                               sn_wlist (f, "Wait", &rs->waiting, col);
  165.                               break;
  166.  
  167.                case TYP_MAILBOX: mb = (mailboxptr) ((nameptr)curr)->strucp;
  168.                               xprintf (f, "%8Fs  ", (farptr)((mb->mail_first == LNULL)
  169.                                        ? "Empty" : "Mail"));
  170.                               sn_wlist (f, "Mail", &mb->waiting, 0);
  171.                               break;
  172.  
  173.                case TYP_PIPE: pp = (pipeptr) ((nameptr)curr)->strucp;
  174.                               xprintf (f, "%8u  ", pp->filled);
  175.                               col = sn_wlist (f, "Read", &pp->wait_read, 0);
  176.                               col = sn_wlist (f, "Write", &pp->wait_write, col);
  177.                               sn_wlist (f, "Clear", &pp->wait_clear, col);
  178.                               break;
  179.  
  180.                case TYP_WPIPE: wp = (wpipeptr) ((nameptr)curr)->strucp;
  181.                               xprintf (f, "%8u  ", wp->filled);
  182.                               col = sn_wlist (f, "Read", &wp->wait_read, 0);
  183.                               col = sn_wlist (f, "Write", &wp->wait_write, col);
  184.                               sn_wlist (f, "Clear", &wp->wait_clear, col);
  185.                               break;
  186.  
  187.                case TYP_BUFFER: bp = (bufferptr) ((nameptr)curr)->strucp;
  188.                               xprintf (f, "%8u  ", bp->msgcnt);
  189.                               col = sn_wlist (f, "Read", &bp->buf_read.waiting, 0);
  190.                               sn_wlist (f, "Write", &bp->buf_write.waiting, col);
  191.                               break;
  192.  
  193.                default:       xprintf (f, "*Invalid Type %02x", curr->kind);
  194.                               break;
  195.                }
  196.             xprintf (f, "\n");
  197.             row++;
  198.             }
  199.       if (group->branch != LNULL)
  200.          event_group (f, group->branch);
  201.       }
  202. }
  203.  
  204.  
  205. local void Staticfunc dump_events (int f)
  206. {
  207.    if (xprintf (f, "List of Events:\n"))
  208.       return;
  209.    /*           1234567890123456789012345678901234567890123456789012345
  210.                 12345678   12345678  12345678  123456(123456789):        */
  211.    row++;
  212.    if (xprintf (f, "Name       Type         State     Waitfor(Queue)   Tasks\n"))
  213.       return;
  214.    row++;
  215.  
  216.    event_group (f, &GLOBDATA group);
  217.    xprintf (f, "\n");
  218.    row++;
  219. }
  220.  
  221.  
  222. local void Staticfunc task_group (int f, gcbptr base, word oldpri)
  223. {
  224.    queptr curr;
  225.    tcbptr task;
  226.    gcbptr group;
  227.  
  228.    for (group = base; group != LNULL; group = group->level)
  229.       {
  230.       dgroup (f, group);
  231.       for (curr = group->namelist.list.first; !(curr->kind & Q_HEAD);
  232.            curr = curr->next)
  233.          if (curr->kind == TYP_TCB)
  234.             {
  235.             task = (tcbptr) ((nameptr)curr)->strucp;
  236.  
  237.             if (xprintf (f, "%-8Fs %-5Fs %Fp ",
  238.                          ((nameptr)curr)->name, 
  239.                          (farptr) sn_state [(task->state <= 5) 
  240.                                             ? task->state : 0],
  241.                          task->qhead))
  242.                return;
  243.  
  244.             if (task->timerq.link.next == LNULL)
  245.                xprintf (f, "%8c", '-');
  246.             else switch (task->timerq.link.kind)
  247.                {
  248.                case TYP_WATCH:         xprintf (f, " Watch ");
  249.                                        if ((task->timerq.elkind & 0xf0)
  250.                                            == TELEM_MEM)
  251.                                           xprintf (f, "M");
  252.                                        else
  253.                                           xprintf (f, "P");
  254.                                        break;
  255.  
  256.                case TYP_HOTKEY:        xprintf (f, " Hotkey ");
  257.                                        break;
  258.  
  259.                case TYP_TIMER:         xprintf (f, "%8ld", 
  260.                                              task->timerq.link.el.ticks);
  261.                                        break;
  262.  
  263.                default:                xprintf (f, "  ?%5d",
  264.                                                 task->timerq.link.kind); 
  265.                                        break;
  266.                }
  267.  
  268. #if (CHECKING)
  269. #if (!DBPSP)
  270.             xprintf (f, " %Fp %Fp   %6d  %Fp",
  271.                   task,
  272.                   task->stack, 
  273.                   stack_free (task),
  274.                   ((struct task_stack far *)task->stack)->retn);
  275. #else
  276.             xprintf (f, " %Fp %04X %04X   %6d  %Fp",
  277.                   task,
  278.                   task->base_psp,
  279.                   *((word far *)(&task->swap_area [0x10])),
  280.                   stack_free (task),
  281.                   ((struct task_stack far *)task->stack)->retn);
  282. #endif
  283. #else
  284. #if (!DBPSP)
  285.             xprintf (f, " %Fp %Fp %Fp %Fp",
  286.                   task,
  287.                   task->stack, 
  288.                   task->stkbot,
  289.                   ((struct task_stack far *)task->stack)->retn);
  290. #else
  291.             xprintf (f, " %Fp %04X %04X %Fp %Fp",
  292.                   task,
  293.                   task->base_psp,
  294.                   *((word far *)(&task->swap_area [0x10])),
  295.                   task->psp_sssp,
  296.                   ((struct task_stack far *)task->stack)->retn);
  297. #endif
  298. #endif
  299.             if (task != GLOBDATA current_task)
  300.                xprintf (f, " %5u\n", task->cqueue.el.pri.prior);
  301.             else
  302.                xprintf (f, "*%5u\n", oldpri);
  303.             row++;
  304.             }
  305.  
  306.       if (group->branch != LNULL)
  307.          task_group (f, group->branch, oldpri);
  308.       }
  309. }
  310.  
  311.  
  312. local void Staticfunc dump_tasks (int f, word oldpri)
  313. {
  314.    static union REGS regs;
  315.  
  316.    regs.x.ax = 0x1683;
  317.    int86 (0x2f, ®s, ®s);
  318.    row++;
  319.    xprintf (f, "\nTask List (VM=%04X):\n", regs.x.bx);
  320.    row++;
  321. #if (CHECKING)
  322. #if (!DBPSP)
  323.    xprintf (f, "Name     State Queue      Timeout TCB-addr  Stackptr  FreeStack Instrptr  Prior\n");
  324. #else
  325.    xprintf (f, "Name     State Queue      Timeout TCB-addr  BPSP CPSP FreeStack Instrptr  Prior\n");
  326. #endif
  327. #else
  328. #if (!DBPSP)
  329.    xprintf (f, "Name     State Queue      Timeout TCB-addr  Stackptr  Stackbot  Instrptr  Prior\n");
  330. #else
  331.    xprintf (f, "Name     State Queue      Timeout TCB-addr  BPSP CPSP PSP-SSSP  Instrptr  Prior\n");
  332. #endif
  333. #endif
  334.    row++;
  335.  
  336.    task_group (f, &GLOBDATA group, oldpri);
  337.    xprintf (f, "\n");
  338.    row++;
  339. }
  340.  
  341.  
  342. local void Staticfunc ssnap (int f)
  343. {
  344.    word oldpri;
  345.  
  346.    oldpri = get_priority (GLOBDATA current_task);
  347.    set_priority (GLOBDATA current_task, 0xffff);
  348.  
  349.    row = 0;
  350.    dump_tasks (f, oldpri);
  351.    dump_events (f);
  352.  
  353.    set_priority (GLOBDATA current_task, oldpri);
  354. }
  355.  
  356.  
  357. #if (!NOSTDIO)
  358.  
  359. void Globalfunc snapshot (FILE far *f)
  360. {
  361.    fflush (f);
  362.    maxrow = 0;
  363.    ssnap (fileno (f));
  364. }
  365.  
  366. #endif
  367.  
  368. void Globalfunc csnapshot (void)
  369. {
  370.    maxrow = 0;
  371.    ssnap (-1);
  372. }
  373.  
  374.  
  375. void Globalfunc screensnap (int rows)
  376. {
  377. #if (DEBUG)
  378.    maxrow = rows - 3;   /* Leave 2 lines at top alone */
  379.    tsk_setpos (2, 0);
  380. #else
  381.    maxrow = rows - 1;
  382.    tsk_setpos (0, 0);
  383. #endif
  384.    tsk_set_clreol (1);
  385.    ssnap (-2);
  386. }
  387.  
  388. #endif
  389.  
  390.