From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!wuarchive!mit-eddie!mit-amt!snorkelwacker!spdcc!merk!alliant!linus!eachus From: eachus@aries.mitre.org (Robert I. Eachus) Newsgroups: comp.lang.ada Subject: Re: Fixed Frame Scheduling Message-ID: Date: 5 Dec 89 17:13:16 GMT References: <23041@gryphon.COM> Sender: news@linus.UUCP Organization: The Mitre Corporation, Bedford, MA In-reply-to: bagpiper@pnet02.gryphon.com's message of 4 Dec 89 06:20:25 GMT List-Id: In article <23041@gryphon.COM> bagpiper@pnet02.gryphon.com (Michael Hunter) writes: > (What I mean by fixed frame scheduler is the ability to start the > execution of a task for some predetermined amount of time, and then > cut it off. This looks like round robin scheduling with very well > defined time slices. I just havn't figured out how to allow the > calling task to get control back from the acceptor.) The answer to the original question is easy. However, every time I give it to someone requesting a cyclic scheduler, they want some other solution. (Which is in general a "good thing", the other solutions are easier in Ada, and usually don't cause the plane to crash.) First of all, the executive has to have a priority higher than all the application tasks. Then each application task calls a specific entry of the executive which is accepted (every appropriate clock interval) to allow the application to run: task EXECUTIVE is entry CLOCK_INTERRUPT; entry GO(1..N); pragma PRIORITY(PRIORITY'LAST); end EXECUTIVE; An entry family makes the example simpler, but an actual application will usually have many different entry declarations. Notice that under no circumstances do you want two tasks queueing for the same executive entry. task body EXECUTIVE is begin -- Create and initialize application tasks here or in the main -- program. loop for I in 1..N loop accept CLOCK_INTERRUPT; accept GO(I); end loop; -- Now check for out of control tasks. Note that in this -- version a timing slot is dedicated to this purpose. -- Alternatives are to make this part of one of the -- application tasks, or to check each task during its time -- slot (using selective waits). Implementation of the -- alternatives is left to the designer. accept CLOCK_INTERRUPT; for I in 1..N loop if GO(I)'COUNT = 0 -- Uh oh! then abort TASKS(I); TASKS(I) := NEW_TASK(I); end if; end loop; end loop; end EXECUTIVE; Application tasks look like: task type APPLICATION_TASK is begin loop EXECUTIVE.GO(I); DO_SOMETHING; end loop; end APPLICATION_TASK; If the task priorities are equal to their index, then lower priority tasks come earlier in the cycle and are allowed to use any free time later in the schedule without being aborted. During development of course the executive should check immediately for overruns. Once you start writing executives and application tasks like this, as I said above, the system designer will ask for some less draconian paradigm which shuffles resources to meet current requirements. With this design it is very easy to do. For example, you may want to allow some tasks to skip one cycle of input before it is killed, or some high priority tasks can be allowed to overrun their slot and prevent a lower priority task from ever being started. By the time you are finished the design will look nothing like what you started out to build, BUT 1) The changes will all be in the executive program. 2) The system will be much more robust in the face of unanticipated loads. 3) You may never execute an abort statement. Good luck... -- Robert I. Eachus with STANDARD_DISCLAIMER; use STANDARD_DISCLAIMER; function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...