home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / DOOG / CTASK.ZIP / TSKSNAP.C < prev    next >
C/C++ Source or Header  |  1989-12-20  |  11KB  |  345 lines

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