Task: Rate counter


C++: #include <iostream>
#include <ctime>



class CRateState
{
protected:
    time_t m_lastFlush;
    time_t m_period;
    size_t m_tickCount;
public:
    CRateState(time_t period);
    void Tick();
};

CRateState::CRateState(time_t period) : m_lastFlush(std::time(NULL)),
                                        m_period(period),
                                        m_tickCount(0)
{ }

void CRateState::Tick()
{
    m_tickCount++;

    time_t now = std::time(NULL);

    if((now - m_lastFlush) >= m_period)
    {
        
        size_t tps = 0.0;
        if(m_tickCount > 0)
            tps = m_tickCount / (now - m_lastFlush);

        std::cout << tps << " tics per second" << std::endl;

        
        m_tickCount = 0;
        m_lastFlush = now;
    }
}



void something_we_do()
{
    
    
    
    
    
    
    
    volatile size_t anchor = 0;
    for(size_t x = 0; x < 0xffff; ++x)
    {
        anchor = x;
    }
}

int main()
{
    time_t start = std::time(NULL);

    CRateState rateWatch(5);

    
    for(time_t latest = start; (latest - start) < 20; latest = std::time(NULL))
    {
        
        something_we_do();

        
        rateWatch.Tick();
    }

    return 0;
}










Ada: with System;                     use System;
with Ada.Text_IO;                use Ada.Text_IO;
with Ada.Calendar;               use Ada.Calendar;
with Ada.Unchecked_Deallocation; use Ada;
with Interfaces;

procedure Rate_Counter is
   pragma Priority (Max_Priority);

   package Duration_IO is new Fixed_IO (Duration);

   Job_Nbr : constant := 6; 
   subtype Job_Index is Natural range 1 .. Job_Nbr;

   task type Job (ID : Job_Index) is
      pragma Priority (Default_Priority);
      entry Start;
   end Job;

   type Job_Ptr is access Job;
   procedure Free is new Unchecked_Deallocation (Job, Job_Ptr);

   Jobs : array (Job_Index) of Job_Ptr;

   Done      : Natural                      := 0;
   Completed : array (Job_Index) of Boolean := (others => False);

   type Timings is array (Job_Index) of Calendar.Time;
   Start_T, Stop_T : Timings;

   task body Job is
      Anchor : Interfaces.Integer_32;
      pragma Volatile (Anchor); 
   begin
      accept Start;

      for I in Interfaces.Integer_32'Range loop      
         Anchor := I;
      end loop;
   end Job;

begin
   for J in Job_Index'Range loop
      Jobs (J) := new Job (ID => J); 
   end loop;
   for J in Job_Index'Range loop 
      Start_T (J) := Calendar.Clock; 
      Jobs (J).Start; 
   end loop;
   
   while not (Done = Job_Nbr) loop
      for J in Job_Index'Range loop
         if not Completed (J) and then Jobs (J)'Terminated then
            Stop_T (J) := Calendar.Clock; 
            Put ("Job #" & Job_Index'Image (J) & " is finished. It took ");
            Duration_IO.Put (Stop_T (J) - Start_T (J), Fore => 3, Aft => 2);
            Put_Line (" seconds.");
            Completed (J) := True;
            Done          := Done + 1;
         end if;
      end loop;
      delay System.Tick; 
   end loop;
   Duration_IO.Put (System.Tick, Fore => 1, Aft => 6);
   Put_Line (" seconds is the precision of System clock.");

   for J in Job_Index'Range loop
      Free (Jobs (J)); 
   end loop;

end Rate_Counter;