home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1994-04-20 | 4.0 KB | 175 lines | [TEXT/MEDT] |
- IMPLEMENTATION MODULE Coroutines;
- (*
- Implementation and Revisions:
- ============================
-
- Author Date Description
- ------ ---- -----------
-
- JT 7/4/94 First implementation (MacMETH_V3.2)
-
- *)
-
-
- FROM Thread IMPORT
- ThreadID,
- OSErr,
- kCooperativeThread,
- kPreemptiveThread,
- kUsePremadeThread, kNewSuspend,
- kCurrentThreadID,
- kStoppedThreadState, kReadyThreadState, kNoThreadID,
- ThreadCurrentStackSpace,
- GetCurrentThread, YieldToThread,
- GetFreeThreadCount, CreateThreadPool,
- NewThread, DisposeThread,
- SetThreadState,
- ThreadBeginCritical, ThreadEndCritical,
- ThreadsAvailable;
-
- FROM SYSTEM IMPORT VAL;
-
- CONST
- POOLSize = 5; (* How many Process-Stacks will be allocated at one time *)
- OVERHead = 2024D; (* How many bytes will be added to the requested workspace *)
-
- TYPE
- Coroutine = ThreadID;
- Process = ThreadID;
-
- VAR
- transferErr : OSErr;
-
- PROCEDURE StartThread(l : LONGINT ) : LONGINT;
- VAR
- p : PROC;
- err : OSErr;
- BEGIN
- p := VAL(PROC, l);
- p;
- err := DisposeThread(kCurrentThreadID, 0D, TRUE);
- RETURN 0D;
- END StartThread;
-
- PROCEDURE NewCoroutine(p: PROC; n: LONGINT; VAR cID: Coroutine);
- VAR
- err : OSErr;
- free : INTEGER;
- BEGIN
- err := GetFreeThreadCount(kCooperativeThread, free);
- IF err <> 0 THEN HALT; RETURN END;
- IF free = 0 THEN
- err := CreateThreadPool(kCooperativeThread, POOLSize, n + OVERHead);
- IF err <> 0 THEN HALT; RETURN END;
- END(*IF*);
- err := NewThread(kCooperativeThread,
- StartThread,
- VAL(LONGINT, p),
- n + OVERHead,
- kUsePremadeThread,
- NIL,
- cID);
- IF err <> 0 THEN HALT; RETURN END;
- END NewCoroutine;
-
-
-
- PROCEDURE Transfer(VAR fromID, toID: Coroutine);
- BEGIN
- transferErr := GetCurrentThread(fromID);
- transferErr := YieldToThread(toID);
- END Transfer;
-
- PROCEDURE FreeCoroutineWorkspace(cID : Coroutine) : LONGINT;
- VAR
- freeStack : LONGINT;
- err : OSErr;
- BEGIN
- err := ThreadCurrentStackSpace(cID, freeStack);
- IF err <> 0 THEN
- RETURN 0D;
- ELSE
- RETURN freeStack;
- END(*IF*);
- END FreeCoroutineWorkspace;
-
- PROCEDURE MyCoroutineID() : Coroutine;
- VAR
- cID : Coroutine;
- err : OSErr;
- BEGIN
- err := GetCurrentThread(cID);
- RETURN cID;
- END MyCoroutineID;
-
-
-
- PROCEDURE NewProcess(p: PROC; n: LONGINT; VAR pID: Process);
- VAR
- err : OSErr;
- free : INTEGER;
- BEGIN
- err := GetFreeThreadCount(kPreemptiveThread, free);
- IF err <> 0 THEN HALT; RETURN END;
- IF free = 0 THEN
- err := CreateThreadPool(kPreemptiveThread, POOLSize, n + OVERHead);
- IF err <> 0 THEN HALT; RETURN END;
- END(*IF*);
- err := NewThread(kPreemptiveThread,
- StartThread,
- VAL(LONGINT, p),
- n + OVERHead,
- kNewSuspend + kUsePremadeThread,
- NIL,
- pID);
- IF err <> 0 THEN HALT; RETURN END;
- END NewProcess;
-
-
- (* the process is started in suspended State *)
-
- PROCEDURE ResumeProcess(pID: Process);
-
- BEGIN
- transferErr := SetThreadState(pID, kReadyThreadState, kNoThreadID)
- END ResumeProcess;
-
-
- PROCEDURE SuspendProcess(pID: Process);
-
- BEGIN
- transferErr := SetThreadState(pID, kStoppedThreadState, kNoThreadID)
- END SuspendProcess;
-
-
- PROCEDURE MyProcessID() : Process;
- VAR
- pID : Coroutine;
- err : OSErr;
- BEGIN
- err := GetCurrentThread(pID);
- RETURN pID;
- END MyProcessID;
-
-
- PROCEDURE BEGINCriticalSection();
- VAR
- err : OSErr;
- BEGIN
- err := ThreadBeginCritical();
- END BEGINCriticalSection;
-
-
- PROCEDURE ENDCriticalSection();
- VAR
- err : OSErr;
- BEGIN
- err := ThreadEndCritical();
- END ENDCriticalSection;
-
-
-
- BEGIN
- IF NOT(ThreadsAvailable()) THEN HALT; END; (* Thread Package not available *)
- END Coroutines.