Win32Forth


Using the Task Wordset


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

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.

The User Area

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.

Glossary

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.

Locking Resources

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.

Glossary

: 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.

WARNING

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 $