APPENDIX C
Buggy Programs
WITH Small_SP; USE Small_SP;
PROCEDURE Pgm0 IS
Value_1 : Integer := 1;
Value_2 : Integer := 2;
Value_3 : Integer := 3;
TASK T1;
TASK T2;
TASK T3;
TASK BODY T1 IS
BEGIN
Put_Line(Value_1);
END T1;
TASK BODY T2 IS
BEGIN
Put_Line(Value_2);
END T2;
TASK BODY T3 IS
BEGIN
Put_Line(Value_3);
END T3;
BEGIN
NULL;
END Pgm0;
WITH Small_SP; USE Small_SP;
PROCEDURE Pgm1 IS
TASK Std_1;
TASK Std_2;
TASK Std_3;
TASK Teacher IS
ENTRY Check_Grade(Stdnt : Integer; Grade : OUT Integer);
END Teacher;
TASK BODY Std_1 IS
My_Grade : Integer;
BEGIN
Teacher.Check_Grade(1,My_Grade);
END STD_1;
TASK BODY Std_2 IS
My_Grade : Integer;
BEGIN
Teacher.Check_Grade(2,My_Grade);
END Std_2;
TASK BODY Std_3 IS
My_Grade : Integer;
BEGIN
Teacher.Check_Grade(3,My_Grade);
END Std_3;
TASK BODY Teacher IS
Class_Grades : ARRAY(1..4) OF Integer;
I : Integer;
BEGIN
Class_Grades(1) := 35;
Class_Grades(2) := 97;
Class_Grades(3) := 85;
Class_Grades(4) := 77;
ACCEPT Check_Grade(Stdnt : Integer; Grade : OUT Integer) DO
I := Stdnt;
Grade := Class_Grades(I);
END Check_Grade;
END Teacher;
BEGIN
NULL;
END Pgm1;
WITH Small_SP; USE Small_SP;
PROCEDURE Pgm2 IS
Result1,
Result2 : Integer;
TASK T1;
TASK T2;
TASK BODY T1 IS
BEGIN
Result1 := 0;
FOR I IN 1..20 LOOP
Result1 := Result1 + 20;
END LOOP;
END T1;
TASK BODY T2 IS
BEGIN
Result2 := 0;
FOR I IN 1..30 LOOP
Result2 := Result2 + 30;
END LOOP;
END T2;
BEGIN
Put("Result1 = ");
Put(Result1);
New_Line;
Put("Result2 = ");
Put(Result2);
New_Line;
END Pgm2;
-- This program outputs the maximum value that is stored into a table. It accomplishes that by using
-- concurrency by means of two tasks. Each task does exactly the same thing, but working with a different
-- region of the table. The first statement of each task is an accept statement which is used for communication
-- with the main program that is also a task. This accept statement is used to pass the "region" of the table that
-- the task will work with. A second accept statement is used after the task has found the maximum value. The
-- accept is used here to pass to the main program the maximum value Found.
WITH Small_SP; USE Small_SP;
PROCEDURE Pgm3 IS
Table_Of_Values : ARRAY(1..40) OF Integer;
Max_Value : Integer;
Max_Value1 : Integer;
Max_Value2 : Integer;
TASK Search_1 IS
ENTRY Start (Lower_Bound, Upper_Bound : Integer);
ENTRY Max_Is(Max_Val : OUT Integer);
END Search_1;
TASK Search_2 IS
ENTRY Start (Lower_Bound, Upper_Bound : Integer);
ENTRY Max_Is(Max_Val : OUT Integer);
END Search_2;
TASK BODY Search_1 IS
Temp : Integer := -20000;
Lb, Ub : Integer;
BEGIN
-- Synchronize with the main program by
-- waiting for a call from the main program
ACCEPT Start(Lower_Bound, Upper_Bound : Integer) DO
-- The rendezvous has been established
Lb := Lower_Bound;
Ub := Upper_Bound;
END Start; -- The rendezvous has been completed
-- Now, run concurrently
FOR I IN Lb..Ub LOOP
IF Table_Of_Values(I) > Temp THEN
Temp := Table_Of_Values(I);
END IF;
END LOOP;
-- Now, synchronize again with the main program and
-- pass to it the maximum value found
ACCEPT Max_Is(Max_Val : OUT Integer) DO
Max_Val := Temp;
END Max_Is;
-- The task will now complete its execution
-- and terminate.
END Search_1;
TASK BODY Search_2 IS
Temp : Integer := -20000;
Lb, Ub : Integer;
BEGIN
-- Synchronize with the main program by
-- waiting for a call from the main program
ACCEPT Start(Lower_Bound, Upper_Bound : Integer) DO
-- The rendezvous has been established
Lb := Lower_Bound;
Ub := Upper_Bound;
END Start; -- The rendezvous has been completed
-- Now, run concurrently
FOR I IN Lb..Ub LOOP
IF Table_Of_Values(I) > Temp THEN
Temp := Table_Of_Values(I);
END IF;
END LOOP;
-- Now, synchronize again with the main program and
-- pass to it the maximum value found
ACCEPT Max_Is(Max_Val : OUT Integer) DO
Max_Val := Temp;
END Max_Is;
-- The task will now complete its execution
-- and terminate.
END Search_2;
BEGIN
-- Store some values into the table
FOR I IN 1..40 LOOP
Table_Of_Values(I) := 41 - I;
END LOOP;
-- Start each task with half of the vector
Search_1.Start( 1,20); -- Entry calls
Search_2.Start(20,40);
-- Get the maximum value from each task
Search_1.Max_Is(Max_Value1);
Search_2.Max_Is(Max_Value2);
-- Output the resulting maximum value
Put("The maximum value is : ");
IF Max_Value1 > Max_Value2 THEN
Max_Value := Max_Value1;
ELSE
Max_Value := Max_Value2;
END IF;
Put_Line(Max_Value);
END Pgm3;