00001 /* hasTimer.cc 00002 */ 00003 #include "osl/search/searchTimer.h" 00004 #include "osl/search/usiReporter.h" 00005 #include <boost/foreach.hpp> 00006 #include <iostream> 00007 00008 osl::search::SearchTimer::~SearchTimer() 00009 { 00010 } 00011 00012 void osl::search::SearchTimer::throwStop() 00013 { 00014 assert(shared_timer->stop_all); 00015 if (shared_timer->stop_reason == SearchTimerCommon::NoMoreMemory) 00016 throw NoMoreMemory(); 00017 throw misc::NoMoreTime(); 00018 } 00019 00020 static osl::uint64_t maximum_node_count = 0; 00021 static double maximum_memory_use_ratio = 0.0; 00022 void osl::search:: 00023 SearchTimer::testAndUpdateNextTimeTest(uint64_t node_count) 00024 { 00025 SCOPED_LOCK(lk,shared_timer->mutex); 00026 if (shared_timer->stop_all) 00027 throwStop(); 00028 if (shared_timer->next_node_count > node_count) 00029 return; 00030 const double elapsed = this->elapsed(); 00031 if (elapsed > shared_timer->assigned.max.toSeconds() 00032 || (shared_timer->stable && elapsed > shared_timer->assigned.standard.toSeconds()) 00033 || node_count > shared_timer->node_count_hard_limit) { 00034 shared_timer->stop_reason = SearchTimerCommon::NoMoreTime; 00035 shared_timer->stop_all = true; 00036 throwStop(); 00037 } 00038 MilliSeconds now = MilliSeconds::now(); 00039 shared_timer->nps = node_count / (0.1+(now - shared_timer->start_time).toSeconds()); 00040 const int period100 = 00041 (shared_timer->node_count_hard_limit != std::numeric_limits<uint64_t>::max()) 00042 ? 1 : 25; 00043 shared_timer->next_node_count = node_count + static_cast<int>(shared_timer->nps * period100 / 100.0); 00044 shared_timer->last_tested = now; 00045 static int skip = 0; 00046 if (++skip % (100 / period100) == 0) { 00047 const double memory_use_ratio = OslConfig::memoryUseRatio(); 00048 if (memory_use_ratio > 0.85) { 00049 if (maximum_node_count > 0) { 00050 if (node_count > maximum_node_count 00051 || (memory_use_ratio > maximum_memory_use_ratio 00052 && node_count > 0.85*maximum_node_count) 00053 || (memory_use_ratio > 0.87 00054 && node_count > 0.8*maximum_node_count)) 00055 { 00056 if (memory_use_ratio > 0.87 && memory_use_ratio > maximum_memory_use_ratio) { 00057 maximum_memory_use_ratio = std::min(0.88, memory_use_ratio); 00058 maximum_node_count = maximum_node_count * 0.9; 00059 } 00060 shared_timer->stop_reason = SearchTimerCommon::NoMoreMemory; 00061 shared_timer->stop_all = true; 00062 std::cerr << "stop by memory full " << memory_use_ratio << " " << node_count << "\n"; 00063 throwStop(); 00064 } 00065 } 00066 maximum_memory_use_ratio = std::max(memory_use_ratio, maximum_memory_use_ratio); 00067 } else if (memory_use_ratio < 0.82) { 00068 maximum_node_count = std::max(maximum_node_count, node_count); 00069 maximum_memory_use_ratio = 0.82; 00070 } 00071 #ifndef GPSONE 00072 boost::mutex::scoped_lock lk(OslConfig::lock_io); 00073 BOOST_FOREACH(const boost::shared_ptr<SearchMonitor>& monitor, 00074 this->monitors()) 00075 { 00076 monitor->timeInfo(node_count, elapsed); 00077 monitor->hashInfo(memory_use_ratio); 00078 } 00079 #endif 00080 } 00081 } 00082 00083 void osl::search::SearchTimer::adjustMemoryUseLimit(double scale) 00084 { 00085 maximum_node_count *= scale; 00086 } 00087 00088 void osl::search::SearchTimer:: 00089 addMonitor(const boost::shared_ptr<SearchMonitor>& monitor) 00090 { 00091 shared_timer->monitors.push_back(monitor); 00092 } 00093 00094 00095 /* ------------------------------------------------------------------------- */ 00096 // ;;; Local Variables: 00097 // ;;; mode:c++ 00098 // ;;; c-basic-offset:2 00099 // ;;; End: