ksubr.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:6k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

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