TaskMonitor

Files CCore/inc/task/TaskMonitor.h CCore/src/task/TaskMonitor.cpp

TaskMonitor

TaskMonitor can be used to monitor task switches. It is a Partial class, you have to build a derived class to use it.


class TaskMonitor : NoCopy
 {
  public:
  
   class Record
    {
     private:
     
      friend class TaskMonitor;
      
      // IntLocked
     
      virtual void transit(Record *from,Record *to)=0; 
   
      void begin() { transit(0,this); }
   
      void end() { transit(this,0); }
      
     public:
  
      Record();
   
      ~Record();
    };
   
   class StartStop : NoCopy
    {
      ....
   
     public: 
  
      explicit StartStop(TaskMonitor &obj);
      
      void stop();
   
      ~StartStop();
    };
  
  private:
   
   ....
  
   virtual void prepare()=0;
   
   virtual void complete()=0;

   // IntLocked
  
   virtual Record * alloc(TextLabel name,TaskPriority priority)=0;
   
   virtual Record * getInt()=0;

  protected:
  
   void guardStopped() const;
  
  public:
  
   TaskMonitor();
   
   ~TaskMonitor();
 };

prepare() is called before a monitoring is started as a part of the start process.

complete() is called after a monitoring is stopped as a part of the stop process.

guardStopped() is a guard method, it throws an exception, if a monitoring is in progress.

The inner class StartStop is used to start/stop a monitoring. Its constructor starts a monitoring with the given TaskMonitor object. The destructor or the method stop() stops it.

When a monitoring is started, record objects are used to monitor task context switches. The type of these objects is derived from the TaskMonitor::Record class. Each task and the interrupt context uses an associated such record. The record is allocated dynamically by the methods alloc() and getInt(). Record is allocated once per task. Allocation methods are called under IntLock protection, so their implementations in a derived class must be "quick", in particular, they cannot use memory allocation routines. Records should be taken from some preallocated record pool. One record can be used with multiple tasks. alloc() method arguments are: the task name and the task priority.

TaskMonitor::Record has tree methods used to monitor task switches: transit(), begin(), end(). These methods are called under IntLock protection. The transit() first argument is always the same as the object (unless it is called in the begin() method). This method is called when a context switch happens. Other methods are called once when a monitoring is started and stopped.

TaskMonitor_CPU

TaskMonitor_CPU is a fully-functional derived class from the TaskMonitor. It counts CPU time usage.


class TaskMonitor_CPU : public TaskMonitor
 {
   ....

  public:
   
   static const ulen DefaultBufLen = 100 ;
  
   explicit TaskMonitor_CPU(ulen buf_len=DefaultBufLen);
   
   ~TaskMonitor_CPU();
   
   template <class P>
   void print(P &out) const;
 };

The usage of this class is very simple: run it, stop it and then print it. The buf_len is a task record buffer length. Normally, 100 should be enough.

An example:


TaskMonitor_CPU monitor;
  
TaskMonitor::StartStop start_stop(monitor);
  
{
 .... // run several tasks here
}
  
start_stop.stop();
  
Printf(Con,"#;\n",monitor);