Multitasking Example

Here is a sample session in the interpreter showing how to awaken a background task. See riscy.forth for the definitions. Here is a quick glossary:

BG1
the task itself, BG1 returns the address of the task control block.
BGCOUNTER
a variable that the background task will increment but that is readable by any task.
TSTBG
the word that background task BG1 executes. It repeatedly adds 1 to the variable BGCOUNTER.
INIT-TASK
is used in the definition of INIT to initialize BG1. (See riscy.forth for definition of INIT.)
WAKE
wakes a task.
SLEEP
puts a task to sleep.
PAUSE
the key to it all. Switches control from the task that executes PAUSE to the next task in the task list.
MAIN?
answers whether the given task is the foreground task.
STOP
put the current task to sleep. It checks to see if the current task is the foreground task and, if so, refuses to put it to sleep.

Below is the session. First, in Lisp, we start the interpreter. Then we type the Forth commands to show off the multitasker. We put 99 98 99 on the stack to have a convenient known value that we can display with .S. We check the value of BGCOUNTER before waking the task and find its uninitialized value. See the definition of TSTBG which will first set BGCOUNTER to zero and then begin incrementing it. Comments about the session are in square brackets.


 (interp)                          [start the interpreter]
hello                              [the target says "hello"]
                                   [press Enter several times]
 ok                                [the interpreter says ok]

 ok
.S                                 [show the stack]
Stack:  3959422934 3844988932 1 ok
99 98 99                           [put recognizable numbers on the stack]
 ok
.S
Stack:  99 98 99 ok
HERE U.                            [show next free location in RAM memory]
 1073742848 ok
.S
Stack:  99 98 99 ok
BGCOUNTER ?                  [check the value of the variable]
14221288  ok                 [it's just random garbage]
BG1 WAKE                     [wake up the task]
 ok
BGCOUNTER ?                  [The variable is incremented only when]
14221288  ok                 [the background task runs and it runs ]
PAUSE                        [when PAUSE transfers control.        ]
 ok
BGCOUNTER ?
9  ok
1000 MS                      [MS executes PAUSE a lot, thus the    ]
 ok                          [ variable increments a lot.          ]
BGCOUNTER ?
8239  ok
BGCOUNTER ?
8244  ok
500 MS
 ok
BGCOUNTER ?
12363  ok
.S
Stack:  99 98 99 ok
BGCOUNTER ?
12369  ok
500 MS
 ok
BGCOUNTER ?
16501  ok
.S
Stack:  99 98 99 ok
BG1 SLEEP                    [SLEEP removes the task from the task list]
 ok
BGCOUNTER ?
16507  ok
BGCOUNTER ?
16507  ok
500 MS
 ok
BGCOUNTER ?
16507  ok                    [thus the variable is no longer incremented]
BG1 WAKE                     [until it awakened and gets control
again. ]
 ok
BGCOUNTER ?
16507  ok
500 MS
 ok
BGCOUNTER ?
20627  ok
BG1 SLEEP
 ok
STOP                         [Try to put the foreground task to sleep]
Cannot put main terminal task to sleep
Sorry that didn't work out.
 ok

TERMINAL MAIN? .             [Yes, TERMINAL is the main foreground task.]
 -1 ok

TERMINAL SLEEP               [Try again to put foreground task to sleep.]
Cannot put main terminal task to sleep
Sorry that didn't work out.
 ok