with Text_Io;
use Text_Io;
with Duration_Io;
use Duration_Io;
with Cpu_Time_Clock;
with Calendar;

procedure Y000001 is
    Stages : constant := 14;
    Smallest : Duration := Duration (Duration (1) / Duration (1024));
    Commanded : array (1 .. Stages) of Duration;
    Actual : array (1 .. Stages) of Duration;
    Actual_Wall : array (1 .. Stages) of Duration;
    Iteration : array (1 .. Stages) of Integer;
    T1 : Duration;
    T2 : Duration;
    T1_Wall : Duration;
    T2_Wall : Duration;

begin
    Put_Line ("Y000001 Measure actual delay vs commanded delay");
--
--  set up Commanded and Iteration
--
    Commanded (1) := Smallest;
    Iteration (1) := 4096;
    for I in 2 .. Stages loop
        Commanded (I) := Commanded (I - 1) * 2;
        Iteration (I) := Iteration (I - 1) / 2;
        if Iteration (I) < 2 then
            Iteration (I) := 2;
        end if;
    end loop;
--
--  Run measurements
--
    for I in 1 .. Stages loop
        T1 := Cpu_Time_Clock;
        T1_Wall := Calendar.Seconds (Calendar.Clock);
        for J in 1 .. Iteration (I) loop
            delay Commanded (I);
        end loop;
        T2_Wall := Calendar.Seconds (Calendar.Clock);
        T2 := Cpu_Time_Clock;
        Actual (I) := Duration ((T2 - T1) / Duration (Iteration (I)));
        Actual_Wall (I) := Duration
                              ((T2_Wall - T1_Wall) / Duration (Iteration (I)));
    end loop;
--
-- Print results
--
    Put_Line ("   Commanded      Actual         CPU    Iterations");
    for I in 1 .. Stages loop
        Put (Commanded (I));
        Put ("  ");
        Put (Actual_Wall (I));
        Put ("  ");
        Put (Actual (I));
        Put ("  ");
        Put_Line (Integer'Image (Iteration (I)));
    end loop;
end Y000001;