6.31.1.1 Basic multi-tasking

Tasks can be created with newtask or newtask4 with a given amount of stack space (either all the same or each stack’s size specified). The task returned by the following words is a single cell that serves as reference to the task.

newtask ( stacksize – task  ) gforth-experimental

creates task; each stack (data, return, FP, locals) has size stacksize.

task ( ustacksize "name" –  ) gforth-experimental

creates a task name; each stack (data, return, FP, locals) has size ustacksize.
name execution: ( – task )

newtask4 ( u-data u-return u-fp u-locals – task  ) gforth-experimental “newtask-four”

creates task with data stack size u-data, return stack size u-return, FP stack size u-fp and locals stack size u-locals.

If you don’t know which stack sizes to use for the task, you can use the size(s) of the main task:

stacksize ( – u  ) gforth-experimental

u is the data stack size of the main task.

stacksize4 ( – u-data u-return u-fp u-locals  ) gforth-experimental “stacksize-four”

Pushes the data, return, FP, and locals stack sizes of the main task.

A task is created in an inactive state. To let it run, you have to activate it with one of the following words:

initiate ( xt task –  ) gforth-experimental

Let task execute xt. Upon return from the xt, the task terminates itself (VFX compatible). Use one-time executable closures (see :}h1, see Closures) to pass arbitrary paramenters to a task.

You can also do creation and initiation in one step:

execute-task ( xt – task  ) gforth-experimental

Create a new task task with the same stack sizes as the main task. Let task execute xt. Upon return from the xt, the task terminates itself.

Apart from terminating by running to the end, a task can terminate itself with kill-task. Other tasks can terminate it with kill.

kill-task ( ) gforth-experimental

Terminate the current task.

kill ( task –  ) gforth-experimental

Terminate task.

Tasks can also temporarily stop themselves or be stopped:

stop ( ) gforth-experimental

stops the current task, and waits for events (which may restart it)

stop-ns ( timeout –  ) gforth-experimental

Stop with timeout (in nanoseconds), better replacement for ms

stop-dns ( dtimeout –  ) gforth-experimental

Stop with dtimeout (in nanoseconds), better replacement for ms

thread-deadline ( d –  ) gforth-experimental

stop until absolute time d in nanoseconds, base is 1970-1-1 0:00 UTC, but you usually will want to base your deadlines on a time you get with ntime.

Using stop-dns is easier to code, but if you want your task to wake up at regular intervals rather than some time after it finished its last piece of work, the way to go is to work with deadlines.

halt ( task –  ) gforth-experimental

Stop task (no difference from sleep)

sleep ( task –  ) gforth-experimental

Stop task (no difference from halt)

A task restarts when the timeout is over or when another task wakes it with:

wake ( task –  ) gforth-experimental

Wake task

restart ( task –  ) gforth-experimental

Wake task (no difference from wake)

There is also:

pause ( ) gforth-experimental

voluntarily switch to the next waiting task (pause is the traditional cooperative task switcher; in the pthread multitasker, you don’t need pause for cooperation, but you still can use it e.g. when you have to resort to polling for some reason). This also checks for events in the queue.