home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
pmos2002.zip
/
TESTS
/
SRC
/
SEMATEST.MOD
< prev
next >
Wrap
Text File
|
1996-09-27
|
7KB
|
192 lines
MODULE SemaTest;
(********************************************************)
(* *)
(* Test program to check that the semaphore *)
(* operations work. *)
(* *)
(* Programmer: P. Moylan *)
(* Last edited: 27 September 1996 *)
(* *)
(* Description: Runs a pair of tasks in a *)
(* simple producer/consumer relationship. *)
(* *)
(* Status: Working, but ... *)
(* *)
(* Problems: *)
(* 1. Painfully slow. I'm going to have to *)
(* put a substantial improvement into *)
(* module Windows. *)
(* 2. On final exit, have to type an extra key *)
(* to get the program to shut down. This *)
(* comes from the way shutdown is handled *)
(* in Windows, and in the long term I'm *)
(* going to have to find a cleaner solution. *)
(* 3. Bug in tracing: attempting to trace kernel *)
(* causes infinite recursion. For now *)
(* kernel tracing has been removed, but *)
(* given the intended use of this program we *)
(* should find a mechanism for kernel tracing.*)
(* *)
(********************************************************)
FROM Windows IMPORT
(* type *) Window, Colour, FrameType, DividerType,
(* proc *) OpenWindow, CloseWindow, WriteString, WriteLn, Write,
PressAnyKey, ReadChar;
FROM Trace IMPORT
(* proc *) TraceOn;
FROM Semaphores IMPORT
(* type *) Semaphore,
(* proc *) CreateSemaphore, Wait, Signal;
FROM TaskControl IMPORT
(* proc *) CreateTask, TaskExit;
FROM CircularBuffers IMPORT
(* type *) CircularBuffer,
(* proc *) CreateBuffer, PutBuffer, GetBuffer;
(************************************************************************)
CONST Esc = CHR(01BH);
VAR
(* The consumer and producer tasks will communicate through a *)
(* circular buffer called "pipe". *)
pipe: CircularBuffer;
(* logwindow is a screen window used for status messages. *)
logwindow: Window;
(* The "finished" semaphore is needed so the main task will know *)
(* when the consumer and producer tasks have both exited. *)
finished: Semaphore;
(************************************************************************)
(* THE PRODUCER AND CONSUMER TASKS *)
(************************************************************************)
PROCEDURE Producer;
(* The producer task. Takes input from the keyboard, sends it to *)
(* the intertask buffer where it will be picked up by the consumer *)
(* task. Exits when a second Esc key is received (the first is *)
(* sent to the consumer task). *)
VAR datum: CHAR; EscSent: BOOLEAN;
pwindow: Window;
BEGIN
OpenWindow (pwindow, red, green, 4, 11, 0, 41, simpleframe, nodivider);
WriteString (pwindow, "Starting producer task.");
WriteLn (pwindow);
WriteString (pwindow, "Type Esc TWICE to exit from both tasks.");
WriteLn (pwindow);
EscSent := FALSE;
LOOP
ReadChar (pwindow, datum);
IF datum = Esc THEN
IF EscSent THEN EXIT(*LOOP*) END (*IF*);
EscSent := TRUE;
END (*IF*);
PutBuffer (pipe, datum);
END (*LOOP*);
WriteString (pwindow, "Producer task is now terminating.");
WriteLn (pwindow);
CloseWindow (pwindow);
Signal (finished);
TaskExit;
END Producer;
(************************************************************************)
PROCEDURE Consumer;
(* The consumer task. Takes input from the intertask buffer and *)
(* prints it, changing lower case letters to upper case. *)
(* Exits when an Esc character has been received. *)
VAR datum: CHAR;
cwindow: Window;
BEGIN
OpenWindow (cwindow, blue, cyan, 14,21, 30,69, simpleframe, nodivider);
WriteString (cwindow, "Starting consumer task.");
WriteLn (cwindow);
LOOP
datum := GetBuffer(pipe);
IF (datum >= 'a') AND (datum <= 'z') THEN
datum := CHR (ORD(datum)-ORD('a')+ORD('A'))
END (*IF*);
IF datum = Esc THEN EXIT(*LOOP*) END(*IF*);
Write (cwindow, datum);
END (*LOOP*);
WriteLn (cwindow);
WriteString (cwindow, "Consumer task is now terminating.");
WriteLn (cwindow);
CloseWindow (cwindow);
Signal (finished);
TaskExit;
END Consumer;
(************************************************************************)
(* THE TEST PROCEDURE *)
(************************************************************************)
PROCEDURE RunTheTest;
CONST ProducerPriority = 10; ConsumerPriority = 8;
VAR taskcount: CARDINAL;
BEGIN
CreateBuffer (pipe, 8);
CreateSemaphore (finished, 0);
taskcount := 0;
CreateTask (Consumer, ConsumerPriority, "Consumer");
INC (taskcount);
WriteString (logwindow, "Have created consumer task.");
WriteLn (logwindow);
CreateTask (Producer, ProducerPriority, "Producer");
INC (taskcount);
WriteString (logwindow, "Have created producer task.");
WriteLn (logwindow);
WHILE taskcount > 0 DO
Wait (finished); DEC(taskcount);
END (*WHILE*);
WriteString (logwindow,
"All tasks terminated - back in RunTheTest.");
WriteLn (logwindow);
END RunTheTest;
(************************************************************************)
(* MAIN PROGRAM *)
(************************************************************************)
BEGIN
(*TraceOn (10, 24, 0, 79, 50);*)
OpenWindow (logwindow, white, black, 0, 3, 0, 49,
noframe, nodivider);
WriteString (logwindow, "Test of semaphore operations.");
WriteLn (logwindow);
RunTheTest;
WriteString (logwindow, "End of test.");
PressAnyKey (logwindow);
CloseWindow (logwindow);
END SemaTest.