Interrupting a Round Robin Dispatcher

David Dymm dymm at b.cs.wvu.wvnet.edu
Sat Mar 11 02:06:17 AEST 1989


    First, THANK YOU to all of the people who took the time
to answer my first (& second) requests for help on the
interrupt handler problem.

    I have a second problem that also involves interrupt handlers,
but is somewhat different from the previous problems.
I would appreciate comments, criticisms, laughter, etc. about
the following architecture, and answers to the questions at
the end.

    The architecture of the system is as follows (running on
BSD 4-2 Unix on a Sun 3 and/or 4):


	Kernel (single process) |   Separate Tasks (separate processes)
	------			|   -----------------------------------
			        |
	Round-Robin Dispatcher	|	task1
				|	task2
	Query Processor		|	task3
				|	task4
				|	task5
				|	  .
				|	  .

    The round robin dispatcher loops between the separate tasks.
Each task is a separate process.  The purpose of a task is to
act as a query interface between some external user and the Kernel
The task uses IPC to communicate user queries for information to the
kernel, and to return the requested information from the kernel to the
user.  Each task is a small, efficient process used solely for
communications.  Each task is fast and will not cause appreciable
degradation of the kernel.
(Note:  The nature of the tasks is such that the above architecture
	is required.)

    Most queries from the user (via a task) to the kernel are
simple queries for information.  The query is processed quickly
by the kernel's "query processor", and the dispatcher can 
quickly move on to the next task.  The user attached to the next
task will see no appreciable time delay.

    However an Occasional query from a user will require an
"appreciable" amount of computation by the query processor.
This will delay the dispatcher and cause appreciable delays
for the waiting users.

SOLUTION (???):

    To handle these delays, use the system calls "signal" and
"ualarm".  "Signal" will interrupt the kernel in the middle
of its processing, and cause the "alarm_handler" to execute.
The alarm handler will do some minor processing, and then a
"longjmp" back to the dispatcher.  The dispatcher will then go
on to the next task.  When the dispatcher comes back to the
interrupted task, it will "longjmp" to the end (IS THIS CORRECT??)
of the alarm_handler which will do a "return (0)", and cause the
dispatcher to pick up from where it left off when the task
was interrupted.

    Assume 6 tasks where tasks 2, 5, and 6 pass queries causing
the kernel to be slow and to be interrupted.  The flow of the
dispatcher  should be:

    (top of dispatcher loop)

	task 1 -- ok

	task 2 ** slow, interrupt ==> to alarm_handler

	task 3 -- ok

	task 4 -- ok

	task 5 ** slow, interrupt ==> to alarm_handler

	task 6 ** slow, interrupt ==> to alarm_handler

 
   (back to top of dispatcher loop)

	task 1 -- ok

	task 2 ** was interrupted, so longjmp to alarm handler
		  which does a return (0)

	task 3 -- ok

	task 4 -- ok

	task 5 ** was interrupted, so longjmp to alarm handler
		  which does a return (0)

	task 6 ** was interrupted, so longjmp to alarm handler
		  which does a return (0)

    (etc .......)

PROBLEM:  the system stack after the first loop through
the dispatcher will look like the following:

	(top)
	task 6
	task 5
	task 2

When the stack gets popped in alarm_handler (via the "return (0)" ),
task 6 will get popped first.  But since task 2 got interrupted
first, I want task 2 to get popped first.

How do I manipulate the system stack to have tasks popped
in the "correct" order ???

Are there any holes/bugs/etc. with the above architecture ???

    Thanks in advance for any help, comments, criticisms, etc.


David Dymm			Software Engineer

USMAIL: Bell Atlantic Knowledge Systems,
        145 Fayette Street, Morgantown, WV 26505
PHONE:	304 291-9898 (8:30-4:30 EST)
USENET:  {allegra,bellcore, cadre,idis,psuvax1}!pitt!wvucsb!dymm
INTERNET: dymm at b.cs.wvu.wvnet.edu



More information about the Comp.unix.wizards mailing list