In Ada, how do I get the current time in seconds as a value I can print out and perform operations with?

5k views Asked by At

I am doing a project for an operating systems class. I need to write a program that prints out the current time every ten seconds but also accounts for the delay of the overhead so that it does not drift when it has been running for a long time. I need it to be up to at least 1 decimal place as well.

I am stuck on step 1 as I can't figure out how to get the current time in seconds as a value. I have searched but could only find out how to get the current time in the HH:MM:SS format.

Thanks

2

There are 2 answers

0
Lancelot SIX On

Here is a simple program that does the "print every 10s" part of the job. You could easily use this code in a separate package.

with Ada.Text_IO;
with Ada.Calendar;

procedure Periodic_Printer is

   task type My_Printer_Task is
   end My_Printer_Task;

   task body My_Printer_Task is
      use Ada.Calendar; -- for the "-" and "+" operations on Time
      Start_Time : Ada.Calendar.Time;
      Next_Cycle : Ada.Calendar.Time;
      Period     : constant Duration  := 10.0;
   begin
      Start_Time := Ada.Calendar.Clock;
      Next_Cycle := Start_Time;
      loop
         Ada.Text_IO.Put_Line(Duration'Image(Ada.Calendar.Clock - Start_Time)); --'
         -- You could use Next_Cycle instead of Ada.Calendar.Clock - Start_Time
         -- so the printing does not depend of the time needed to do the elapsed
         -- time calculation

         delay 3.0; -- like a long operation, takes time......
                    -- This pattern assumes the each cycle last less than Period
                    -- If you cannot ensure that, you should consider improving
                    -- the pattern or reduce the computation load of each cycle

         Next_Cycle := Next_Cycle + Period;
         delay until Next_Cycle;
      end loop;
   end My_Printer_Task;

   Printer : My_Printer_Task;
begin
   delay 90.0; -- You can do your 'real work' here.

   -- Unclean way to terminate a task, you should consider improve it for a
   -- real world scenario
   abort Printer;

   Ada.Text_IO.Put_Line("End of program");
end Periodic_Printer;
5
Shark8 On

Here's what I came up with:

writing_test.ads

package Writing_Test is

    protected Writer is
        entry write( Text : String; New_Line : Boolean:= True );
    end Writer;

    task Timer is
        entry Start;
        entry Pause;
        entry Stop;
    end Timer;


private

    Timer_Frequency : constant Duration:= 10.0;

end Writing_Test;

writing_test.adb

with
Ada.Calendar,
Ada.Text_IO;

package body Writing_Test is

    protected body Writer is
        entry write( Text : String; New_Line : Boolean:= True ) when True is
        begin
            Ada.Text_IO.Put( Text );

            if New_Line then
                Ada.Text_IO.New_Line;
            end if;
        end;
    end Writer;

    task body Timer is
        Active,
        Stop_Task : Boolean:= False;

        Next_Time : Ada.Calendar.Time;
        use type Ada.Calendar.Time;
    begin
        MAIN:
        loop
            if not Active then
                select
                    accept Start do
                        Active:= True;
                        Next_Time:= Ada.Calendar.Clock + Timer_Frequency;
                    end Start;
                or
                    terminate;
                end select;
            else
                select
                    accept Pause do
                        Active:= False;
                    end Pause;
                or
                    accept Stop do
                        Stop_Task:= True;
                    end Stop;
                or
                    delay until Next_Time;
                end select;

                exit MAIN when Stop_Task;

                if Active then
                    declare
                        Use Ada.Calendar;
                        Now : Time renames Clock;
                        Str : String renames
                          Day_Duration'Image( Ada.Calendar.Seconds(Now) );
    --' Formatter-correction trick
                    begin
                        Writer.write(Text => Str);
                        Next_Time:= Next_Time + Timer_Frequency;
                    end;
                end if;
            end if;        
        end loop MAIN;

    end Timer;

end Writing_Test;