EternalLines.com: Components: Micro Threads: Documentation 

Micro Threads

1.  Introduction

    Micro-threads are light-weight threads that run in a single system
    thread. Micro-threads are cooperatively scheduled by the user, unlike
    system threads which are pre-emptively scheduled by the operating
    system.

    Micro-threads are also called user threads or cooperative routines.
    Windows Fibers is an example of a micro-thread implementation.

    A switcher is responsible for doing the context switch when execution
    is transferred between two micro-threads.

2.  Switcher Object

    The switcher object must be constructed in the system thread it intends
    running in; and in addition, all switcher methods must be called from
    within that same system thread.

    The cMicroThreads.pas unit implements two switcher objects.

    TFiberSwitcher uses Windows Fibers to do task switching.
    Experiments have shown that Windows 2000 can handle in the order of two
    hundred fibers per thread.

    TWintelSwitcher is a low level implementation for Windows.
    It can handle hundreds of thousands of tasks per thread.

2.1 Methods

    function  Add (
              const RunProc : TMicroThreadRunProc;
              const StackSize : Integer = -1;
              const Data : Pointer = nil ) : TMicroThreadHandle

    Call Add to create a new micro-thread. It returns a handle to the new
    micro-thread. The micro-thread only starts execution when it is activated
    by a call to SwitchTo.

    function  GetCurrent : TMicroThreadHandle;

    GetCurrent returns a handle of the currently executing micro-thread.
    When a switcher is created, there exists one micro-thread for the
    currently running thread.

    procedure Delete (
              const Handle : TMicroThreadHandle )

    Delete removes a micro-thread previously created by a call to Add.
    The initial thread and the currently running thread can not be deleted.

    procedure SwitchTo (
              const Handle : TMicroThreadHandle )

    function  GetPrimary : TMicroThreadHandle

    function  GetCount : Integer

3.  Flow of execution

    A call to SwitchTo is invalid to a terminated micro-thread. A micro-
    thread terminates when it returns normally or when an exception is
    raised. When a thread terminates, control is returned to the primary
    micro-thread. When an exception is raised in a non-primary micro-thread,
    the exception is re-raised in the primary micro-thread. The primary
    micro-thread follows normal exception handling and flow of execution
    rules.

    Because the primary micro-thread never terminates, and because execution
    returns to the primary micro-thread when other micro-threads terminate
    or raise an exception, it is useful to use the primary thread as a
    scheduler for the other threads.

4.  Examples

4.1 Using the switcher object directly

    uses cMicroThreads;

    var Switcher : TWintelSwitcher;           // The switcher object
        T1, T2   : TMicroThreadHandle;        // Handles to Task1 and Task2

    procedure Task1(const Data: Pointer);
    begin
      Writeln('Task1.1');
      Switcher.SwitchTo(T2);                 // Switch to Task2
      Writeln('Task1.2');
      Switcher.SwitchTo(T2);                 // Switch to Task2
    end;

    procedure Task2(const Data: Pointer);
    begin
      Writeln('Task2.1');
      Switcher.SwitchTo(T1);                 // Switch to Task1
      Writeln('Task2.2');
    end;

    begin
      Switcher := TWintelSwitcher.Create;    // Create switcher object
      T1 := Switcher.Add(Task1);             // Add Task1 and save handle
      T2 := Switcher.Add(Task2);             // Add Task2 and save handle
      Switcher.SwitchTo(T1);                 // Switch to Task1
      Writeln('Fin');                        // Returns here when tasks complete
      Switcher.Free;                         // Destroy switcher object
    end.

    The output of the above code will be:

        Task1.1
        Task2.1
        Task1.2
        Task2.2
        Fin