--
-- Version: @(#)rendez.ada 1.2  Date: 9/21/84
--
-- Author:  Bryce Bardin
--          Ada Projects Section
--          Software Engineering Division
--          Ground Systems Group
--          Hughes Aircraft Company
--          Fullerton, CA
--
-- This program measures the time required for a simple rendezvous.
--
-- Note:  In order for the measurement to be meaningful, it must be the
-- only program executing while the test is run.
--
-- Please set Times large enough to provide at least two significant
-- digits in the average rendezvous times, i.e., the difference between
-- the elapsed time and the loop time must be at least 100 times
-- Duration'Small & at least 100 times System.Tick.

with Text_Io;
use Text_Io;
with Calendar;
use Calendar;
with System;
use System;
procedure Rendezvous is

    Times : constant Positive := 1000;

    type Real_Time is digits Max_Digits;

    Start_Time : Time;
    Loop_Time : Duration;
    Elapsed_Time : Duration;
    Average_Time : Real_Time;

    package Duration_Io is new Fixed_Io (Duration);
    use Duration_Io;

    package Real_Time_Io is new Float_Io (Real_Time);
    use Real_Time_Io;

    package Int_Io is new Integer_Io (Integer);
    use Int_Io;

    task T is
        entry Call;
    end T;

    -- This package is used to prevent elimination of the "null" timing loop
    -- by a smart compiler.
    package Prevent is
        Count : Natural := 0;
        procedure Prevent_Optimization;
    end Prevent;

    use Prevent;

    task body T is
    begin
        loop
            select
                accept Call;
            or
                terminate;
            end select;
        end loop;
    end T;

    package body Prevent is
        procedure Prevent_Optimization is
        begin
            Count := Count + 1;
        end Prevent_Optimization;
    end Prevent;

begin

    -- Measure the timing loop overhead.
    Start_Time := Clock;

    for N in 1 .. Times loop
        Prevent_Optimization;
    end loop;

    Loop_Time := Clock - Start_Time;

    -- Measure the time including rendezvous.
    Start_Time := Clock;

    for N in 1 .. Times loop
        Prevent_Optimization;
        T.Call;
    end loop;

    Put ("Loop time = ");
    Put (Loop_Time, Fore => 0);
    Put (" seconds for ");
    Put (Times, Width => 0);
    Put_Line (" iterations");

    Elapsed_Time := Clock - Start_Time;
    Put ("Elapsed time = ");
    Put (Elapsed_Time, Fore => 0);
    Put (" seconds for ");
    Put (Times, Width => 0);
    Put_Line (" iterations");

    Average_Time := Real_Time (Elapsed_Time - Loop_Time) / Real_Time (Times);
    Put ("Average time for no-parameter rendezvous = ");
    Put (Average_Time, Fore => 0);
    Put_Line (" seconds");

    New_Line;

    if (Elapsed_Time - Loop_Time < 100 * Duration'Small or
        Elapsed_Time - Loop_Time < 100 * System.Tick) then
        Put_Line ("** TEST FAILED (due to insufficient precision)! **");
    else
        Put_Line ("** TEST PASSED **");
    end if;

end Rendezvous;


