|##########|
|#MAGIC   #|CKOLFLGN
|#PROJECT #|""
|#PATHS   #|"StdProject"
|#FLAGS   #|xx---x--x---xxx-----------------
|#USERSW  #|--------------------------------
|#USERMASK#|--------------------------------
|#SWITCHES#|x----xxxxx-xx---
|##########|
DEFINITION MODULE OThreads;

IMPORT Exec,System,Resources,Dos;
IMPORT OTrees,OLists;
FROM System IMPORT LONGSET,Regs;

TYPE
  Thread     = POINTER TO ThreadObj;
  MinSig     = POINTER TO MinSigObj;

  DEFINITION MODULE Threads = OTrees.StdTrees(Thread);
  DEFINITION MODULE TLists  = OLists.BiLists(MinSig);

TYPE
  MinSigObj  = OBJECT OF TLists.Node;
                 DEFERRED METHOD Wake;
               END;

  ThreadObj  = OBJECT OF Threads.Tree,MinSig AS link;
                 task       : Exec.TaskPtr;
                 returnCode : LONGINT;

                 deadSignal : Exec.TaskSignals;
                 deadMask   : Exec.TaskSigSet;

                 sigSignal  : Exec.TaskSignals;
                 sigMask    : Exec.TaskSigSet;

                 tname      : STRING(64);

                 numSons    : INTEGER;

                 context    : Resources.ContextPtr;

                 CONSTRUCTOR Create(REF name : STRING := "";pri : INTEGER := 0);

                 METHOD Wait(ticks : INTEGER);

                 METHOD Break;
                 DESTRUCTOR BreakAsynch;

                 METHOD Active():BOOLEAN;

                 METHOD Destruct;
                 METHOD link.Wake;

                 DEFERRED METHOD Code;
               END;



TYPE
  Signal     = POINTER TO OBJECT OF TLists.List;
                 CONSTRUCTOR Create;
                 METHOD Wait;
                 METHOD Send;
                 METHOD Destruct;
               END;

  SigNode    = POINTER TO SigNodeObj;

  DEFINITION MODULE SLists = OLists.BiLists(SigNode);

TYPE
  SignalList = POINTER TO OBJECT OF SLists.List;
                 CONSTRUCTOR Create(sigs : LIST OF Signal);
                 METHOD Wait;
                 task : MinSig;
               END;

  SigNodeObj = OBJECT OF SLists.Node,MinSig AS link;
                 signal  : Signal;
                 list    : SignalList;
                 METHOD link.Wake;
               END;

EXCEPTION
  SigListOccupied    : "Signallist occupied";
  SemaphoreNotLocked : "Semaphore not locked";

TYPE
  Semaphore  = POINTER TO OBJECT OF Signal;
                 useCount : INTEGER;
                 METHOD LockShared;
                 METHOD LockExclusive;
                 METHOD Release;
               END;

  Rendezvouz = POINTER TO OBJECT OF Signal AS emitter,
                                    Signal AS acceptor;
                 METHOD accepts():BOOLEAN;

                 METHOD Accept;
                 METHOD Emit;
               END;

  Rendezvouz2= POINTER TO OBJECT OF Signal AS emitter,
                                    Signal AS acceptor,
                                    Signal AS sleeper,
                                    Signal AS waker;
                 METHOD accepts():BOOLEAN;

                 METHOD Accept;
                 METHOD Emit;
                 METHOD Reply;
               END;

VAR ActiveThread : Thread;

END OThreads.

