From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=BAYES_00, PP_MIME_FAKE_ASCII_TEXT autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII X-Google-Thread: ffc1e,b69f59721bf77f6a,start X-Google-Attributes: gidffc1e,public X-Google-Thread: 103376,b69f59721bf77f6a,start X-Google-Attributes: gid103376,public From: "James S. Rogers" Subject: Ada Protected Object Tutorial #3: Simple Tasks Date: 1999/12/20 Message-ID: <83ms0t$7ql$1@bgtnsc01.worldnet.att.net> X-Deja-AN: 563250626 X-MimeOLE: Produced By Microsoft MimeOLE V4.72.2106.4 X-Complaints-To: abuse@worldnet.att.net X-Trace: bgtnsc01.worldnet.att.net 945746781 8021 12.74.130.95 (21 Dec 1999 03:26:21 GMT) Organization: AT&T WorldNet Services NNTP-Posting-Date: 21 Dec 1999 03:26:21 GMT Newsgroups: comp.programming.threads,comp.lang.ada Date: 1999-12-21T03:26:21+00:00 List-Id: An example of tasks and rendezvous The following simple tasking example illustrates the basic uses of tasks and rendezvous. A rendezvous consists of an entry called by one task and accepted by another. Each task specification defines the entries it handles. Parameters may be passed during a rendezvous. A rendezvous causes the tasks involved to synchronize. The task calling the entry will suspend until the task accepting the entry reaches the accept statement. The task accepting the entry will suspend until a task calls that entry. The following example is complete in a single file. It also demonstrates Ada �s ability to nest tasks within procedures, and Ada�s ability to easily manipulate time/date information. The task type is declared, including the implementation of the class. An array type is then declared containing 10 elements of the task type. Finally, an instance of the array of task types is declared. The tasks actually begin executing upon the declaration of the instance �Jobs�. They do not go very far because each task suspends until its �Start� entry is called. The Start entry passes in a parameter of type Integer. The task doubles that value, waits 1.0 seconds, then suspends on the accept statement for the �Stop� entry. The main procedure gets the value passed out of the task during the �Stop� entry. The subtraction operation for two time values returns a duration value, which is measured in seconds. ------------------------------------------------------------ -- Simple Tasking Example -- -- This program illustrates a simple use of the Ada -- Rendezvou for communicating results between tasks. ------------------------------------------------------------ with Ada.Text_Io; with Ada.Integer_Text_Io; with Ada.Calendar; use Ada.Calendar; procedure Task_Example is -- Declare a simple task type with two entries: -- Start and Stop. -- An initial value is passed in to the task by the start -- entry -- A final value is passed out of the task by the stop -- entry task type Simple_Task is entry Start(Initial_Value : in Integer); entry Stop(Final_Value : out Integer); end Simple_Task; -- Implement the simple task -- This task doubles the initial value, then delays for -- one second to simulate a long task. task body Simple_Task is My_Value : Integer; begin -- Wait at the accept statement until some other task -- calls the Start entry accept Start(Initial_Value : in Integer) do My_Value := Initial_Value; end Start; -- Perform the calculation and then delay 1 second My_Value := 2 * My_Value; delay 1.0; -- Wait at the accept statement until some other task -- calls the Stop entry accept Stop(Final_Value : out Integer) do Final_Value := My_Value; end Stop; end Simple_Task; subtype Task_Index is Integer range 1..10; -- Declare an array type that contains several instances -- of the task type type Task_List is array(Task_Index) of Simple_Task; -- Declare an instance of the array of tasks Jobs : Task_List; Start_Time : Ada.Calendar.Time; -- Holds the program start time. Current_Time : Ada.Calendar.Time; Result : Integer; begin -- Task_Example Start_Time := Ada.Calendar.Clock; Ada.Text_Io.Put_Line("Start time: " & Duration'Image(Start_Time - Start_Time)); -- Start all the tasks in the array, passing them their -- index value in the array. for This_Task in Task_Index loop Jobs(This_Task).Start(This_Task); end loop; -- Record the time after completion of all the Start -- entries Current_Time := Ada.Calendar.Clock; Ada.Text_Io.Put_Line("All tasks started at: " & Duration'Image(Current_Time - Start_Time)); -- Call the Stop entry for each task -- Output the results and record the time when the Stop -- entry completed. for This_Task in Task_Index loop Ada.Text_Io.Put("Task"); Ada.Integer_Text_Io.Put(Item => This_Task, Width => 3); Jobs(This_Task).Stop(Result); Ada.Text_Io.Put(" Result"); Ada.Integer_Text_Io.Put(Item => Result, Width => 3); Current_Time := Ada.Calendar.Clock; Ada.Text_Io.Put_Line(" Completion Time: " & Duration'Image(Current_Time - Start_Time)); end loop; -- Record the time when all Stop entries have completed. Current_Time := Ada.Calendar.Clock; Ada.Text_Io.Put_Line("Program Finished: Time " & Duration'Image(Current_Time - Start_Time)); end Task_Example; The output from one run of this program, on a 166 MHz PC is: Start time: 0.000000000 All tasks started at: 0.000000000 Task 1 Result 2 Completion Time: 1.040000000 Task 2 Result 4 Completion Time: 1.040000000 Task 3 Result 6 Completion Time: 1.040000000 Task 4 Result 8 Completion Time: 1.040000000 Task 5 Result 10 Completion Time: 1.040000000 Task 6 Result 12 Completion Time: 1.040000000 Task 7 Result 14 Completion Time: 1.040000000 Task 8 Result 16 Completion Time: 1.040000000 Task 9 Result 18 Completion Time: 1.100000000 Task 10 Result 20 Completion Time: 1.100000000 Program Finished: Time 1.100000000 Note that some real parallel behavior has happened. A non-concurrent version of this program would take at least 10 seconds to complete because each task delays for one second. Jim Rogers Colorado Springs, Colorado