⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsksnap.c

📁 一个可以立即使用的嵌入式操作系统
💻 C
字号:
/*
   --- Version 2.2 93-06-08 10:26 ---

   TSKSNAP.C - CTask State Snaphot

   Public Domain Software written by
      Thomas Wagner
      Ferrari electronic Gmbh
      Beusselstrasse 27
      D-1000 Berlin 21
      Germany

   This file is new with Version 1.1
   It has been changed to use the assembler printf routines in 
   version 2.1.
*/

#include "tsk.h"
#include "tsklocal.h"
#include "tsksup.h"
#include "tskprf.h"
#include "tskdeb.h"

#include <stdarg.h>

#define DBPSP  0  /* If defined nonzero, the PSP info is displayed in place
                     of stack-pointer and stack-bottom in dump_tasks. */

#define NOSTDIO 0  /* If defined nonzero, the routines using the standard
                      I/O routines are not included in the compilation. */

#if (DOS)

local char *sn_state [] = { "*???*", "Stop", "Delay", "Wait", "Elig", "Run" };
local char *sn_kind [] = { "*Undef*", "Task", "Flag", "Resource", "Counter",
                           "Mailbox", "Pipe", "Wpipe", "Buffer" };

local int maxrow, row;

#if (CHECKING)
local word Staticfunc stack_free (tcbptr task)
{
   word i;
   byteptr ptr;

   ptr = task->stkbot;
   for (i = 0; *ptr++ == (byte)i; i++)
      ;
   return i;
}
#endif

local int CStaticfunc xprintf (int handle, byteptr format, ...)
{
   va_list argptr;

   if (maxrow > 0 && row >= maxrow)
      return -1;

   va_start (argptr, format);

   if (handle >= 0)
      tsk_vfprintf (handle, format, argptr);
   else if (handle == -1)
      tsk_vprintf (format, argptr);
   else if (handle == -3)
      tsk_vcprintf (format, argptr);
   else
      tsk_vrprintf (format, argptr);

   va_end (argptr);
   return 0;
}


local int Staticfunc sn_wlist (int f, byteptr str, queheadptr list, int col)
{
   queptr curr;

   curr = list->first;
   if (curr->kind & Q_HEAD)
      return col;
   if (col)
      {
      row++;
      xprintf (f, "\n%31c", ' ');
      }
   col = 52;
   xprintf (f, "%6Fs(%Fp):  ", (farptr)str, list);
   while (!(curr->kind & Q_HEAD))
      {
      if (col >= 60)
         {
         row++;
         xprintf (f, "\n%51c", ' ');
         col = 52;
         }
      xprintf (f, "%-8Fs(%Fp) ", ((tcbptr)curr)->name.name, curr);
      col += 20;
      curr = curr->next;
      }
   return col;
}


local void Staticfunc dgroup (int f, gcbptr group)
{
   xprintf (f, ">> Group %-8Fs (%Fp), C:%-8Fs (%Fp), B:%Fp, L:%Fp\n",
            group->namelist.name, group, 
            group->creator->name.name, group->creator,
            group->branch, group->level);
   row++;
}


local void Staticfunc event_group (int f, gcbptr base)
{
   queptr curr;
   int col;
   flagptr fl;
   counterptr ct;
   resourceptr rs;
   mailboxptr mb;
   pipeptr pp;
   wpipeptr wp;
   bufferptr bp;
   gcbptr group;

   for (group = base; group != LNULL; group = group->level)
      {
      dgroup (f, group);
      for (curr = group->namelist.list.first; !(curr->kind & Q_HEAD); curr = curr->next)
         if (curr->kind != TYP_TCB)
            {
            if (xprintf (f, "%-8Fs   %-8Fs  ", ((nameptr)curr)->name,
                         (farptr)sn_kind [curr->kind]))
               return;
            switch (curr->kind)
               {
               case TYP_FLAG: fl = (flagptr) ((nameptr)curr)->strucp;
                              xprintf (f, "%8Fs  ", (farptr)((fl->state) ? "Set" : "Clear"));
                              col = sn_wlist (f, "Set", &fl->wait_set, 0);
                              sn_wlist (f, "Clear", &fl->wait_clear, col);
                              break;

               case TYP_COUNTER: ct = (counterptr) ((nameptr)curr)->strucp;
                              xprintf (f, "%8ld  ", ct->state);
                              col = sn_wlist (f, "Set", &ct->wait_set, 0);
                              sn_wlist (f, "Clear", &ct->wait_clear, col);
                              break;

               case TYP_RESOURCE: rs = (resourceptr) ((nameptr)curr)->strucp;
                              if (rs->count)
                                 {
                                 xprintf (f, "%8u  ", rs->count);
                                 xprintf (f, "Owner (%Fp):  ", (farptr)&rs->owner);
                                 xprintf (f, "%-8Fs(%Fp) ", rs->owner->name.name, 
                                                         rs->owner);
                                 col = 70;
                                 }
                              else
                                 {
                                 xprintf (f, "    Free  ");
                                 col = 0;
                                 }
                              sn_wlist (f, "Wait", &rs->waiting, col);
                              break;

               case TYP_MAILBOX: mb = (mailboxptr) ((nameptr)curr)->strucp;
                              xprintf (f, "%8Fs  ", (farptr)((mb->mail_first == LNULL)
                                       ? "Empty" : "Mail"));
                              sn_wlist (f, "Mail", &mb->waiting, 0);
                              break;

               case TYP_PIPE: pp = (pipeptr) ((nameptr)curr)->strucp;
                              xprintf (f, "%8u  ", pp->filled);
                              col = sn_wlist (f, "Read", &pp->wait_read, 0);
                              col = sn_wlist (f, "Write", &pp->wait_write, col);
                              sn_wlist (f, "Clear", &pp->wait_clear, col);
                              break;

               case TYP_WPIPE: wp = (wpipeptr) ((nameptr)curr)->strucp;
                              xprintf (f, "%8u  ", wp->filled);
                              col = sn_wlist (f, "Read", &wp->wait_read, 0);
                              col = sn_wlist (f, "Write", &wp->wait_write, col);
                              sn_wlist (f, "Clear", &wp->wait_clear, col);
                              break;

               case TYP_BUFFER: bp = (bufferptr) ((nameptr)curr)->strucp;
                              xprintf (f, "%8u  ", bp->msgcnt);
                              col = sn_wlist (f, "Read", &bp->buf_read.waiting, 0);
                              sn_wlist (f, "Write", &bp->buf_write.waiting, col);
                              break;

               default:       xprintf (f, "*Invalid Type %02x", curr->kind);
                              break;
               }
            xprintf (f, "\n");
            row++;
            }
      if (group->branch != LNULL)
         event_group (f, group->branch);
      }
}


local void Staticfunc dump_events (int f)
{
   if (xprintf (f, "List of Events:\n"))
      return;
   /*           1234567890123456789012345678901234567890123456789012345
                12345678   12345678  12345678  123456(123456789):        */
   row++;
   if (xprintf (f, "Name       Type         State     Waitfor(Queue)   Tasks\n"))
      return;
   row++;

   event_group (f, &GLOBDATA group);
   xprintf (f, "\n");
   row++;
}


local void Staticfunc task_group (int f, gcbptr base, word oldpri)
{
   queptr curr;
   tcbptr task;
   gcbptr group;

   for (group = base; group != LNULL; group = group->level)
      {
      dgroup (f, group);
      for (curr = group->namelist.list.first; !(curr->kind & Q_HEAD);
           curr = curr->next)
         if (curr->kind == TYP_TCB)
            {
            task = (tcbptr) ((nameptr)curr)->strucp;

            if (xprintf (f, "%-8Fs %-5Fs %Fp ",
                         ((nameptr)curr)->name, 
                         (farptr) sn_state [(task->state <= 5) 
                                            ? task->state : 0],
                         task->qhead))
               return;

            if (task->timerq.link.next == LNULL)
               xprintf (f, "%8c", '-');
            else switch (task->timerq.link.kind)
               {
               case TYP_WATCH:         xprintf (f, " Watch ");
                                       if ((task->timerq.elkind & 0xf0)
                                           == TELEM_MEM)
                                          xprintf (f, "M");
                                       else
                                          xprintf (f, "P");
                                       break;

               case TYP_HOTKEY:        xprintf (f, " Hotkey ");
                                       break;

               case TYP_TIMER:         xprintf (f, "%8ld", 
                                             task->timerq.link.el.ticks);
                                       break;

               default:                xprintf (f, "  ?%5d",
                                                task->timerq.link.kind); 
                                       break;
               }

#if (CHECKING)
#if (!DBPSP)
            xprintf (f, " %Fp %Fp   %6d  %Fp",
                  task,
                  task->stack, 
                  stack_free (task),
                  ((struct task_stack far *)task->stack)->retn);
#else
            xprintf (f, " %Fp %04X %04X   %6d  %Fp",
                  task,
                  task->base_psp,
                  *((word far *)(&task->swap_area [0x0e])),
                  stack_free (task),
                  ((struct task_stack far *)task->stack)->retn);
#endif
#else
#if (!DBPSP)
            xprintf (f, " %Fp %Fp %Fp %Fp",
                  task,
                  task->stack, 
                  task->stkbot,
                  ((struct task_stack far *)task->stack)->retn);
#else
            xprintf (f, " %Fp %04X %04X %Fp %Fp",
                  task,
                  task->base_psp,
                  *((word far *)(&task->swap_area [0x0e])),
                  task->psp_sssp,
                  ((struct task_stack far *)task->stack)->retn);
#endif
#endif
            if (task != GLOBDATA current_task)
               xprintf (f, " %5u\n", task->cqueue.el.pri.prior);
            else
               xprintf (f, "*%5u\n", oldpri);
            row++;
            }

      if (group->branch != LNULL)
         task_group (f, group->branch, oldpri);
      }
}


local void Staticfunc dump_tasks (int f, word oldpri)
{
   static union REGS regs;

   regs.x.ax = 0x1683;
   int86 (0x2f, &regs, &regs);
   row++;
   xprintf (f, "\nTask List (VM=%04X):\n", regs.x.bx);
   row++;
#if (CHECKING)
#if (!DBPSP)
   xprintf (f, "Name     State Queue      Timeout TCB-addr  Stackptr  FreeStack Instrptr  Prior\n");
#else
   xprintf (f, "Name     State Queue      Timeout TCB-addr  BPSP CPSP FreeStack Instrptr  Prior\n");
#endif
#else
#if (!DBPSP)
   xprintf (f, "Name     State Queue      Timeout TCB-addr  Stackptr  Stackbot  Instrptr  Prior\n");
#else
   xprintf (f, "Name     State Queue      Timeout TCB-addr  BPSP CPSP PSP-SSSP  Instrptr  Prior\n");
#endif
#endif
   row++;

   task_group (f, &GLOBDATA group, oldpri);
   xprintf (f, "\n");
   row++;
}


local void Staticfunc ssnap (int f)
{
   word oldpri;

   oldpri = get_priority (GLOBDATA current_task);
   set_priority (GLOBDATA current_task, 0xffff);

   row = 0;
   dump_tasks (f, oldpri);
   dump_events (f);

   set_priority (GLOBDATA current_task, oldpri);
}


#if (!NOSTDIO)

void Globalfunc snapshot (FILE *f)
{
   fflush (f);
   maxrow = 0;
   ssnap (fileno (f));
}

#endif

void Globalfunc csnapshot (void)
{
   maxrow = 0;
   ssnap (-1);
}


void Globalfunc comsnapshot ()
{
   maxrow = 0;
   ssnap (-3);
}


void Globalfunc screensnap (int rows)
{
#if (DEBUG)
   maxrow = rows - 3;   /* Leave 2 lines at top alone */
   tsk_setpos (2, 0);
#else
   maxrow = rows - 1;
   tsk_setpos (0, 0);
#endif
   tsk_set_clreol (1);
   ssnap (-2);
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -