home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 15 / 15.iso / s / s300 / 1.ddi / CHAP5 / BSCHED.C next >
Encoding:
C/C++ Source or Header  |  1988-05-02  |  7.8 KB  |  289 lines

  1. /***********************************************************************
  2.  
  3. FILE
  4.     bsched.c  -  special abbreviated version of stlsched.c
  5.  
  6. ENTRY ROUTINES
  7.     StlDispatch  -  schedule and dispatch tasks
  8.     StlStart     -  initialize timer
  9.  
  10. PRIVATE ROUTINES
  11.     dec_tleft  -  decrement t_tleft for all tasks in queue
  12.     set_tnext  -  set time to next sampling instance tnext
  13.     deep_background
  14.  
  15. REMARKS
  16.     The routines reference the STL queue as a parameter rather than 
  17.     as a global variable.  This is to allow the STL queue to be 
  18.     implemented as a soft timer-driven event queue.  
  19.     Note that multiple STL queues driven by different timers can be 
  20.     easily added later, only requiring the timer-number parameter to 
  21.     be passed as well as the queue pointer.
  22.  
  23. LAST UPDATE
  24.     11 February 1986
  25.         add event tasktype recognition
  26.     14 April 1988
  27.         make this abbreviated non-interrupt driven version
  28.  
  29.     Copyright (c) 1985 - 1988  D.M. Auslander  and  C.H. Tham
  30.  
  31. ***********************************************************************/
  32.  
  33. /***********************************************************************
  34.                             I M P O R T S
  35. ***********************************************************************/
  36.  
  37. #include <stdio.h>
  38.  
  39. #include "envir.h"          /* environment definitions */
  40.  
  41. #include "config.h"         /* system configuration header */
  42. #include "types.h"          /* type definitions */
  43. #include "task.h"           /* task descriptor definitions */
  44. #include "tqueue.h"         /* task queue module definitions */
  45. #include "dispatch.h"       /* dispatcher module declarations */
  46. #include "time.h"           /* time module definitions */
  47.  
  48. extern TASK *curtask;       /* pointer to current task descriptor */
  49.  
  50. /***********************************************************************
  51.                 F O R W A R D    D E C L A R A T I O N S
  52. ***********************************************************************/
  53.  
  54. void dec_tleft(long, TQUEUE *);
  55. void set_tnext(TQUEUE *, TQUEUE *);
  56. void deep_background(void);
  57.  
  58. /***********************************************************************
  59.             MODULE  PRIVATE  DATA  STRUCTURES  AND  VARIABLES
  60. ***********************************************************************/
  61.  
  62. static long tnext = 0L;         /* time to next sampling instance */
  63.  
  64. /***********************************************************************
  65.                     E N T R Y    R O U T I N E S
  66. ***********************************************************************/
  67.  
  68. /*----------------------------------------------------------------------
  69. PROCEDURE
  70.     STLDISPATCH  -  STL dispatcher/scheduler (background non preemptive)
  71.  
  72. SYNOPSIS
  73.     void StlDispatch(stlq, urgentq, stltimer)
  74.     TQUEUE *stlq, *urgentq;
  75.     int stltimer;
  76.  
  77. PARAMETER
  78.     stlq     -  STL task queue
  79.     urgentq  -  queue of urgent waiting tasks
  80.     stltimer -  timer to use for stl scheduling
  81.  
  82. REMARKS
  83.     1. No other scheduler can be running while this is running.
  84.     2. Since scheduler is background, obviously non pre-emptive.
  85.  
  86. LAST UPDATE
  87.     10 April 1988
  88.         specially modified to call plant simulation
  89. ----------------------------------------------------------------------*/
  90.  
  91. void StlDispatch(stlq, urgentq, stltimer)
  92. TQUEUE *stlq, *urgentq;
  93. int stltimer;
  94. {
  95.  
  96.     for (;;)        /* infinite loop */
  97.     {
  98. #ifdef SIMRT
  99.         while (!TimeUp(stltimer))
  100.         {
  101.             do_simul();
  102.             chronos();
  103.         }
  104. #else
  105.         while (!TimeUp(stltimer))
  106.             if (ReadDTimer(stltimer) > (1000L / TICKRATE))
  107.                 deep_background();
  108. #endif
  109.     
  110.         if ((curtask = GetTqueue(stlq)) == TNULL)
  111.             panic("background StlDispatch: no task to dispatch");
  112.     
  113.         dec_tleft(tnext, stlq);
  114.         set_tnext(stlq, urgentq);
  115.     
  116.         if (tnext > 0)
  117.             SetDTimer(stltimer, tnext);
  118.     
  119.         (*curtask->t_func)(curtask->t_argp);
  120.     
  121.         curtask->t_tleft = curtask->t_tsamp;
  122.     
  123.         EnterTqueue(curtask, stlq, STL_ENTER);
  124.     }
  125. }
  126.  
  127.  
  128.  
  129. /*----------------------------------------------------------------------
  130. PROCEDURE
  131.     STLSTART  -  start STL dispatcher/scheduler module
  132.  
  133. SYNOPSIS
  134.     StlStart(stlq, urgentq, stltimer)
  135.     TQUEUE *stlq, *urgentq;
  136.     int stltimer;
  137.  
  138. PARAMETER
  139.     stlq     -  STL task queue
  140.     urgentq  -  queue of urgent waiting tasks
  141.     stltimer -  timer for stl scheduling
  142.  
  143. REMARKS
  144.     This function is used to initialize this module and to start the
  145.     STL timer.  If a task is ready to run immediately (tleft == 0),
  146.     that task is dispatched.
  147.  
  148.     StlStart should to be called whenever a new task (or a new group 
  149.     of tasks) is put into the STL queue since the queue may initially 
  150.     be empty and the timer not set.
  151.  
  152. LAST UPDATE
  153.     18 March 1985
  154. ----------------------------------------------------------------------*/
  155.  
  156. void StlStart(stlq, urgentq, stltimer)
  157. TQUEUE *stlq, *urgentq;
  158. int stltimer;
  159. {
  160.  
  161.     if (stlq == TQNULL)
  162.         panic("StlStart: stlq is NULL");
  163.  
  164.     if (!EmptyTqueue(stlq))
  165.     {
  166.         tnext = HeadTqueue(stlq)->t_tleft; 
  167.  
  168.         SetDTimer(stltimer, tnext); 
  169.     }
  170.     
  171.     StlDispatch(stlq, urgentq, stltimer);
  172.  
  173. }
  174.  
  175.  
  176. /***********************************************************************
  177.                     P R I V A T E    R O U T I N E S 
  178. ***********************************************************************/
  179.  
  180. /*----------------------------------------------------------------------
  181. PROCEDURE
  182.     DEC_TLEFT  -  decrement t_tleft for all tasks in queue
  183.  
  184. SYNOPSIS
  185.     static void dec_tleft(deltime, taskq)
  186.     long deltime;
  187.     TQUEUE *taskq;
  188.  
  189. PARAMETERS
  190.     deltime  -  amount to decrement (ms)
  191.     taskq    -  task queue in question
  192.  
  193. REMARKS
  194.     Normally used to decrement by tnext.
  195.  
  196. LAST UPDATE
  197.     15 February 1985
  198. ----------------------------------------------------------------------*/
  199.  
  200. static void dec_tleft(deltime, taskq)
  201. long deltime;
  202. TQUEUE *taskq;
  203. {
  204.     register TASK *task;
  205.  
  206.  
  207.     if ((task = HeadTqueue(taskq)) != TNULL)
  208.     {
  209.         do
  210.         {
  211.             task->t_tleft -= deltime;
  212.  
  213.             task = task->t_next;
  214.         }
  215.         while (task != TNULL);
  216.     }
  217.  
  218. }
  219.  
  220.  
  221.  
  222. /*----------------------------------------------------------------------
  223. PROCEDURE
  224.     SET_TNEXT  -  set time to next sampling, tnext
  225.  
  226. SYNOPSIS
  227.     static void set_tnext(stlq, urgentq)
  228.     TQUEUE *stlq, *urgentq;
  229.  
  230. PARAMETERS
  231.     stlq    -  stl task queue
  232.     urgentq -  queue of urgently waiting tasks
  233.  
  234. REMARKS
  235.     Uses side-effects to change tnext.  
  236.  
  237.     Tnext is the minimum of (curtask->tsamp, stlq->tleft)
  238.  
  239. LAST UPDATE
  240.     10 April 1988
  241.         special background version, ignore urgentq.
  242. ----------------------------------------------------------------------*/
  243.  
  244. static void set_tnext(stlq, urgentq)
  245. TQUEUE *stlq, *urgentq;
  246. {
  247.     register TASK *task;
  248.  
  249.  
  250.     tnext = MAXLONG;            /* re-initialize for comparison */
  251.  
  252.     if (((task = HeadTqueue(stlq)) != TNULL) && (task->t_tleft < tnext))
  253.         tnext = task->t_tleft;
  254.     
  255.     if ((curtask != TNULL) && (curtask->t_tsamp < tnext))
  256.         tnext = curtask->t_tsamp;
  257.  
  258. }
  259.  
  260.  
  261.  
  262. /*----------------------------------------------------------------------
  263. PROCEDURE
  264.     DEEP_BACKGROUND  -  runs when nothing else is running
  265.  
  266. SYNOPSIS
  267.     static void deep_background()
  268.  
  269. REMARKS
  270.     This is called by the non pre-emptive scheduler when waiting for
  271.     time to sample.  Currently, this routine does nothing and is used
  272.     as a place holder.  Any routine you put in here MUST BE SHORT!
  273.  
  274. LAST UPDATE
  275.     12 March 1985
  276. ----------------------------------------------------------------------*/
  277.  
  278. static void deep_background()
  279. {
  280.     int i;
  281.  
  282.  
  283.     for (i = 0; i < 500; i++)   /* idle loop */
  284.         ;
  285.  
  286. }
  287.  
  288.  
  289.