00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT! -*- c++ -*- 00002 00003 #ifndef timeout_h 00004 #define timeout_h 00005 00006 #include "l4_types.h" 00007 00008 // 00009 // INTERFACE definition follows 00010 // 00011 00012 00013 class Timeout 00014 { 00015 friend class Jdb_timeout_list; 00016 friend class Jdb_list_timeouts; 00017 00018 public: 00022 Timeout(); 00023 00024 static bool do_timeouts(); 00025 00026 void reset(); 00027 00031 bool is_set(); 00032 00036 bool has_hit(); 00037 00038 void set(Unsigned64 clock); 00039 00040 void set_again(); 00041 00042 static Timeout* Timeout::get_first_timeout(); 00043 00047 Signed64 get_timeout(); 00048 00049 protected: 00053 Unsigned64 _wakeup; 00054 00055 private: 00059 Timeout(const Timeout&); 00060 00064 void enqueue(); 00065 00070 bool dequeue(); 00071 00072 virtual bool expired() = 0; 00073 00077 Timeout *_next, *_prev; 00078 00079 struct { 00080 bool set : 1; 00081 bool hit : 1; 00082 unsigned res : 6; // performance optimization 00083 } _flags; 00084 00085 static Timeout *first_timeout; 00086 }; 00087 00088 // 00089 // IMPLEMENTATION includes follow (for use by inline functions) 00090 // 00091 00092 00093 #include <cassert> 00094 #include "cpu_lock.h" 00095 #include "kip.h" 00096 #include "lock_guard.h" 00097 #include "timer.h" 00098 00099 // 00100 // IMPLEMENTATION of inline functions (and needed classes) 00101 // 00102 00103 00104 00105 00106 inline Timeout::Timeout() 00107 { 00108 _flags.set = _flags.hit = 0; 00109 _flags.res = 0; 00110 } 00111 00112 00113 00114 inline bool 00115 Timeout::is_set() 00116 { 00117 return _flags.set; 00118 } 00119 00120 00121 00122 inline bool 00123 Timeout::has_hit() 00124 { 00125 return _flags.hit; 00126 } 00127 00128 00129 00130 inline Timeout* 00131 Timeout::get_first_timeout() 00132 { 00133 return first_timeout; 00134 } 00135 00136 00137 00138 inline void 00139 Timeout::enqueue() 00140 { 00141 _flags.set = 1; 00142 00143 if (!first_timeout) // insert as first 00144 { 00145 first_timeout = this; 00146 _prev = _next = 0; 00147 Timer::update_timer(_wakeup); 00148 return; 00149 } 00150 00151 Timeout *t; 00152 00153 for (t = first_timeout;; t = t->_next) 00154 { 00155 if (t->_wakeup >= _wakeup) // insert before t 00156 { 00157 _next = t; 00158 _prev = t->_prev; 00159 t->_prev = this; 00160 00161 if (_prev) 00162 _prev->_next = this; 00163 else 00164 { 00165 first_timeout = this; 00166 Timer::update_timer(_wakeup); 00167 } 00168 return; 00169 } 00170 00171 if (!t->_next) 00172 break; 00173 } 00174 00175 t->_next = this; // insert as last after t 00176 _prev = t; 00177 _next = 0; 00178 } 00179 00180 00181 00182 inline void 00183 Timeout::set(Unsigned64 clock) 00184 { 00185 // XXX uses global kernel lock 00186 Lock_guard<Cpu_lock> guard (&cpu_lock); 00187 00188 assert (!is_set()); 00189 00190 _wakeup = clock; 00191 enqueue(); 00192 } 00193 00194 00195 00196 inline Signed64 00197 Timeout::get_timeout() 00198 { 00199 return _wakeup - Timer::system_clock(); 00200 } 00201 00202 00203 00204 inline void 00205 Timeout::set_again() 00206 { 00207 // XXX uses global kernel lock 00208 Lock_guard<Cpu_lock> guard (&cpu_lock); 00209 00210 assert(! is_set()); 00211 if (! has_hit()) 00212 { 00213 enqueue(); 00214 } 00215 } 00216 00217 00218 00219 inline void 00220 Timeout::reset() 00221 { 00222 // XXX uses global kernel lock 00223 00224 if (!is_set()) 00225 return; // avoid lock overhead if not set 00226 00227 { 00228 Lock_guard<Cpu_lock> guard (&cpu_lock); 00229 00230 if (is_set()) 00231 { 00232 if (_prev) 00233 _prev->_next = _next; 00234 else 00235 { 00236 first_timeout = _next; 00237 if (_next) 00238 Timer::update_timer(_next->_wakeup); 00239 } 00240 if (_next) 00241 _next->_prev = _prev; 00242 } 00243 00244 _flags.set = 0; 00245 } 00246 } 00247 00248 00249 00250 inline bool 00251 Timeout::dequeue() 00252 { 00253 // XXX assume we run kernel-locked 00254 00255 first_timeout = _next; // dequeue 00256 if (_next) 00257 _next->_prev = 0; 00258 00259 _flags.hit = 1; 00260 _flags.set = 0; 00261 00262 return expired(); 00263 } 00264 00265 00266 00267 inline bool 00268 Timeout::do_timeouts() 00269 { 00270 bool reschedule = false; 00271 00272 // timer interrupt handler synchronized clock before calling 00273 // Thread::handle_timer_interrupt which in turn called us 00274 while (first_timeout && (Kip::k()->clock >= first_timeout->_wakeup)) 00275 if (first_timeout->dequeue()) 00276 reschedule = true; 00277 00278 // After dequeueing all expired timeouts, program next event, if any 00279 if (first_timeout) 00280 Timer::update_timer (first_timeout->_wakeup); 00281 00282 return reschedule; 00283 } 00284 00285 #endif // timeout_h