LCOV - code coverage report
Current view: top level - DCPS - ThreadStatusManager.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 23 38 60.5 %
Date: 2023-04-30 01:32:43 Functions: 7 11 63.6 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *
       4             :  * Distributed under the OpenDDS License.
       5             :  * See: http://www.opendds.org/license.html
       6             :  */
       7             : 
       8             : #ifndef OPENDDS_DCPS_THREADSTATUSMANAGER_H
       9             : #define OPENDDS_DCPS_THREADSTATUSMANAGER_H
      10             : 
      11             : #include "dcps_export.h"
      12             : #include "TimeTypes.h"
      13             : 
      14             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      15             : 
      16             : namespace OpenDDS {
      17             : namespace DCPS {
      18             : 
      19             : class OpenDDS_Dcps_Export ThreadStatusManager {
      20             : public:
      21             : 
      22             : #if defined (ACE_WIN32)
      23             :   typedef unsigned ThreadId;
      24             : #else
      25             : 
      26             : #  ifdef ACE_HAS_GETTID
      27             :   typedef pid_t ThreadId;
      28             : #  else
      29             :   typedef String ThreadId;
      30             : #  endif
      31             : #endif /* ACE_WIN32 */
      32             : 
      33             :   class OpenDDS_Dcps_Export Thread {
      34             :   public:
      35             :     enum ThreadStatus {
      36             :       ThreadStatus_Active,
      37             :       ThreadStatus_Idle,
      38             :     };
      39             : 
      40           0 :     Thread(const String& bit_key)
      41           0 :       : bit_key_(bit_key)
      42           0 :       , timestamp_(SystemTimePoint::now())
      43           0 :       , status_(ThreadStatus_Active)
      44           0 :       , last_update_(MonotonicTimePoint::now())
      45           0 :       , current_bucket_(0)
      46           0 :       , nesting_depth_(0)
      47           0 :     {}
      48             : 
      49             :     const String& bit_key() const { return bit_key_; }
      50             :     const SystemTimePoint& timestamp() const { return timestamp_; }
      51           0 :     const MonotonicTimePoint& last_update() const { return last_update_; }
      52             : 
      53             :     void update(const MonotonicTimePoint& m_now,
      54             :                 const SystemTimePoint& s_now,
      55             :                 ThreadStatus next_status,
      56             :                 const TimeDuration& bucket_limit,
      57             :                 bool nested);
      58             :     double utilization(const MonotonicTimePoint& now) const;
      59             : 
      60             :     static const size_t bucket_count = 8;
      61             : 
      62             :   private:
      63             :     const String bit_key_;
      64             :     SystemTimePoint timestamp_;
      65             :     ThreadStatus status_;
      66             : 
      67             :     struct OpenDDS_Dcps_Export Bucket {
      68             :       TimeDuration active_time;
      69             :       TimeDuration idle_time;
      70             :     };
      71             :     MonotonicTimePoint last_update_;
      72             :     Bucket total_;
      73             :     Bucket bucket_[bucket_count];
      74             :     size_t current_bucket_;
      75             :     size_t nesting_depth_;
      76             :   };
      77             :   typedef OPENDDS_MAP(ThreadId, Thread) Map;
      78             :   typedef OPENDDS_LIST(Thread) List;
      79             : 
      80           0 :   void thread_status_interval(const TimeDuration& thread_status_interval)
      81             :   {
      82           0 :     thread_status_interval_ = thread_status_interval;
      83           0 :     bucket_limit_ = thread_status_interval / static_cast<double>(Thread::bucket_count);
      84           0 :   }
      85             : 
      86           0 :   const TimeDuration& thread_status_interval() const
      87             :   {
      88           0 :     return thread_status_interval_;
      89             :   }
      90             : 
      91        5531 :   bool update_thread_status() const
      92             :   {
      93        5531 :     return thread_status_interval_ > TimeDuration::zero_value;
      94             :   }
      95             : 
      96             :   /// Add the calling thread with the manager.
      97             :   /// name is for a more human-friendly name that will be appended to the BIT key.
      98             :   /// Implicitly makes the thread active and finishes the thread on destruction.
      99             :   class Start {
     100             :   public:
     101           9 :     Start(ThreadStatusManager& thread_status_manager, const String& name)
     102           9 :       : thread_status_manager_(thread_status_manager)
     103             :     {
     104           9 :       thread_status_manager_.add_thread(name);
     105           9 :     }
     106             : 
     107           9 :     ~Start()
     108             :     {
     109           9 :       thread_status_manager_.finished();
     110           9 :     }
     111             : 
     112             :   private:
     113             :     ThreadStatusManager& thread_status_manager_;
     114             :   };
     115             : 
     116             :   class Event {
     117             :   public:
     118          25 :     Event(ThreadStatusManager& thread_status_manager)
     119          25 :       : thread_status_manager_(thread_status_manager)
     120             :     {
     121          25 :       thread_status_manager_.active(true);
     122          25 :     }
     123             : 
     124          25 :     ~Event()
     125             :     {
     126          25 :       thread_status_manager_.idle(true);
     127          25 :     }
     128             : 
     129             :   private:
     130             :     ThreadStatusManager& thread_status_manager_;
     131             :   };
     132             : 
     133             :   class Sleeper {
     134             :   public:
     135        2727 :     Sleeper(ThreadStatusManager& thread_status_manager)
     136        2727 :       : thread_status_manager_(thread_status_manager)
     137             :     {
     138        2727 :       thread_status_manager_.idle();
     139        2727 :     }
     140             : 
     141        2727 :     ~Sleeper()
     142             :     {
     143        2727 :       thread_status_manager_.active();
     144        2727 :     }
     145             : 
     146             :   private:
     147             :     ThreadStatusManager& thread_status_manager_;
     148             :   };
     149             : 
     150             :   /// Copy active and idle threads to running and finished threads to
     151             :   /// finished.  Only threads updated after start are considered.
     152             :   void harvest(const MonotonicTimePoint& start,
     153             :                List& running,
     154             :                List& finished) const;
     155             : 
     156             : #ifdef ACE_HAS_GETTID
     157             :   static inline pid_t gettid()
     158             :   {
     159             :     return syscall(SYS_gettid);
     160             :   }
     161             : #endif
     162             : 
     163             : private:
     164             :   static ThreadId get_thread_id();
     165             :   void add_thread(const String& name);
     166             :   void active(bool nested = false);
     167             :   void idle(bool nested = false);
     168             :   void finished();
     169             : 
     170             :   void cleanup(const MonotonicTimePoint& now);
     171             : 
     172             :   TimeDuration thread_status_interval_;
     173             :   TimeDuration bucket_limit_;
     174             :   Map map_;
     175             :   List list_;
     176             : 
     177             :   mutable ACE_Thread_Mutex lock_;
     178             : };
     179             : 
     180             : } // namespace DCPS
     181             : } // namespace OpenDDS
     182             : 
     183             : OPENDDS_END_VERSIONED_NAMESPACE_DECL
     184             : 
     185             : #endif  /* OPENDDS_DCPS_THREADSTATUSMANAGER_H */

Generated by: LCOV version 1.16