home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / s920603.zip / KSUBR.C < prev    next >
C/C++ Source or Header  |  1992-06-03  |  6KB  |  253 lines

  1. /* Machine or compiler-dependent portions of kernel
  2.  * Turbo-C version for PC
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include <stdio.h>
  7. #include <dos.h>
  8. #include "global.h"
  9. #include "proc.h"
  10. #include "pc.h"
  11. #include "commands.h"
  12.  
  13. static char *Taskers[] = {
  14.     "",
  15.     "DoubleDos",
  16.     "DesqView",
  17.     "Windows",
  18.     "OS/2",
  19. };
  20.  
  21.  
  22. static oldNull;
  23.  
  24. /* Template for contents of jmp_buf in Turbo C */
  25. struct env {
  26.     unsigned    sp;
  27.     unsigned    ss;
  28.     unsigned    flag;
  29.     unsigned    cs;
  30.     unsigned    ip;
  31.     unsigned    bp;
  32.     unsigned    di;
  33.     unsigned    es;
  34.     unsigned    si;
  35.     unsigned    ds;
  36. };
  37.  
  38. static int chkintstk __ARGS((void));
  39. static int stkutil __ARGS((struct proc *pp));
  40. static void pproc __ARGS((struct proc *pp));
  41.  
  42. void
  43. kinit()
  44. {
  45.     int i;
  46.  
  47.     /* Initialize interrupt stack for high-water-mark checking */
  48.     for(i=0;i<512;i++)
  49.         Intstk[i] = STACKPAT;
  50.  
  51.     /* Remember location 0 pattern to detect null pointer derefs */
  52.     oldNull = *(unsigned short *)NULL;
  53.  
  54.     /* Initialize signal queue */
  55.     Ksig.wp = Ksig.rp = Ksig.entry;
  56. }
  57. /* Print process table info
  58.  * Since things can change while ps is running, the ready proceses are
  59.  * displayed last. This is because an interrupt can make a process ready,
  60.  * but a ready process won't spontaneously become unready. Therefore a
  61.  * process that changes during ps may show up twice, but this is better
  62.  * than not having it showing up at all.
  63.  */
  64. int
  65. ps(argc,argv,p)
  66. int argc;
  67. char *argv[];
  68. void *p;
  69. {
  70.     register struct proc *pp;
  71.     int i;
  72.  
  73.     printf("Uptime %s Stack %x max intstk %u psp %x",tformat(secclock()),
  74.      getss(),chkintstk(),_psp);
  75.     if(Mtasker != 0){
  76.         printf(" Running under %s",Taskers[Mtasker]);
  77.     }
  78.     printf("\n");
  79.  
  80.     printf("psigs %lu queued %lu hiwat %u woken %lu nops %lu dups %u\n",Ksig.psigs,
  81.      Ksig.psigsqueued,Ksig.maxentries,Ksig.psigwakes,Ksig.psignops,Ksig.dupsigs);
  82.     Ksig.maxentries = 0;
  83.     printf("pwaits %lu nops %lu from int %lu\n",
  84.      Ksig.pwaits,Ksig.pwaitnops,Ksig.pwaitints);
  85.     printf("PID       SP        stksize   maxstk    event     fl  in  out  name\n");
  86.  
  87.     for(pp = Susptab;pp != NULLPROC;pp = pp->next)
  88.         pproc(pp);
  89.  
  90.     for(i=0;i<PHASH;i++)
  91.         for(pp = Waittab[i];pp != NULLPROC;pp = pp->next)
  92.             pproc(pp);
  93.  
  94.     for(pp = Rdytab;pp != NULLPROC;pp = pp->next)
  95.         pproc(pp);
  96.  
  97.     if(Curproc != NULLPROC)
  98.         pproc(Curproc);
  99.  
  100.     return 0;
  101. }
  102. static void
  103. pproc(pp)
  104. struct proc *pp;
  105. {
  106.     register struct env *ep;
  107.     char insock[5],outsock[5];
  108.  
  109.     ep = (struct env *)&pp->env;
  110.     if(fileno(pp->input) != -1)
  111.         sprintf(insock,"%3d",fileno(pp->input));
  112.     else
  113.         sprintf(insock,"   ");
  114.     if(fileno(pp->output) != -1)
  115.         sprintf(outsock,"%3d",fileno(pp->output));
  116.     else
  117.         sprintf(outsock,"   ");
  118.     printf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %s %s  %s\n",
  119.      ptol(pp),ptol(MK_FP(ep->ss,ep->sp)),pp->stksize,stkutil(pp),
  120.      ptol(pp->event),
  121.      (pp->flags & P_ISTATE) ? 'I' : ' ',
  122.      (pp->state & WAITING) ? 'W' : ' ',
  123.      (pp->state & SUSPEND) ? 'S' : ' ',
  124.      insock,outsock,pp->name);
  125. }
  126. static int
  127. stkutil(pp)
  128. struct proc *pp;
  129. {
  130.     unsigned i;
  131.     register int16 *sp;
  132.  
  133.     i = pp->stksize;
  134.     for(sp = pp->stack;*sp == STACKPAT && sp < pp->stack + pp->stksize;sp++)
  135.         i--;
  136.     return i;
  137. }
  138. /* Return number of used words in interrupt stack. Note hardwired value
  139.  * for stack size; this is also found in the various .asm files
  140.  */
  141. static int
  142. chkintstk()
  143. {
  144.     register int i;
  145.     register int16 *cp;
  146.  
  147.     for(i=512,cp = Intstk; i != 0 && *cp == STACKPAT; cp++)
  148.         i--;
  149.     return i;
  150. }
  151.  
  152. /* Verify that stack pointer for current process is within legal limits;
  153.  * also check that no one has dereferenced a null pointer
  154.  */
  155. void
  156. chkstk()
  157. {
  158.     int16 *sbase;
  159.     int16 *stop;
  160.     int16 *sp;
  161.  
  162.     sp = MK_FP(_SS,_SP);
  163.     if(_SS == _DS){
  164.         /* Probably in interrupt context */
  165.         return;
  166.     }
  167.     sbase = Curproc->stack;
  168.     if(sbase == NULL)
  169.         return;    /* Main task -- too hard to check */
  170.  
  171.     stop = sbase + Curproc->stksize;
  172.     if(sp < sbase || sp >= stop){
  173.         printf("Stack violation, process %s\n",Curproc->name);
  174.         printf("SP = %lx, legal stack range [%lx,%lx)\n",
  175.         ptol(sp),ptol(sbase),ptol(stop));
  176.         fflush(stdout);
  177.         killself();
  178.     }
  179.     if(*(unsigned short *)NULL != oldNull){
  180.         printf("WARNING: Location 0 smashed, process %s\n",Curproc->name);
  181.         *(unsigned short *)NULL = oldNull;
  182.         fflush(stdout);
  183.     }
  184. }
  185. /* Machine-dependent initialization of a task */
  186. void
  187. psetup(pp,iarg,parg1,parg2,pc)
  188. struct proc *pp;    /* Pointer to task structure */
  189. int iarg;        /* Generic integer arg */
  190. void *parg1;        /* Generic pointer arg #1 */
  191. void *parg2;        /* Generic pointer arg #2 */
  192. void (*pc)();        /* Initial execution address */
  193. {
  194.     register int *stktop;
  195.     register struct env *ep;
  196.  
  197.     /* Set up stack to make it appear as if the user's function was called
  198.      * by killself() with the specified arguments. When the user returns,
  199.      * killself() automatically cleans up.
  200.      *
  201.      * First, push args on stack in reverse order, simulating what C
  202.      * does just before it calls a function.
  203.      */
  204.     stktop = (int *)(pp->stack + pp->stksize);
  205. #ifdef    LARGEDATA
  206.     *--stktop = FP_SEG(parg2);
  207. #endif
  208.     *--stktop = FP_OFF(parg2);
  209. #ifdef    LARGEDATA
  210.     *--stktop = FP_SEG(parg1);
  211. #endif
  212.     *--stktop = FP_OFF(parg1);
  213.     *--stktop = iarg;
  214.         
  215.     /* Now push the entry address of killself(), simulating the call to
  216.      * the user function.
  217.      */
  218. #ifdef    LARGECODE
  219.     *--stktop = FP_SEG(killself);
  220. #endif
  221.     *--stktop = FP_OFF(killself);
  222.  
  223.     /* Set up task environment. Note that for Turbo-C, the setjmp
  224.      * sets the interrupt enable flag in the environment so that
  225.      * interrupts will be enabled when the task runs for the first time.
  226.      * Note that this requires newproc() to be called with interrupts
  227.      * enabled!
  228.      */
  229.     setjmp(pp->env);
  230.     ep = (struct env *)&pp->env;
  231.     ep->ss = FP_SEG(stktop);
  232.     ep->sp = FP_OFF(stktop);
  233.     ep->cs = FP_SEG(pc);    /* Doesn't hurt in small model */
  234.     ep->ip = FP_OFF(pc);
  235.     ep->bp = 0;        /* Anchor stack traces */
  236.     /* Task initially runs with interrupts on */
  237.     pp->flags |= P_ISTATE;
  238. }
  239. unsigned
  240. phash(event)
  241. void *event;
  242. {
  243.     register unsigned x;
  244.  
  245.     /* Fold the two halves of the pointer */
  246.     x = FP_SEG(event) ^ FP_OFF(event);
  247.  
  248.     /* If PHASH is a power of two, this will simply mask off the
  249.      * higher order bits
  250.      */
  251.     return x % PHASH;
  252. }
  253.