home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1987 / 12 / holub / kernel.h < prev    next >
Text File  |  1987-12-21  |  15KB  |  178 lines

  1. #ifndef NULL                                                                      
  2. #include <stdio.h>                                                                
  3. #endif                                                                            
  4. #include <tools/pq.h>                                                             
  5.                                                                                   
  6.                             /* Error codes                                 */     
  7. #define TE_NOERR         0  /* No error                                    */     
  8. #define TE_TOOMANY      -1  /* Maximum number of tasks (32) already exists */     
  9. #define TE_NOMEM        -2  /* Insufficient memory available               */     
  10. #define TE_BADARG       -3  /* Illegal Argument                            */     
  11. #define TE_TIMEOUT      -4  /* Timeout                                     */     
  12. #define TE_QFULL        -5  /* Queue is full                               */     
  13. #define TE_NOTASKS      -6  /* No tasks to send message                    */     
  14. #define TE_INTERNAL     -7  /* Internal error                              */     
  15. #define TE_DEADLOCK     -8  /* Delete would have caused a deadlock.        */     
  16. #define TE_STACK        -9  /* Stack overflow                              */     
  17. #define TE_KILL         -10 /* Ctrl-Break encountered                      */     
  18.                                                                                   
  19. #define TS_NORMAL       0   /* Must be 0                                   */     
  20. #define TS_WAIT         1                                                         
  21. #define TS_TIMEOUT      2                                                         
  22.                                                                                   
  23. #define T_MAXTASK       32 /* Max. number of tasks that can be active    */       
  24. #define TQ_SIG      0xa5a5 /* Signature used for queues to test validity */       
  25.                                                                                   
  26. /* PRIORITY(a,b) evaluates to a neagive number if task a is lower priority        
  27.  *               than task b, to 0 if they're equal, to a positive number         
  28.  *               if task a is higher priority than task b. If priorities          
  29.  *               are the same, the timestamps are compared and the routine        
  30.  *               with the smaller (older) time stamp is assumed to be the         
  31.  *               higher priority.                                                 
  32.  */                                                                               
  33.                                                                                   
  34. #define T_PRIORITY(a,b)  ( ((a)->priority != (b)->priority)             \         
  35.                                 ? (a)->priority  - (b)->priority        \         
  36.                                 : (b)->timestamp - (a)->timestamp       )         
  37.                                                                                   
  38. /*----------------------------------------------------------------------          
  39.  *  Task Control Block. Do not change the register-save area                      
  40.  *  (ax, bx, cx ... ) without also changing the code in swap.asm.                 
  41.  *  Don't change anything without changing the offset to the stack                
  42.  *  base in chkstk.asm.                                                           
  43.  *                                                                                
  44.  *  I'm assuming the small model here. That is, I'm assuming that                 
  45.  *  the only segment register that can change is the extra segment                
  46.  *  and that the stack and data segments always have the same value.              
  47.  *                                                                                
  48.  *  Be sure to block() if you're going to modifiy the CS, DS, or SS               
  49.  *  registers.                                                                    
  50.  *                                                                                
  51.  *  A context swap is done by pushing the registers in the following              
  52.  *  order:                                                                        
  53.  *              flags,cs,ip,ax,bx,cx,dx,si,di,bp,ds,es                            
  54.  *                                                                                
  55.  *  Then, the current stack pointer is saved in the TCB. Context is               
  56.  *  restored by popping es,ds,bp,di,si,dx,cx,bx, and ax, and then                 
  57.  *  restoring the flags, cs, and ip with an iret instruction.                     
  58.  */                                                                               
  59.                                                                                   
  60. typedef struct tcb                                                                
  61. {                                                                                 
  62.     void          **sp;         /* Must be first and must be 16 bits  */          
  63.     unsigned      ss;           /* Must be second &  must be 16 bits  */          
  64.                                                                                   
  65.     unsigned      priority;     /* priority 0=lowest, 65,535=highest    */        
  66.     unsigned long timestamp;    /* Clock tick when task was preempted.  */        
  67.                                                                                   
  68.     unsigned      wait;         /* Counting semaphore used by tasks that          
  69.                                  * are waiting at a queue. Set to initial         
  70.                                  * timeout value and decremented on each          
  71.                                  * clock tick.  Task is put back into             
  72.                                  * the active list if semaphore gets to           
  73.                                  * 0. If wait < 0, task will not time out.        
  74.                                  */                                               
  75.                                                                                   
  76.     struct tcb    *next;        /* Pointer to next task waiting at queue. */      
  77.                                                                                   
  78.     int           status;       /* TS_NORMAL  Not suspended by wait.              
  79.                                  * TS_WAIT    Suspended by wait                   
  80.                                  */                                               
  81.                                                                                   
  82.     void          *msg;         /* Dequeued message if task was waiting           
  83.                                  * for a message. NULL if task timed out.         
  84.                                  */                                               
  85.                                                                                   
  86.                                 /* The following are handy for debugging */       
  87.                                 /* but aren't used for anything else     */       
  88.     char          *tag;         /* Identifying string of some sort       */       
  89.     void          **initial_sp; /* Initial stack pointer                 */       
  90.                                                                                   
  91.     void          *stack[1];    /* First cell of stack. Must be last              
  92.                                  * thing in the structure. Must be declared       
  93.                                  * as pointer-sized for t_create().               
  94.                                  */                                               
  95. }                                                                                 
  96. TCB;                                                                              
  97.                                                                                   
  98. typedef struct t_queue                                                            
  99. {                                                                                 
  100.     int            signature;   /* Signature                        */            
  101.     struct t_queue *next;       /* Next queue in chain.             */            
  102.     TCB            *task_h;     /* Head (start) of task list.       */            
  103.     TCB            *task_t;     /* Tail (end)   of task list.       */            
  104.     int            q_size;      /* Maximum number of elements       */            
  105.     int            numele;      /* # of elements currently in queue */            
  106.     void           **headp;     /* Head pointer                     */            
  107.     void           **tailp;     /* Tail pointer                     */            
  108.     void           *queue[1];   /* First cell of actual queue.                    
  109.                                  * Must be at the bottom of the                   
  110.                                  * structure.                                     
  111.                                  */                                               
  112. }                                                                                 
  113. T_QUEUE;                                                                          
  114.                                                                                   
  115. /*----------------------------------------------------------------------          
  116.  *      Global variables. Actually declared in globals.c. I'm assuming            
  117.  *      the default initialization to 0 here. These may be used by                
  118.  *      your programs (T_clock and T_numtasks are useful) but should              
  119.  *      never be modified by them. It's safest to block while                     
  120.  *      accessing them.                                                           
  121.  */                                                                               
  122.                                                                                   
  123. #ifdef ALLOC                                                                      
  124. #       define CLASS                                                              
  125. #       define I(x) x                                                             
  126. #else                                                                             
  127. #       define CLASS extern                                                       
  128. #       define I(x)                                                               
  129. #endif                                                                            
  130.                                                                                   
  131. CLASS PQ   *T_tasks I(=0);  /* Priority queue of tasks that are waiting      */   
  132.                             /* for service. See /src/tools/pq.c for priority */   
  133.                             /* queue routines and definition of PQ.          */   
  134.                                                                                   
  135. CLASS TCB  *T_active I(=0); /* Pointer to currently active task. NULL if          
  136.                              * multitasking is off or if no tasks are active      
  137.                              * (this latter is a deadlock).                       
  138.                              */                                                   
  139.                                                                                   
  140. CLASS unsigned long T_clock I(=0);                                                
  141.                                                                                   
  142.                             /* Incremented on each system clock tick. If you      
  143.                              * assume the default 18.2 ticks/second,              
  144.                              * the clock will roll over after about               
  145.                              * 65552 hours (about 7.47 years):                    
  146.                              *                                                    
  147.                              *    ((0xffffffff/18.2) /60) /60 == 65552            
  148.                              *    65552 / 24 /365.35          == 7.47798          
  149.                              *                                                    
  150.                              * Of course, this number will scale with faster      
  151.                              * tick rates but the resolution should be ok for     
  152.                              * all reasonable tick rates.                         
  153.                              */                                                   
  154.                                                                                   
  155. CLASS T_QUEUE *T_queues   I(=0); /* Pointer to head of linked list of queues. */  
  156. CLASS int      T_numtasks I(=0); /* Total # of tasks that have been created.  */  
  157.                                                                                   
  158. /*----------------------------------------------------------------------          
  159.  * Function prototypes. You should never call any of the _t_xxxx                  
  160.  * functions directly.                                                            
  161.  */                                                                               
  162.                                                                                   
  163. extern  T_QUEUE *t_makequeue    (int size                        );               
  164. extern  int     t_send          (T_QUEUE *q,    void *msg        );               
  165. extern  void    *t_wait         (T_QUEUE *q,    int timeout      );               
  166. extern  int     t_yield         (void                            );               
  167. extern  int     t_perror        (char *str,     int errcode      );               
  168. extern  int     t_start         (int factor                      );               
  169. extern  TCB     *t_create       (int (*subr)(), char* tag, unsigned pri,          
  170.                                                         int stk_size,...);        
  171. extern  int     t_chg_priority  (TCB *tp,       int new_priority );               
  172. extern  int     t_delete        (TCB *task                       );               
  173. extern  int     t_print         (TCB *task                       );               
  174. extern  void    t_stop          (int exit_code                   );               
  175. extern  int     t_second        (void                            );               
  176. extern  void    _t_swap         (TCB *old, TCB *new              );               
  177. extern  void    _t_install      (TCB *new                        );               
  178. extern  void    _t_shazam       (void                            );