home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************
-
- FILE
- bsched.c - special abbreviated version of stlsched.c
-
- ENTRY ROUTINES
- StlDispatch - schedule and dispatch tasks
- StlStart - initialize timer
-
- PRIVATE ROUTINES
- dec_tleft - decrement t_tleft for all tasks in queue
- set_tnext - set time to next sampling instance tnext
- deep_background
-
- REMARKS
- The routines reference the STL queue as a parameter rather than
- as a global variable. This is to allow the STL queue to be
- implemented as a soft timer-driven event queue.
- Note that multiple STL queues driven by different timers can be
- easily added later, only requiring the timer-number parameter to
- be passed as well as the queue pointer.
-
- LAST UPDATE
- 11 February 1986
- add event tasktype recognition
- 14 April 1988
- make this abbreviated non-interrupt driven version
-
- Copyright (c) 1985 - 1988 D.M. Auslander and C.H. Tham
-
- ***********************************************************************/
-
- /***********************************************************************
- I M P O R T S
- ***********************************************************************/
-
- #include <stdio.h>
-
- #include "envir.h" /* environment definitions */
-
- #include "config.h" /* system configuration header */
- #include "types.h" /* type definitions */
- #include "task.h" /* task descriptor definitions */
- #include "tqueue.h" /* task queue module definitions */
- #include "dispatch.h" /* dispatcher module declarations */
- #include "time.h" /* time module definitions */
-
- extern TASK *curtask; /* pointer to current task descriptor */
-
- /***********************************************************************
- F O R W A R D D E C L A R A T I O N S
- ***********************************************************************/
-
- void dec_tleft(long, TQUEUE *);
- void set_tnext(TQUEUE *, TQUEUE *);
- void deep_background(void);
-
- /***********************************************************************
- MODULE PRIVATE DATA STRUCTURES AND VARIABLES
- ***********************************************************************/
-
- static long tnext = 0L; /* time to next sampling instance */
-
- /***********************************************************************
- E N T R Y R O U T I N E S
- ***********************************************************************/
-
- /*----------------------------------------------------------------------
- PROCEDURE
- STLDISPATCH - STL dispatcher/scheduler (background non preemptive)
-
- SYNOPSIS
- void StlDispatch(stlq, urgentq, stltimer)
- TQUEUE *stlq, *urgentq;
- int stltimer;
-
- PARAMETER
- stlq - STL task queue
- urgentq - queue of urgent waiting tasks
- stltimer - timer to use for stl scheduling
-
- REMARKS
- 1. No other scheduler can be running while this is running.
- 2. Since scheduler is background, obviously non pre-emptive.
-
- LAST UPDATE
- 10 April 1988
- specially modified to call plant simulation
- ----------------------------------------------------------------------*/
-
- void StlDispatch(stlq, urgentq, stltimer)
- TQUEUE *stlq, *urgentq;
- int stltimer;
- {
-
- for (;;) /* infinite loop */
- {
- #ifdef SIMRT
- while (!TimeUp(stltimer))
- {
- do_simul();
- chronos();
- }
- #else
- while (!TimeUp(stltimer))
- if (ReadDTimer(stltimer) > (1000L / TICKRATE))
- deep_background();
- #endif
-
- if ((curtask = GetTqueue(stlq)) == TNULL)
- panic("background StlDispatch: no task to dispatch");
-
- dec_tleft(tnext, stlq);
- set_tnext(stlq, urgentq);
-
- if (tnext > 0)
- SetDTimer(stltimer, tnext);
-
- (*curtask->t_func)(curtask->t_argp);
-
- curtask->t_tleft = curtask->t_tsamp;
-
- EnterTqueue(curtask, stlq, STL_ENTER);
- }
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- STLSTART - start STL dispatcher/scheduler module
-
- SYNOPSIS
- StlStart(stlq, urgentq, stltimer)
- TQUEUE *stlq, *urgentq;
- int stltimer;
-
- PARAMETER
- stlq - STL task queue
- urgentq - queue of urgent waiting tasks
- stltimer - timer for stl scheduling
-
- REMARKS
- This function is used to initialize this module and to start the
- STL timer. If a task is ready to run immediately (tleft == 0),
- that task is dispatched.
-
- StlStart should to be called whenever a new task (or a new group
- of tasks) is put into the STL queue since the queue may initially
- be empty and the timer not set.
-
- LAST UPDATE
- 18 March 1985
- ----------------------------------------------------------------------*/
-
- void StlStart(stlq, urgentq, stltimer)
- TQUEUE *stlq, *urgentq;
- int stltimer;
- {
-
- if (stlq == TQNULL)
- panic("StlStart: stlq is NULL");
-
- if (!EmptyTqueue(stlq))
- {
- tnext = HeadTqueue(stlq)->t_tleft;
-
- SetDTimer(stltimer, tnext);
- }
-
- StlDispatch(stlq, urgentq, stltimer);
-
- }
-
-
- /***********************************************************************
- P R I V A T E R O U T I N E S
- ***********************************************************************/
-
- /*----------------------------------------------------------------------
- PROCEDURE
- DEC_TLEFT - decrement t_tleft for all tasks in queue
-
- SYNOPSIS
- static void dec_tleft(deltime, taskq)
- long deltime;
- TQUEUE *taskq;
-
- PARAMETERS
- deltime - amount to decrement (ms)
- taskq - task queue in question
-
- REMARKS
- Normally used to decrement by tnext.
-
- LAST UPDATE
- 15 February 1985
- ----------------------------------------------------------------------*/
-
- static void dec_tleft(deltime, taskq)
- long deltime;
- TQUEUE *taskq;
- {
- register TASK *task;
-
-
- if ((task = HeadTqueue(taskq)) != TNULL)
- {
- do
- {
- task->t_tleft -= deltime;
-
- task = task->t_next;
- }
- while (task != TNULL);
- }
-
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- SET_TNEXT - set time to next sampling, tnext
-
- SYNOPSIS
- static void set_tnext(stlq, urgentq)
- TQUEUE *stlq, *urgentq;
-
- PARAMETERS
- stlq - stl task queue
- urgentq - queue of urgently waiting tasks
-
- REMARKS
- Uses side-effects to change tnext.
-
- Tnext is the minimum of (curtask->tsamp, stlq->tleft)
-
- LAST UPDATE
- 10 April 1988
- special background version, ignore urgentq.
- ----------------------------------------------------------------------*/
-
- static void set_tnext(stlq, urgentq)
- TQUEUE *stlq, *urgentq;
- {
- register TASK *task;
-
-
- tnext = MAXLONG; /* re-initialize for comparison */
-
- if (((task = HeadTqueue(stlq)) != TNULL) && (task->t_tleft < tnext))
- tnext = task->t_tleft;
-
- if ((curtask != TNULL) && (curtask->t_tsamp < tnext))
- tnext = curtask->t_tsamp;
-
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- DEEP_BACKGROUND - runs when nothing else is running
-
- SYNOPSIS
- static void deep_background()
-
- REMARKS
- This is called by the non pre-emptive scheduler when waiting for
- time to sample. Currently, this routine does nothing and is used
- as a place holder. Any routine you put in here MUST BE SHORT!
-
- LAST UPDATE
- 12 March 1985
- ----------------------------------------------------------------------*/
-
- static void deep_background()
- {
- int i;
-
-
- for (i = 0; i < 500; i++) /* idle loop */
- ;
-
- }
-
-
-