Rapicorn - Experimental UI Toolkit - Source Code  13.07.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
quicktimer.hh
Go to the documentation of this file.
00001  // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
00002 #ifndef __RAPICORN_QUICKTIMER_HH__
00003 #define __RAPICORN_QUICKTIMER_HH__
00004 
00005 #include <rcore/cpuasm.hh>
00006 #include <rcore/utilities.hh>
00007 
00008 namespace Rapicorn {
00009 
00010 class QuickTimer {
00011   enum Type { NONE, PROCESS, RDTSC, TIMEOFDAY };
00012   uint64        usecs_, start_, mark_;
00013   static uint64 volatile timer_pcounter;
00014   static uint64 const granularity = 1700; // rough granularity for expiration checks
00015   static Type   timer_type;
00016   static uint64 rdtsc_mask;
00017   static bool   toggle_timers (bool);
00018   static void   inc_pcounter  ();
00019   static void   unref_timers  ();
00020   static void   init_timers   ();
00021   static void   ref_timers    ();
00022   bool          time_elapsed  ();
00023   RAPICORN_CLASS_NON_COPYABLE (QuickTimer);
00024 public:
00025   explicit      QuickTimer      (uint64 usecs);
00026   virtual      ~QuickTimer      ();
00027   void          start           ();
00028   void          start           (uint64 usecs);
00029   inline bool   expired         ();
00030 };
00031 
00032 
00033 // === Implementation Details ===
00034 inline bool // inlined for performance
00035 QuickTimer::expired()
00036 {
00037   // fast path: QuickTimer::PROCESS and counter hasn't changed
00038   if (RAPICORN_LIKELY (mark_ == timer_pcounter))
00039     return false;
00040   // fallback to rdtsc polling
00041   if (RAPICORN_HAVE_X86_RDTSC && RAPICORN_LIKELY (timer_type == QuickTimer::RDTSC))
00042     {
00043       const uint64 rnow = RAPICORN_X86_RDTSC();
00044       // check: ABS (rnow - last) * 1000000 / rdtsc_timer_freq >= granularity
00045       if (RAPICORN_UNLIKELY ((rnow ^ mark_) & rdtsc_mask))
00046         {
00047           mark_ = rnow;
00048           return RAPICORN_UNLIKELY (time_elapsed());
00049         }
00050       return false;
00051     }
00052   // fallback to gettimeofday polling
00053   if (RAPICORN_LIKELY (timer_type == QuickTimer::TIMEOFDAY))
00054     {
00055       const uint64 tnow = timestamp_realtime();
00056       if (RAPICORN_UNLIKELY (ABS (tnow - mark_) >= granularity))
00057         {
00058           mark_ = tnow;
00059           return RAPICORN_UNLIKELY (time_elapsed());
00060         }
00061       return false;
00062     }
00063   // QuickTimer::PROCESS, counter changed
00064   mark_ = timer_pcounter; // update mark
00065   return RAPICORN_UNLIKELY (time_elapsed());
00066 }
00067 
00068 } // Rapicorn
00069 
00070 #endif /* __RAPICORN_QUICKTIMER_HH__ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines