searchTimer.h
Go to the documentation of this file.
00001 /* hasTimer.h
00002  */
00003 #ifndef OSL_SEARCHTIMER_H
00004 #define OSL_SEARCHTIMER_H
00005 #include "osl/misc/milliSeconds.h"
00006 #include "osl/misc/lightMutex.h"
00007 #include "osl/stl/vector.h"
00008 #include "osl/oslConfig.h"
00009 #include <boost/shared_ptr.hpp>
00010 #include <boost/cstdint.hpp>
00011 #include <limits>
00012 
00013 namespace osl
00014 {
00015   namespace search
00016   {
00017     struct TimeAssigned
00018     {
00019       MilliSeconds::Interval standard, max;
00020       TimeAssigned() 
00021         : standard(MilliSeconds::Interval::infinity()),
00022           max(MilliSeconds::Interval::infinity())
00023       {
00024       }
00025       explicit TimeAssigned(MilliSeconds::Interval assign) 
00026         : standard(assign), max(assign)
00027       {
00028       }
00029       TimeAssigned(MilliSeconds::Interval s, MilliSeconds::Interval m) 
00030         : standard(s), max(m)
00031       {
00032       }
00033     };
00034     class SearchMonitor;
00035     struct SearchTimerCommon
00036     {
00037       enum StopReason { NotStopped, NoMoreTime, NoMoreMemory, StopByOutside };
00039       MilliSeconds start_time;
00041       TimeAssigned assigned;
00043       volatile double next_iteration_coefficient;
00044       volatile bool stop_all;
00045       volatile StopReason stop_reason;
00046       uint64_t node_count_hard_limit;
00047       volatile int last_memory_use1000;
00048       
00049       // work area
00050       MilliSeconds last_tested;
00051       uint64_t next_node_count;
00052       double nps;
00053       volatile bool stable;
00054       vector<boost::shared_ptr<SearchMonitor> > monitors;
00055       typedef LightMutex Mutex;
00056       mutable Mutex mutex;
00057 
00058       SearchTimerCommon() 
00059         : start_time(MilliSeconds::now()), 
00060           next_iteration_coefficient(4.0), stop_all(0), stop_reason(NotStopped),
00061           node_count_hard_limit(std::numeric_limits<uint64_t>::max()),
00062           last_memory_use1000(0), stable(true)
00063       {
00064       }
00065     };
00066     class SearchTimer
00067     {
00068       boost::shared_ptr<SearchTimerCommon> shared_timer;
00069       typedef SearchTimerCommon::Mutex Mutex;
00070     public:
00071       SearchTimer() : shared_timer(new SearchTimerCommon) {}
00072       SearchTimer(const SearchTimer& src) : shared_timer(src.shared_timer) {}
00073       virtual ~SearchTimer();
00074       void setTimeAssign(const TimeAssigned& a) {
00075         SCOPED_LOCK(lk,shared_timer->mutex);
00076         shared_timer->assigned = a;
00077       }
00078       void setStartTime(MilliSeconds start) {
00079         SCOPED_LOCK(lk,shared_timer->mutex);
00080         shared_timer->start_time = start;
00081         shared_timer->next_node_count = 0;
00082         shared_timer->nps = 0.0;
00083         shared_timer->last_tested = start;
00084         shared_timer->stop_all = false;
00085       }
00086       void setStable(bool new_stable) { shared_timer->stable = new_stable; }
00087       bool isStableNow() const { return shared_timer->stable; }
00088       bool hasSchedule() const {
00089         SCOPED_LOCK(lk,shared_timer->mutex);
00090         return ! shared_timer->assigned.standard.isInfinity();
00091       }
00092       const TimeAssigned& timeAssigned() const
00093       {
00094         SCOPED_LOCK(lk,shared_timer->mutex);
00095         return shared_timer->assigned;
00096       }
00097       const MilliSeconds startTime() const {
00098         SCOPED_LOCK(lk,shared_timer->mutex);
00099         return shared_timer->start_time;
00100       }
00101       double elapsed(MilliSeconds now) const 
00102       {
00103         return (now - shared_timer->start_time).toSeconds();
00104       }
00105       double elapsed() const { return elapsed(MilliSeconds::now()); }
00106 
00107       void setNextIterationCoefficient(double new_value) {
00108         SCOPED_LOCK(lk,shared_timer->mutex);
00109         shared_timer->next_iteration_coefficient = new_value;
00110       }
00111       void setNodeCountHardLimit(uint64_t new_value) {
00112         SCOPED_LOCK(lk,shared_timer->mutex);
00113         shared_timer->node_count_hard_limit = new_value;
00114       }
00115       double nextIterationCoefficient() const {
00116         SCOPED_LOCK(lk,shared_timer->mutex);
00117         return shared_timer->next_iteration_coefficient;
00118       }
00119 
00120       bool stopping() const { return shared_timer->stop_all; }
00121       void stopNow() 
00122       {
00123         shared_timer->stop_reason = SearchTimerCommon::StopByOutside;
00124         shared_timer->stop_all = true; 
00125       }
00126       SearchTimerCommon::StopReason stopReason() { return shared_timer->stop_reason; }
00127       void throwIfNoMoreTime(uint64_t node_count)
00128       {
00129         SearchTimerCommon& shared = *shared_timer;
00130         if (! shared.stop_all) {
00131           uint64_t next_node_count;
00132           {
00133 #ifdef OSL_USE_RACE_DETECTOR
00134             SCOPED_LOCK(lk,shared_timer->mutex);
00135 #endif
00136             next_node_count = shared.next_node_count;
00137           }
00138           if (next_node_count > node_count || ! hasSchedule())
00139             return;
00140         }
00141         testAndUpdateNextTimeTest(node_count);
00142       }
00143       int nodeAffordable() const
00144       {
00145         const MilliSeconds now = MilliSeconds::now();
00146 #ifdef OSL_USE_RACE_DETECTOR
00147         SCOPED_LOCK(lk,shared_timer->mutex);
00148 #endif
00149         const double nps = shared_timer->nps;
00150         const double left 
00151           = (shared_timer->start_time + shared_timer->assigned.max - now).toSeconds();
00152         return std::max(0, static_cast<int>(nps * left));
00153       }
00155       static void adjustMemoryUseLimit(double scale=0.9);
00156       void addMonitor(const boost::shared_ptr<SearchMonitor>&);
00157       bool hasMonitor() const 
00158       { 
00159         return ! shared_timer->monitors.empty();
00160       }
00161       const vector<boost::shared_ptr<SearchMonitor> >& monitors() const
00162       {
00163         return shared_timer->monitors;
00164       }
00165       int lastMemoryUseRatio1000() const 
00166       {
00167         return shared_timer->last_memory_use1000;
00168       }
00169     private:
00170       void testAndUpdateNextTimeTest(uint64_t node_count);
00171       void throwStop();
00172     };
00173   } // namespace search
00174 } // namespace osl
00175 
00176 
00177 #endif /* OSL_SEARCHTIMER_H */
00178 // ;;; Local Variables:
00179 // ;;; mode:c++
00180 // ;;; c-basic-offset:2
00181 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines