home *** CD-ROM | disk | FTP | other *** search
- MPTSK(3C) "MP-UNIX" Programmer's Manual MPTSK(3C)
-
-
-
- NAME
- mptsk - cluster for multitask scheduling and communications
-
-
- SYNOPSIS
- #include "mptsk.h" /* (also link in mptsk libarary) */
-
- typedef struct _MPBOX MPBOX, PTR MPBOXID; /* Mailbox */
- typedef MPRNG MPMSG, PTR MPMSGID; /* Message */
- typedef struct _MPTSK MPTSK, PTR MPTSKID; /* Task */
-
- typedef MPBOX MPSCD, PTR MPSCDID; /* Schedule Mailbox */
-
-
- /* INITIALIZATION */
-
- void mptsk_setup(void);
-
- MPTSKID mptsk_init(VOIDPTR buf, MPTHDFN mpthdfn,
- MPSCDID mpscd);
- VOIDPTR mptsk_dinit(MPSCDID mpscd);
-
-
- /* MESSAGE/CONTROL TRANSFER FUNCTONS */
-
- MPMSGID mptsk_xfer(MPBOXID mpbox, MPMSGID mpmsg, BOOL block,
- MPSCDID mpscd);
-
- void mptsk_send(MPBOXID mpbox, MPMSGID mpmsg);
- MPMSGID mptsk_csend(MPBOXID mpbox, MPMSGID mpmsg);
- MPMSGID mptsk_recv(MPBOXID mpbox);
- MPMSGID mptsk_crecv(MPBOXID mpbox, MPMSGID mpmsg);
- void mptsk_yield(void);
- void mptsk_yieldto(MPSCDID mpscd);
- void mptsk_broadcast(MPBOXID mpbox, MPMSGID mpmsg);
-
-
- /* STATUS FUNCTIONS */
- MPTSKID mptsk_me(void);
-
- MPBOXID mptsk_mpbox(MPTSKID mptsk);
- MPBOXID mptsk_mympbox(void);
-
- MPBOXID mptsk_waitingfor(MPTSKID mptsk);
- MPBOXID mptsk_mywaitingfor(void);
-
- MPMSGID mptsk_owns(MPTSKID mptsk);
- MPMSGID mptsk_myowns(void);
-
- MPSCDID mptsk_mpscd(MPTSKID mptsk);
- MPSCDID mptsk_mympscd();
-
-
- /* DEFAULT PRIORITY SCHEDULE BOXES */
- MPSCDID mpscd_toptasks();
- MPSCDID mpscd_emergencytasks;
- MPSCDID mpscd_timecriticaltasks;
- MPSCDID mpscd_interactivetasks;
- MPSCDID mpscd_backgroundtasks;
- MPSCDID mpscd_batchtasks;
- MPSCDID mpscd_idletasks;
-
-
- DESCRIPTION
-
- The MPTSK CLUSTER is the middle (2nd) layer of the Mailbox Multitasker. It
- provides fast and flexible hiearchal scheduling and mailbox message passing
- for light-weight tasks. The design is portable and support even course-grain
- *multiprocessing*.
-
- The design is based on a mailbox abstraction. A mailbox is the laison
- between tasks and messages. When not empty, a mailbox will either contain a
- surpus of messages (waiting for tasks) or a deficit of tasks (waiting for
- messages). The tasks/messages are queued and dequeued one at a time in
- strict FIFO order.
-
- The mailboxes are used for scheduling as well as message passing. Mailboxes
- in an ordered list are treated as a schedule (mpscd); when a processor needs
- a task to run, it will choose the first task on the first mailbox with tasks.
- Lower scheduled tasks will not be run until all higher scheduled tasks are
- completed or blocked. However, since a task can yieldto its own schedule
- list it can also subschedule its time and thus provide for hiearchal or other
- kinds of scheduling.
-
- The underlying mpthd functions are still usable. With care, the programmer
- can switch between threads within a task.
-
- The schedule organization and fast message & task passing is done with the
- mprng cluster (worth looking into). It allows any data strcture to be
- efficently organized into circular lists (rings).
-
- ---
-
- mptsk_setup() initializes the cluster. It should be called after
- mpthd_setup() has been called, and before any mailbox operations are called.
-
-
- mptsk_init() and mptsk_dinit() initialize and deinitialize, returning the new
- task or old buffer. The mpscd argument of mptsk_init() indicates what
- schedule mailbox (priority) the new task should be scheduled on now and by
- default in the future (see mptsk_mpscd()); if scheduled on one of the
- mpscd_toptasks() (accessable to mptsk_xfer()), for instance, the task may
- begin running immediately. For safety, if either argument of mptsk_init() is
- nil it returns nil. Note mptsk_dinit() takes a MPSCDID as an argument; it a
- multiprocessing environment, you cannot assume a task is not running when you
- are (even when interrupts are disabled) and must wait for the task to put
- itself on a schedule box; also note, if there are no tasks in this box,
- mptsk_dinit() returns immediately with nil.
-
- mptsk_xfer() is the heart of the mailbox multitasker. Iff mpmsg is nil, it
- attempts to receive (and return) a message from the mpbox mailbox; otherwise,
- it attempts to send (and return nil) the message to mpbox. Iff block is
- false, however, and there is no message waiting / no task to receive the
- message, then mptsk_xfer() returns nil / returns the message. In the case
- when another waiting task is activated by a send, both it and the calling
- (mptsk_me()) tasks are rescheduled (on their default mptsk_mpscd() schedule
- box) and a new task to run is selected. Whenever a runable task is needed,
- the user-supplied mpscd schedule list argument (if not nil) is first checked;
- if none are found or no list is given, a task will be found from the
- mpscd_toptasks() list.
-
- Several common scheduling and communications operations can be derived from
- the mptsk_xfer() call, easily implemented as macros. mptsk_send() and
- mptsk_recv() send and receive from a mpbox with blocking, and continuous
- mptsk_csend() and mptsk_crecv() without blocking. The mptsk_yield()
- reschedules the calling task and temporarily yields its timeslice for other
- tasks; it should be called whenever a need for polling some condition (which
- cannot be explicitly (and more efficently) signaled by a mptsk_send()). The
- deluxe mptsk_yieldto() allows a parent task to yield to its own schedule of
- children tasks, thus allowing hiearchal and more elaborate schedulers to be
- built.
-
- mptsk_me() returns the current (calling) task. This function is similar (but
- independent from) the mpthd_me() function. The shorthand functions
- mptsk_my...() use mptsk_me() as their mptsk argument.
-
- mptsk_mpbox() is the task's private mailbox. This is initialized but unused
- by any of the Mailbox Multitasker functions and is provided to the user for
- his own inventive uses.
-
- mptsk_waitingfor() tells the mailbox on which a task is currently waiting (or
- nil if it is executing right now). It is maintained but not used by Mailbox.
- The associated mptsk_owns(), for use with the high (3rd) layer, returns the
- ring of resource sources the task owns. If deadlocking is a problem, these
- two pieces of information can be used to efficently find and break deadlock,
- or, better yet, detect potential deadlock and prevent it. This is left as an
- excercise for the programmer.
-
- The mptsk_mpscd() variable tells the task's default schedule box (in essence,
- its priority) on which it is scheduled by mptsk_xfer(). This is a variable
- associated with the task, and can be assigned a new schedule box to change
- the task's priority (or freeze a task).
-
- WARNING: This status information can be accessed by tasks other than the
- owner. For this reason, in pre-emptive or multiprocessing environments,
- information can be partially (non-autonomously) written by one task while it
- read by another, causing mysterious, haphazard, unrepeatable bugs. It is up
- to the user to control access to shared objects and realize which objects are
- shared.
-
- A suggested priority list of scheduling boxes is provided and initialized.
- The only required box is mpscd_idletasks. Onto this box, any selection of
- scheduling boxes (priorities) can be attached and dynamically arranged to
- suit the application needs. The highest priority box, returned by
- mpscd_toptasks(), must always be the one cyclically after (mprng_next) the
- mpscd_idletask. For example, after mptsk_setup(), mpscd_toptasks() will
- return mpscd_emergencytasks.
-
-
- RETURN VALUES & ERRORS
-
- Return values are as specified. Note the mptsk_xfer() transfer function
- returns the message iff it was not sent and returns nil iff no message was
- received.
-
- No error checking is done on the MPSCDID and MPBOXID arguments. For
- initialization functions, the MPTHDID and MPTSKID arguments are checked for
- nil value, and return nil if so.
-
- WARNING: A common error causing mysterious bugs is stack overflow within the
- mptsk's mpthd. Though mpthd_switch() often detects this when it trys to
- switch into a corrupted mpthd, by that time it may be to late. If there
- seems to be mysterious pointer problems, try significantly increasing all the
- thread stack sizes.
-
- NOTES
-
- The multitasking interface is especially designed to take advantage of
- course-grain common-memory multiprocessor machines and to be portable to
- different "C" environments. Using the same interface, similar functionality
- can be obtained with most stack-based languages.
-
-
- AVAILABILITY & BUGS
-
- The mptsk cluster has been partially tested under MS-DOS (Turbo C). It will
- later be tested on UNIX BSD 4.3 (IBM RT, DEC VAX, & SUN). It may be easily
- ported to other machines & operating systems.
-
- SEE ALSO
- mpres(3C), mpthd(3C), mpbox(3C), mprng(3C), and the mptsk*.* files.
-
- "Building a Portable Multitasking Environment in "C":
- found in the file mptsk.tex
- "First Come, First Served", BYTE Magazine, July 1988.
-
-
- AUTHOR
-
- Copyright (C) 1987, 1988 Michael Benjamin Parker (USA SS# 557-49-4130)
-
- This interface, code, and documentation may be freely distributed *at no cost*
- provided the copyright notices are preserved and modifications are forwarded
- to the author (for inclusion in future releases). See the file "mpthd.cpy"
- for specific details. All other rights reserved.
-
- mbparker@ATHENA.MIT.EDU / 721 E Walnut, Orange, CA 92667-6833 / 714-639-9497
-
- Created: 4/1/88 Release: 0.7 Version: 06/27/88
-