What words typically make up a simple co-operative multitasking word set?
From a very preliminary review I can find words such as PAUSE, ACTIVATE,
WAKE, SLEEP, and TASK, along with a "Linked list of tasks."
Can a simple co-operative multitasking design make use of system timer
: Can anyone direct me to URLs that discuss co-operative multitasking,
: preferably in Forth?
: What words typically make up a simple co-operative multitasking word set?
: From a very preliminary review I can find words such as PAUSE, ACTIVATE,
: WAKE, SLEEP, and TASK, along with a "Linked list of tasks."
Forth, Inc's mulitasker has a linked list of tasks, where each task
has a "next" pointer and a status word, which is either WAKE or JUMP.
WAKE means the task is ready to run, JUMP means skip this task and try
the next one.
When a task runs, its status is changed from WAKE to JUMP. The word
PAUSE sets the task's status to WAKE and jumps to the next task in the
list. The word STOP jumps to the next task in the list without
changing the task's status.
Generally speaking, one very rarely sees PAUSE used in application
code at all. Whenever a task performs I/O, it puts its address into a
variable associated with that hardware, does something to the hardware
(such as issuing a request), and calls STOP. When the device has
finished, an interrupt occurs, which changes the task's status to
WAKE. Later, the task is awoken and continues from the point where it
called STOP. PAUSE might be used in a very time consuming loop, but
I've never seen it done.
Polled I/O might do something like:
BEGIN PAUSE READY? UNTIL OUTPUT
but this is very ineffieicent in a multitasking system, and not
: Can a simple co-operative multitasking design make use of system timer
: facilities ?
Yes, but generally such timers are only used for programmed time
delays and a real-time clock.
I've done it (with PolyForth) in a ROMmed application that controlled
three conveyor lines, an assembly station with three robots, and many
actuators along the lines. For many of the devices, the robots included,
interrupts weren't available. With a 4 MHz Z80, we had comfortably
enough time. ... JYA
> Polled I/O might do something like:
> BEGIN PAUSE READY? UNTIL OUTPUT
> but this is very ineffieicent in a multitasking system, and not
> : Can a simple co-operative multitasking design make use of system timer
> : facilities ?
> Yes, but generally such timers are only used for programmed time
> delays and a real-time clock.
If my address has "x" or "z" in it, remove them to reply.
Speak sweetly. You'll be glad you did if you have to eat your words.
Our word set is:
xpause. ( --) Sets the task_status to wake and exits task
xwait ( n --) Sets the task re activation time to current time + n,
sets the task status to wake and exits the task
xcycle ( n--) Sets the task activation time to last activation time +n
sets task_status to wake and exits the task
xsleep ( --) Sets the task status to sleep.
xnext ( --) Exits the current task
xoff ( --) Set the task status to sleep and exit
xtest ( set the current status to test and exit
There are also more exotic ones line
xawait ( queue --) Wait until an item is queued
Why xsleep xnext? can't you use xoff.
When a task is put to sleep until some external event wakes it up the
sequence has to be
set_up_status activate_external_task_that _will_cause_event exit_task
The code becomes
xsleep activate_other xnext
Why xtest xnext? Can't you use xwait.
Same explanation as above. Better combination to use as the task will
be reactivated even if the even doesn't occur. On reactivating the
task_status will still be set to test if time-out, it will be set to
wake if the event occurred. There is another word to test this
By now it should be clear all multi-tasker words start with x.
Why xcycle and xwait?
xwait uses the current time and adds the activation time, if the task
isn't activated spot on time a slip occurs, from the system load point
of view iti s best to let the slip happen, but there are times when you
want the task activated 10 times a sec if it happens at 0 110 90 100 120
80 etc. that's ok. This application requires xcycle.
With xwait the activation time would be 0 110 100 100 120 100.
Using the clock.
It is best to have the clock interrupt increment a cell and decrement
another. The time delays are then set by using one of the counts adding
an offset and storing. The test is done by taking the stored value and
adding to the other count, when you no longer get a carry you have timed
out and it is time for action.
Running the multitasker.
I prefer to have a trap instruction at the start of each task, and a
cell containing the task status. I know others use different
instructions as a task status, but writing to your instruction stream
can cause considerable delays on some processors. And even when I went
to school it was discouraged.
Single or multiple loops the action of the task trap instruction is the
same. If the task is asleep return to the instruction that is at the
start of the next task, if the test is to be awakened start the task, if
it is has a xtest status do you clock test, if time-out start, if not
jump to next.
So the answer to your question can the clock be involved is yes even
for a single loop.
Tasks with into the loop only have to save the forth state when they are
suspended. In our case this is the return stack onto the data stack and
data stack to the user are. Our forth is subroutine threaded and the PC
is already on the stack.
A single loop is the simplest but suffers from one major problem, time
critical tasks are stopped by bill smith doing a compile in another, or
To solve this you go to multiple loops. In a multiple loop system you
have the clock restart the high priority loop as well as update the
This requires the saving of the machine state. If you make the clock the
lowest priority interrupt then the machine states can be stacked on the
supervisor stack. This is the fastest option as only the clock routine
has to see if the task priority has to change. This is a vary acceptable
solution if you don't mind writing things for other events in interrupt
If you want to write the code for all events as user tasks you need to
go to the next step.
Multiple task levels for different events, when an event occurs a flag
is set for the levels that have to be dealt with and the priority
raised to that event. When the CPU moves from supervisor to user the
required task level is checked and the priority adjusted accordingly. If
you use this method every exception has to check if we are switching
from supervisor to user. If switch to user it has to see if the priority
is being raised.
If you want do this with a coldfire I can help you, I am currently
converting our system to ANS forth and plan on putting it up under the
wil blake wrote:
> Can anyone direct me to URLs that discuss co-operative multitasking,
> preferably in Forth?
> What words typically make up a simple co-operative multitasking word
> From a very preliminary review I can find words such as PAUSE,
> WAKE, SLEEP, and TASK, along with a "Linked list of tasks."
> Can a simple co-operative multitasking design make use of system timer
> facilities ?
> Thank you,
> Wil Blake
My Forth underview includes an introduction to on the traditional Forth
co-operative multitasking system: