The multi-tasker is not loaded in the system by default so the file TASK.F in the lib folder should be included in any program that multi-tasks, unless using the file MULTITHR.F (also in the lib folder) which includes it automatically.
Multi-tasking in Win32Forth is accomplished by using the Windows® multi-tasker. This is a pre-emptive multi-tasker.
The task control block (also known as task-block or TCB) is a small structure either alloted in the dictionary or allocated on the heap containing information about a task.
When a task is created the operating system allocates a stack for the task. Win32Forth splits this stack into three regions, a return stack, a User area and a data stack. The address of this User area is stored in thread local storage so that callbacks have access to the correct User area for the task (Versions prior to V6.05 always used the main task's User area for callbacks). When a task starts the contents of the User area are undefined except
All other User variables used by a task should be explicitly set before use. If the task uses floating-point words then FINIT should be called first.
cell field+ task>parm ( task-block -- addr ) \ W32F Task
Convert the task-block address into the address of the thread parameter
cell field+ task>id ( task-block -- addr ) \ W32F Task
Convert the task-block address into the address of the thread id
cell field+ task>handle ( task-block -- addr ) \ W32F Task
Convert the task-block address into the address of the thread handle
cell field+ task>stop ( task-block -- addr ) \ W32F Task
Convert the task-block address into the address of the the stop flag
: task>parm@ ( task-block -- parm ) \ W32F Task
Fetch the parameter from the task-block.
1 proc ExitThread as exit-task ( n -- ) \ W32F Task
Exit the current task returning the value n to the operating system, which can be retrieved by calling GetExitCodeThread. The stacks and user area for the thread are freed and DLLs are detatched. If the thread is the last active thread of the process then the process is terminated.
: create-task ( task-block -- flag ) \ W32F Task
Create a new task which is suspended. Flag is true if successful.
: run-task ( task-block -- flag ) \ W32F Task
Create a new task and run it. Flag is true if successful.
: suspend-task ( task-block -- flag ) \ W32F Task
Suspend a task. Flag is true if successful.
: resume-task ( task-block -- flag ) \ W32F Task
Resume a task. Flag is true if successful.
: stop-task ( task-block -- ) \ W32F Task
Set the stop flag of the task block to true.
: task-sleep ( n -- ) \ W32F Task
Suspend the current task for at least n msec. If n is INFINITE (-1) the task is suspended forever.
: (task-block) ( parm cfa-task addr -- len ) \ W32F Task
Build a task block at the supplied address, initialise the parameter and xt and return the size of the task block.
: task-block ( parm cfa-task -- addr ) \ W32F Task
Build a task block in the dictionary, initialise the parameter and xt and return the address of the block.
: task-stop? ( task-block -- flag ) \ W32F Task
Flag is true if stop-task has been set by another task. In this case the task should do any necessary clean-up and exit.
Since the multi-tasker is pre-emptive it is sometimes necessary to restrict access to resources to a single task to prevent inteference between different tasks. Win32Forth provides a set of words for efficiently locking sections of code. The system also contains some locks used internally that are transparent to the user.
: lock ( lock -- ) \ W32F Lock
If another thread owns the lock wait until it's free, then if the lock is free claim it for this thread, then increment the lock count.
: unlock ( lock -- ) \ W32F Lock
Decrement the lock count and free the lock if the resultant count is zero.
: trylock ( lock -- fl ) \ W32F Lock
For NT4, w2k and XP;
If the lock is owned by another thread return false.
If the lock is free claim it for this thread,
then increment the lock count and return true.
For Win9x, and NT<4;
Perform the action of LOCK and return true.
: (make-lock) ( -- lock ) \ W32F Lock
Make a new lock, and return it's identifier.
: make-lock ( compiling: -<name>- -- runtime: -- lock ) \ W32F Lock
Create a new lock. When executed the lock returns it's identifier.
Before using FORGET or executing MARKER words unlock any locks which are about to be forgotten to avoid memory leaks AND exit any threads which will be forgotten to avoid CRASHING !! YOU HAVE BEEN WARNED
Document $Id: p-task.htm,v 1.11 2007/05/26 10:24:11 dbu_de Exp $