Main Page | Modules | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

timeout.h

Go to the documentation of this file.
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

Generated on Mon Sep 26 14:20:12 2005 for Fiasco by  doxygen 1.4.2