4/16/97  slice.txt	dkelly@fdma.com
------------------

Goal:      Implement a fixed (but selectable) round robin time-slice mechanism.

Problem:   QNX timeslicer runs at a fixed 50ms, independent of ticksize 
  (which is adjustable).  However, the process manager (independent of 
  the timeslicer) runs the highest priority "ready" task after each hardware 
  interrupt has occured, and each time a running task blocks.  Re-evaluation
  of priorities after an interrupt assures that the interrupt handler's
  "proxy" task runs immediately.

Solution:  To effectively select another timeslice, a high priority
  scheduler task must lower the priority of the current task and raise 
  the priority of the next task to run.

  This scheduler task must periodically gain control (via proxy) from a 
  hardware timer interrupt.  The period of this timer represents the 
  effective timeslice interval.  The scheduler then modifies the priorities 
  and blocks - allowing the new highest priority task to run until the timer
  expires again.

Details:   The hardware timer sends a proxy to the blocked, high priority 
  scheduler.  It unblocks only long enough to lower the priority of one
  task and raise the priority of another.  When it again blocks, the
  process manager will be required to run the highest blocked task.  Of
  course, this will be the "new" current task, not the previous one.
  The timesliced tasks themselves must never yield control (block).

Implementation:

  There are two source files, slice.c (main) and handler.c (interrupt).
The use of the Makefile is required due to special options for handler.c.

  The files one.c, two.c, three.c and four.c are the tasks to be started
by the scheduler.  Notice that they never give up their timeslice - this
is the only way that uniform timeslicing can be guaranteed by this example.

  If I were coding this applications, I would use tfork() rather than
spawning separate executables.  tfork() spawns a new pid for the tfork'd 
process but the data segment is common.  This produces a pseudo-thread.
Advantages I see to tfork()...

1. can share common ram (no need to use shm_open()...)
2. threads are killed when the parent dies (no signal handlers to write)
3. no extra files or extra load time since their code is part of the main 
  executable.

Parameters:

  SLICE_MS selects the number of milliseconds of the timeslice
  SLICE_TASKS is the nubmer of tasks to switch between
  SLICE_PRIO is the priority of the scheduler - must be higher then the
  	tasks and higher than "normal" tasks of the o/s.
  SLICE_RUN is the priority of the running process (below scheduler)
  SLICE_SLEEP is the priority of the sleeping process (below running process)

Testing:
  I have not actually verified that it is timelicing correctly.  I have only
verified that the timer is firing 1000 times per second and that priorities
are being altered.  I do know that 100% of the processor is being spent at
priority SLICE_RUN.

Problems:
  The timeslicer itself is also tinkering with the priorities.  If it runs
AFTER us on every 50th timer event, it could introduce some inconsistency
to the time slices.  However, this scheduler would restore its own order
withing 1 ms. 
