#include <Timer_Wheel_T.h>
Inheritance diagram for ACE_Timer_Wheel_T:


Public Types | |
| typedef ACE_Timer_Wheel_Iterator_T< TYPE, FUNCTOR, ACE_LOCK > | Iterator |
| Type of iterator. More... | |
| typedef ACE_Timer_Node_T< TYPE > | Node |
| typedef ACE_Timer_Queue_T< TYPE, FUNCTOR, ACE_LOCK > | Base |
| Type inherited from. More... | |
| typedef ACE_Free_List< Node > | FreeList |
Public Methods | |
| ACE_Timer_Wheel_T (FUNCTOR *upcall_functor=0, FreeList *freelist=0) | |
| Default constructor. More... | |
| ACE_Timer_Wheel_T (u_int spoke_count, u_int resolution, size_t prealloc=0, FUNCTOR *upcall_functor=0, FreeList *freelist=0) | |
| Constructor with opportunities to set the wheelsize and resolution. More... | |
| virtual | ~ACE_Timer_Wheel_T (void) |
| Destructor. More... | |
| virtual int | is_empty (void) const |
| True if queue is empty, else false. More... | |
| virtual const ACE_Time_Value & | earliest_time (void) const |
| Returns the time of the earlier node in the <ACE_Timer_Wheel>. Must be called on a non-empty queue. More... | |
| virtual long | schedule (const TYPE &type, const void *act, const ACE_Time_Value &future_time, const ACE_Time_Value &interval=ACE_Time_Value::zero) |
| Schedules a timer. More... | |
| virtual int | reset_interval (long timer_id, const ACE_Time_Value &interval) |
| Changes the interval of a timer (and can make it periodic or non periodic by setting it to ACE_Time_Value::zero or not). More... | |
| virtual int | cancel (const TYPE &type, int dont_call_handle_close=1) |
| Cancel all timer associated with <type>. If <dont_call> is 0 then the <functor> will be invoked. Returns number of timers cancelled. More... | |
| virtual int | cancel (long timer_id, const void **act=0, int dont_call_handle_close=1) |
| virtual int | expire (void) |
| Run the <functor> for all timers whose values are <= <ACE_OS::gettimeofday>. Also accounts for <timer_skew>. Returns the number of timers canceled. More... | |
| int | expire (const ACE_Time_Value &) |
| virtual ACE_Timer_Queue_Iterator_T< TYPE, FUNCTOR, ACE_LOCK > & | iter (void) |
| Returns a pointer to this <ACE_Timer_Queue_T>'s iterator. More... | |
| virtual ACE_Timer_Node_T< TYPE > * | remove_first (void) |
| Removes the earliest node from the queue and returns it. More... | |
| virtual void | dump (void) const |
| Dump the state of an object. More... | |
| virtual ACE_Timer_Node_T< TYPE > * | get_first (void) |
| Reads the earliest node from the queue and returns it. More... | |
Private Methods | |
| ACE_Timer_Node_T< TYPE > * | get_first_i (void) const |
| ACE_Timer_Node_T< TYPE > * | remove_first_expired (const ACE_Time_Value &now) |
| void | open_i (size_t prealloc, u_int spokes, u_int res) |
| virtual void | reschedule (ACE_Timer_Node_T< TYPE > *) |
| ACE_Timer_Node_T< TYPE > * | find_spoke_node (u_int spoke, long timer_id) const |
| Searches for a node by timer_id within one spoke. More... | |
| ACE_Timer_Node_T< TYPE > * | find_node (long timer_id) const |
| Searches all spokes for a node matching the specified timer_id Uses the spoke encoded in the timer_id as a starting place. More... | |
| u_int | calculate_spoke (const ACE_Time_Value &expire) const |
| Uses a simple hash to find which spoke to use based on when the timer is due to expire. Hopefully the 64bit int operations avoid any overflow problems. More... | |
| long | generate_timer_id (u_int spoke) |
| Generates a unique timer_id for the given spoke. It should be pretty fast until the point where the counter overflows. At that time you have to do exhaustive searches within the spoke to ensure that a particular timer id is not already in use. Some optimizations are in place so that this hopefully doesn't have to happen often. More... | |
| void | schedule_i (ACE_Timer_Node_T< TYPE > *n, u_int spoke, const ACE_Time_Value &expire) |
| The shared scheduling functionality between schedule() and reschedule(). More... | |
| void | cancel_i (ACE_Timer_Node_T< TYPE > *n, int skip_close) |
| Shared subset of the two cancel() methods. More... | |
| void | unlink (ACE_Timer_Node_T< TYPE > *n) |
| void | recalc_earliest (const ACE_Time_Value &last) |
| There are a few places where we have to figure out which timer will expire next. This method makes the assumption that spokes are always sorted, and that timers are always in the correct spoke determined from their expiration time. The last time is always passed in, even though you can often calculate it as get_first()->get_timer_value(). More... | |
| ACE_Timer_Wheel_T (const ACE_Timer_Wheel_T< TYPE, FUNCTOR, ACE_LOCK > &) | |
| void | operator= (const ACE_Timer_Wheel_T< TYPE, FUNCTOR, ACE_LOCK > &) |
Private Attributes | |
| ACE_Timer_Node_T< TYPE > ** | spokes_ |
| Timing Wheel. More... | |
| u_int | spoke_count_ |
| Size of the timing wheel. More... | |
| int | spoke_bits_ |
| Number of timer_id bits used for the spoke. More... | |
| u_int | max_per_spoke_ |
| Maximum number of timers per spoke. More... | |
| int | res_bits_ |
| Resolution (in microsoconds) of the timing wheel. More... | |
| u_int | earliest_spoke_ |
| Index of the list with the earliest time. More... | |
| Iterator * | iterator_ |
| Iterator used to expire timers. More... | |
| ACE_Time_Value | wheel_time_ |
| The total amount of time in one iteration of the wheel. (resolution * spoke_count). More... | |
| u_int | timer_count_ |
| The total number of timers currently scheduled. More... | |
Friends | |
| class | ACE_Timer_Wheel_Iterator_T< TYPE, FUNCTOR, ACE_LOCK > |
| Iterator is a friend. More... | |
This implementation uses a hash table of ordered doubly- linked lists of absolute times. The enhancements over the ACE_Timer_List include adding a free list and the ability to preallocate nodes. Timer Wheel is based on the timing wheel implementation used in Adam M. Costello and George Varghese's paper "Redesigning the BSD Callout and Timer Facilities" (http://dworkin.wustl.edu/~varghese/PAPERS/newbsd.ps.Z)
Definition at line 90 of file Timer_Wheel_T.h.
|
|||||
|
Type inherited from.
Definition at line 99 of file Timer_Wheel_T.h. |
|
|||||
|
Definition at line 100 of file Timer_Wheel_T.h. |
|
|||||
|
Type of iterator.
Definition at line 94 of file Timer_Wheel_T.h. |
|
|||||
|
Definition at line 97 of file Timer_Wheel_T.h. |
|
||||||||||||||||
|
Default constructor. Default Constructor that sets defaults for spoke_count_ and resolution_ and doesn't do any preallocation.
Definition at line 45 of file Timer_Wheel_T.cpp. References ACE_DEFAULT_TIMER_WHEEL_RESOLUTION, ACE_DEFAULT_TIMER_WHEEL_SIZE, and ACE_TRACE.
00048 : Base (upcall_functor, freelist) 00049 , spokes_(0) 00050 , spoke_count_(0) // calculated in open_i 00051 , spoke_bits_(0) 00052 , res_bits_ (0) 00053 , earliest_spoke_ (0) 00054 , iterator_(0) 00055 , timer_count_(0) 00056 { 00057 ACE_TRACE ("ACE_Timer_Wheel_T::ACE_Timer_Wheel_T"); 00058 this->open_i (0, 00059 ACE_DEFAULT_TIMER_WHEEL_SIZE, 00060 ACE_DEFAULT_TIMER_WHEEL_RESOLUTION); 00061 } |
|
||||||||||||||||||||||||||||
|
Constructor with opportunities to set the wheelsize and resolution. Constructor that sets up the timing wheel and also may preallocate some nodes on the free list
Definition at line 75 of file Timer_Wheel_T.cpp. References ACE_TRACE.
00080 : Base (upcall_functor, freelist) 00081 , spokes_ (0) 00082 , spoke_count_ (0) // calculated in open_i 00083 , spoke_bits_ (0) 00084 , res_bits_ (0) 00085 , earliest_spoke_ (0) 00086 , iterator_ (0) 00087 , timer_count_ (0) 00088 { 00089 ACE_TRACE ("ACE_Timer_Wheel_T::ACE_Timer_Wheel_T"); 00090 this->open_i (prealloc, spoke_count, resolution); 00091 } |
|
||||||||||
|
Destructor.
Definition at line 163 of file Timer_Wheel_T.cpp. References ACE_TRACE, ACE_Timer_Queue_T::free_node, ACE_Timer_Node_T::get_act, ACE_Timer_Node_T::get_next, ACE_Timer_Node_T::get_type, iterator_, spoke_count_, spokes_, and ACE_Timer_Queue_T::upcall_functor.
00164 {
00165 ACE_TRACE ("ACE_Timer_Wheel_T::~ACE_Timer_Wheel_T");
00166
00167 delete iterator_;
00168
00169 for (u_int i = 0; i < this->spoke_count_; ++i)
00170 {
00171 // Free all the nodes starting at the root
00172 ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
00173 for (ACE_Timer_Node_T<TYPE>* n = root->get_next (); n != root;)
00174 {
00175 ACE_Timer_Node_T<TYPE>* next = n->get_next ();
00176 this->upcall_functor ().deletion (*this, n->get_type (), n->get_act ());
00177 this->free_node (n);
00178 n = next;
00179 }
00180 delete root;
00181 }
00182 delete[] this->spokes_;
00183 }
|
|
||||||||||
|
|
|
||||||||||
|
Uses a simple hash to find which spoke to use based on when the timer is due to expire. Hopefully the 64bit int operations avoid any overflow problems.
Definition at line 266 of file Timer_Wheel_T.cpp. Referenced by reschedule, and schedule.
00267 {
00268 return ACE_static_cast(u_int, (t.msec () >> this->res_bits_) & (this->spoke_count_ - 1));
00269 }
|
|
||||||||||||||||||||
|
Cancels the single timer that is specified by the timer_id. In this case the timer_id is actually a pointer to the node, so we cast it to the node. This can be dangerous if the timer_id is made up (or deleted twice) so we do a little sanity check. Finally we update the earliest time in case the earliest timer was removed.
Implements ACE_Timer_Queue_T. Definition at line 571 of file Timer_Wheel_T.cpp. References ACE_GUARD_RETURN, ACE_MT, ACE_TRACE, cancel_i, find_node, ACE_Timer_Node_T::get_act, get_first_i, ACE_Timer_Node_T::get_timer_value, and recalc_earliest.
00574 {
00575 ACE_TRACE ("ACE_Timer_Wheel_T::cancel");
00576 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00577 ACE_Timer_Node_T<TYPE>* n = this->find_node (timer_id);
00578 if (n != 0)
00579 {
00580 ACE_Time_Value last = n->get_timer_value ();
00581 int recalc = (this->get_first_i () == n);
00582 if (act != 0)
00583 *act = n->get_act ();
00584 this->cancel_i (n, skip_close);
00585 if (recalc)
00586 this->recalc_earliest (last);
00587 return 1;
00588 }
00589 return 0;
00590 }
|
|
||||||||||||||||
|
Cancel all timer associated with <type>. If <dont_call> is 0 then the <functor> will be invoked. Returns number of timers cancelled. Goes through every list in the wheel and whenever we find one with the correct type value, we remove it and continue. At the end make sure we reset the earliest time value in case the earliest timers were removed.
Implements ACE_Timer_Queue_T. Definition at line 506 of file Timer_Wheel_T.cpp. References ACE_GUARD_RETURN, ACE_MT, ACE_TRACE, cancel_i, get_first, ACE_Timer_Node_T::get_next, ACE_Timer_Node_T::get_timer_value, ACE_Timer_Node_T::get_type, is_empty, recalc_earliest, spoke_count_, spokes_, and ACE_Timer_Queue_T::upcall_functor.
00507 {
00508 ACE_TRACE ("ACE_Timer_Wheel_T::cancel");
00509 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00510
00511 int num_canceled = 0; // Note : Technically this can overflow.
00512
00513 if (!this->is_empty ())
00514 {
00515 ACE_Timer_Node_T<TYPE>* first = this->get_first ();
00516 ACE_Time_Value last = first->get_timer_value ();
00517 int recalc = 0;
00518
00519 for (u_int i = 0; i < this->spoke_count_; ++i)
00520 {
00521 ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
00522 for (ACE_Timer_Node_T<TYPE>* n = root->get_next (); n != root; )
00523 {
00524 if (n->get_type () == type)
00525 {
00526 ++num_canceled;
00527 if (n == first)
00528 recalc = 1;
00529
00530 ACE_Timer_Node_T<TYPE>* tmp = n;
00531 n = n->get_next ();
00532 int always_skip_close = 1; // todo : Is this correct?
00533 this->cancel_i (tmp, always_skip_close);
00534 }
00535 else
00536 {
00537 n = n->get_next ();
00538 }
00539 }
00540 }
00541
00542 if (recalc)
00543 this->recalc_earliest (last);
00544 }
00545
00546 if (!skip_close) // && num_canceled > 0)
00547 this->upcall_functor().cancellation (*this, type);
00548
00549 return num_canceled;
00550 }
|
|
||||||||||||||||
|
Shared subset of the two cancel() methods.
Definition at line 594 of file Timer_Wheel_T.cpp. References ACE_Timer_Queue_T::free_node, ACE_Timer_Node_T::get_type, unlink, and ACE_Timer_Queue_T::upcall_functor. Referenced by cancel.
00595 {
00596 //ACE_ERROR((LM_ERROR, "Canceling %x\n", (long) n));
00597 this->unlink (n);
00598 this->free_node (n);
00599 if (!skip_close)
00600 this->upcall_functor ().cancellation (*this, n->get_type ());
00601 }
|
|
||||||||||
|
Dump the state of an object. Dumps out the size of the wheel, the resolution, and the contents of the wheel. Reimplemented from ACE_Timer_Queue_T. Definition at line 650 of file Timer_Wheel_T.cpp. References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_LIB_TEXT, ACE_TRACE, ACE_Timer_Node_T::dump, ACE_Timer_Node_T::get_next, LM_DEBUG, spoke_count_, and spokes_.
00651 {
00652 ACE_TRACE ("ACE_Timer_Wheel_T::dump");
00653 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00654
00655 ACE_DEBUG ((LM_DEBUG,
00656 ACE_LIB_TEXT ("\nspoke_count_ = %d"), this->spoke_count_));
00657 ACE_DEBUG ((LM_DEBUG,
00658 ACE_LIB_TEXT ("\nresolution_ = %d"), 1 << this->res_bits_));
00659 ACE_DEBUG ((LM_DEBUG,
00660 ACE_LIB_TEXT ("\nwheel_ = \n")));
00661
00662 for (u_int i = 0; i < this->spoke_count_; ++i)
00663 {
00664 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("%d\n"), i));
00665 ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
00666 for (ACE_Timer_Node_T<TYPE>* n = root->get_next ();
00667 n != root;
00668 n = n->get_next ())
00669 {
00670 n->dump ();
00671 }
00672 }
00673
00674 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00675 }
|
|
||||||||||
|
Returns the time of the earlier node in the <ACE_Timer_Wheel>. Must be called on a non-empty queue.
Implements ACE_Timer_Queue_T. Definition at line 252 of file Timer_Wheel_T.cpp. References ACE_TRACE, get_first_i, ACE_Timer_Node_T::get_timer_value, and ACE_Time_Value::zero.
00253 {
00254 ACE_TRACE ("ACE_Timer_Wheel_T::earliest_time");
00255 ACE_Timer_Node_T<TYPE>* n = this->get_first_i ();
00256 if (n != 0)
00257 return n->get_timer_value ();
00258 return ACE_Time_Value::zero;
00259 }
|
|
||||||||||
|
This is a specialized version of expire that is more suited for the internal data representation.
Reimplemented from ACE_Timer_Queue_T. Definition at line 769 of file Timer_Wheel_T.cpp. References ACE_GUARD_RETURN, ACE_MT, ACE_TRACE, ACE_Timer_Queue_T::free_node, ACE_Timer_Node_T::get_act, ACE_Timer_Node_T::get_interval, ACE_Timer_Node_T::get_type, remove_first_expired, reschedule, ACE_Timer_Node_T::set_timer_value, ACE_Timer_Queue_T::upcall, and ACE_Time_Value::zero.
00770 {
00771 ACE_TRACE ("ACE_Timer_Wheel_T::expire");
00772 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00773
00774 int expcount = 0;
00775 ACE_Timer_Node_T<TYPE>* n = this->remove_first_expired (cur_time);
00776
00777 while (n != 0)
00778 {
00779 ++ expcount;
00780
00781 //ACE_ERROR((LM_ERROR, "Expiring %x\n", (long) n));
00782
00783 this->upcall (n->get_type (), n->get_act (), cur_time);
00784
00785 if (n->get_interval () > ACE_Time_Value::zero)
00786 {
00787 n->set_timer_value (cur_time + n->get_interval ());
00788 this->reschedule (n);
00789 }
00790 else
00791 {
00792 this->free_node (n);
00793 }
00794
00795 n = this->remove_first_expired (cur_time);
00796 }
00797
00798 //ACE_ERROR((LM_ERROR, "Expired %d nodes\n", expcount));
00799
00800 return expcount;
00801 }
|
|
||||||||||
|
Run the <functor> for all timers whose values are <= <ACE_OS::gettimeofday>. Also accounts for <timer_skew>. Returns the number of timers canceled. Dummy version of expire to get rid of warnings in Sun CC 4.2 Just call the expire of the base class. Reimplemented from ACE_Timer_Queue_T. Definition at line 755 of file Timer_Wheel_T.cpp. References ACE_Timer_Queue_T::expire. Referenced by reschedule.
00756 {
00757 return ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::expire ();
00758 }
|
|
||||||||||
|
Searches all spokes for a node matching the specified timer_id Uses the spoke encoded in the timer_id as a starting place.
Definition at line 206 of file Timer_Wheel_T.cpp. References find_spoke_node, and spoke_count_. Referenced by cancel, and reset_interval.
00207 {
00208 if (timer_id == -1)
00209 return 0;
00210
00211 // Search the spoke where timer_id was originally scheduled
00212 u_int spoke_mask = this->spoke_count_ - 1;
00213 u_int start = timer_id & spoke_mask;
00214 ACE_Timer_Node_T<TYPE>* n = this->find_spoke_node (start, timer_id);
00215 if (n != 0)
00216 return n;
00217
00218 //ACE_ERROR((LM_ERROR, "Node not found in original spoke.\n"));
00219
00220 // Search the rest of the spokes
00221 for (u_int i = 0; i < this->spoke_count_; ++i)
00222 {
00223 if (i != start)
00224 { // already searched this one
00225 n = this->find_spoke_node (i, timer_id);
00226 if (n != 0)
00227 return n;
00228 }
00229 }
00230
00231 //ACE_ERROR((LM_ERROR, "Node not found.\n"));
00232 return 0;
00233 }
|
|
||||||||||||||||
|
Searches for a node by timer_id within one spoke.
Definition at line 189 of file Timer_Wheel_T.cpp. References ACE_Timer_Node_T::get_next, and ACE_Timer_Node_T::get_timer_id. Referenced by find_node, and generate_timer_id.
00190 {
00191 ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
00192 for (ACE_Timer_Node_T<TYPE>* n = root->get_next ();
00193 n != root;
00194 n = n->get_next ())
00195 {
00196 if (n->get_timer_id () == timer_id)
00197 return n;
00198 }
00199 return 0;
00200 }
|
|
||||||||||
|
Generates a unique timer_id for the given spoke. It should be pretty fast until the point where the counter overflows. At that time you have to do exhaustive searches within the spoke to ensure that a particular timer id is not already in use. Some optimizations are in place so that this hopefully doesn't have to happen often.
Definition at line 277 of file Timer_Wheel_T.cpp. References find_spoke_node, ACE_Timer_Node_T::get_act, ACE_Timer_Node_T::get_next, ACE_Timer_Node_T::get_timer_id, ACE_Timer_Node_T::set_act, ACE_Timer_Node_T::set_timer_id, spoke_bits_, spoke_count_, and spokes_. Referenced by schedule.
00278 {
00279
00280 int cnt_bits = sizeof (long) * 8 - this->spoke_bits_;
00281 long max_cnt = ((long)1 << cnt_bits) - 1;
00282 if (spoke == this->spoke_count_)
00283 --max_cnt; // Because -1 is used as a special invalid timer_id.
00284
00285 ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
00286
00287 if (root == root->get_next ())
00288 root->set_act(0);
00289
00290 // We use this field to keep track of the next counter value that
00291 // may be in use. Of course it may have expired, so we just use
00292 // this field so that we know when we don't have to check for duplicates
00293 #if defined (ACE_WIN64)
00294 // The cast below is legit... we know that long is shorter than a
00295 // pointer, but are only using it as a 'long' storage area.
00296 # pragma warning(push)
00297 # pragma warning(disable : 4311)
00298 #endif /* ACE_WIN64 */
00299 long next_cnt = ACE_reinterpret_cast (long, root->get_act ());
00300 #if defined (ACE_WIN64)
00301 # pragma warning(pop)
00302 #endif /* ACE_WIN64 */
00303
00304 // This field is used as a counter instead of a timer_id.
00305 long cnt = root->get_timer_id ();
00306
00307 if (cnt >= max_cnt && root == root->get_next ())
00308 {
00309 // Special case when we overflow on an empty spoke. We can just
00310 // wrap the count around without searching for duplicates. We only
00311 // want to do this when the counter overflows, so that we return
00312 // unique timer_id values as often as possible.
00313 root->set_timer_id (1);
00314 return spoke;
00315 }
00316 else if (cnt >= max_cnt)
00317 { // overflow
00318 cnt = 0; // try again starting at zero
00319 }
00320 else if (next_cnt == 0 || cnt < next_cnt)
00321 {
00322 root->set_timer_id (cnt + 1);
00323 return (cnt << this->spoke_bits_) | spoke;
00324 }
00325
00326 //ACE_ERROR((LM_ERROR, "Timer id overflow. We have to search now.\n"));
00327
00328 // We've run out of consecutive id numbers so now we have to search
00329 // for a unique id.
00330 // We'll try increasing numbers until we find one that is not in use,
00331 // and we'll record the next highest number so that we can avoid this
00332 // search as often as possible.
00333 for (; cnt < max_cnt - 1; ++cnt)
00334 {
00335 long id = (cnt << this->spoke_bits_) | spoke;
00336 ACE_Timer_Node_T<TYPE>* n = this->find_spoke_node (spoke, id);
00337 if (n == 0)
00338 {
00339 root->set_timer_id (cnt + 1);
00340 // Now we need to find the next highest cnt in use
00341 next_cnt = 0;
00342 for (; n != root; n = n->get_next ())
00343 {
00344 long tmp = n->get_timer_id () >> this->spoke_bits_;
00345 if (tmp > cnt && (tmp < next_cnt || next_cnt == 0))
00346 next_cnt = tmp;
00347 }
00348 #if defined (ACE_WIN64)
00349 // The cast below is legit... we know we're storing a long in
00350 // a pointer, but are only using it as a 'long' storage area.
00351 # pragma warning(push)
00352 # pragma warning(disable : 4312)
00353 #endif /* ACE_WIN64 */
00354 root->set_act (ACE_reinterpret_cast (void*, next_cnt));
00355 #if defined (ACE_WIN64)
00356 # pragma warning(pop)
00357 #endif /* ACE_WIN64 */
00358 return id;
00359 }
00360 }
00361
00362 return -1; // We did our best, but the spoke is full.
00363 }
|
|
||||||||||
|
Reads the earliest node from the queue and returns it. Returns the earliest node without removing it
Implements ACE_Timer_Queue_T. Definition at line 721 of file Timer_Wheel_T.cpp. References ACE_TRACE, and get_first_i. Referenced by cancel, and remove_first_expired.
00722 {
00723 ACE_TRACE ("ACE_Timer_Wheel_T::get_first");
00724 return this->get_first_i ();
00725 }
|
|
||||||||||
|
Definition at line 729 of file Timer_Wheel_T.cpp. References earliest_spoke_, ACE_Timer_Node_T::get_next, and spokes_. Referenced by cancel, earliest_time, and get_first.
00730 {
00731 ACE_Timer_Node_T<TYPE>* root = this->spokes_[this->earliest_spoke_];
00732 ACE_Timer_Node_T<TYPE>* first = root->get_next ();
00733 if (first != root)
00734 return first;
00735 return 0;
00736 }
|
|
||||||||||
|
True if queue is empty, else false. Check to see if the wheel is empty
Implements ACE_Timer_Queue_T. Definition at line 241 of file Timer_Wheel_T.cpp. References ACE_TRACE, and timer_count_. Referenced by cancel.
00242 {
00243 ACE_TRACE ("ACE_Timer_Wheel_T::is_empty");
00244 return timer_count_ == 0;
00245 }
|
|
||||||||||
|
Returns a pointer to this <ACE_Timer_Queue_T>'s iterator.
Implements ACE_Timer_Queue_T. Definition at line 744 of file Timer_Wheel_T.cpp. References ACE_Timer_Wheel_Iterator_T::first, and iterator_.
|
|
||||||||||||||||||||
|
Initialize the queue. Uses the established members for all needed information. Definition at line 127 of file Timer_Wheel_T.cpp. References ACE_NEW, ACE_TRACE, ACE_OS::gettimeofday, power2bits, ACE_Timer_Node_T::set, spoke_count_, and ACE_Time_Value::zero.
00128 {
00129 ACE_TRACE ("ACE_Timer_Wheel_T::open_i");
00130
00131 this->gettimeofday (ACE_OS::gettimeofday);
00132
00133 // Rather than waste bits in our timer id, we might as well round up
00134 // the spoke count to the next power of two - 1 . (i.e 1,3,7,15,...127,etc.)
00135 const int MIN_SPOKE_BITS = 3; // Allow between 8 and 4096 spokes
00136 const int MAX_SPOKE_BITS = 12;
00137 const int MAX_RES_BITS = 20; // 20 is plenty, even on 64 bit platforms.
00138
00139 this->spoke_bits_ = power2bits (spokes, MIN_SPOKE_BITS, MAX_SPOKE_BITS);
00140 this->res_bits_ = power2bits (res, 1, MAX_RES_BITS);
00141
00142 this->spoke_count_ = 1 << this->spoke_bits_;
00143
00144 this->free_list_->resize (prealloc + this->spoke_count_);
00145
00146 this->wheel_time_.msec (1 << (this->res_bits_ + this->spoke_bits_));
00147
00148 ACE_NEW (this->spokes_, ACE_Timer_Node_T<TYPE>* [this->spoke_count_]);
00149
00150 // Create the root nodes. These will be treated specially
00151 for (u_int i = 0; i < this->spoke_count_; ++i)
00152 {
00153 ACE_Timer_Node_T<TYPE>* root = this->alloc_node ();
00154 root->set (0, 0, ACE_Time_Value::zero, ACE_Time_Value::zero, root, root, 0);
00155 this->spokes_[i] = root;
00156 }
00157
00158 ACE_NEW (iterator_, Iterator (*this));
00159 }
|
|
||||||||||
|
|
|
||||||||||
|
There are a few places where we have to figure out which timer will expire next. This method makes the assumption that spokes are always sorted, and that timers are always in the correct spoke determined from their expiration time. The last time is always passed in, even though you can often calculate it as get_first()->get_timer_value().
Definition at line 611 of file Timer_Wheel_T.cpp. References ACE_Timer_Node_T::get_next, ACE_Timer_Node_T::get_timer_value, is_empty, and ACE_Time_Value::zero. Referenced by cancel, and remove_first_expired.
00612 {
00613 // This is possible because we use a count for is_empty()
00614 if (this->is_empty ())
00615 return;
00616
00617 ACE_Time_Value et = ACE_Time_Value::zero;
00618
00619 u_int spoke = this->earliest_spoke_;
00620
00621 // We will have to go around the wheel at most one time.
00622 for (u_int i = 0; i < this->spoke_count_; ++i)
00623 {
00624 ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
00625 ACE_Timer_Node_T<TYPE>* n = root->get_next ();
00626 if (n != root)
00627 {
00628 ACE_Time_Value t = n->get_timer_value ();
00629 if (t < last + this->wheel_time_)
00630 {
00631 this->earliest_spoke_ = spoke;
00632 return;
00633 }
00634 else if (et == ACE_Time_Value::zero || t < et)
00635 {
00636 et = t;
00637 }
00638 }
00639 if (++spoke >= this->spoke_count_)
00640 spoke = 0;
00641 }
00642 //ACE_ERROR((LM_ERROR, "We had to search the whole wheel.\n"));
00643 }
|
|
||||||||||
|
Removes the earliest node from the queue and returns it. Removes the earliest node and then find the new <earliest_spoke_>
Implements ACE_Timer_Queue_T. Definition at line 684 of file Timer_Wheel_T.cpp. References ACE_TRACE, ACE_Time_Value::max_time, and remove_first_expired.
00685 {
00686 ACE_TRACE ("ACE_Timer_Wheel_T::remove_first");
00687 return remove_first_expired (ACE_Time_Value::max_time);
00688 }
|
|
||||||||||
|
Definition at line 702 of file Timer_Wheel_T.cpp. References get_first, ACE_Timer_Node_T::get_timer_value, recalc_earliest, and unlink. Referenced by expire, and remove_first.
00703 {
00704 ACE_Timer_Node_T<TYPE>* n = this->get_first ();
00705 if (n != 0 && n->get_timer_value() <= now)
00706 {
00707 this->unlink (n);
00708 this->recalc_earliest (n->get_timer_value ());
00709 return n;
00710 }
00711 return 0;
00712 }
|
|
||||||||||
|
Takes an ACE_Timer_Node and inserts it into the correct position in the correct list. Also makes sure to update the earliest time.
Implements ACE_Timer_Queue_T. Definition at line 418 of file Timer_Wheel_T.cpp. References ACE_TRACE, calculate_spoke, expire, ACE_Timer_Node_T::get_timer_value, and schedule_i. Referenced by expire.
00419 {
00420 ACE_TRACE ("ACE_Timer_Wheel_T::reschedule");
00421 const ACE_Time_Value& expire = n->get_timer_value ();
00422 u_int spoke = calculate_spoke (expire);
00423 this->schedule_i (n, spoke, expire);
00424 }
|
|
||||||||||||||||
|
Changes the interval of a timer (and can make it periodic or non periodic by setting it to ACE_Time_Value::zero or not). Find the timer node by using the id as a pointer. Then use set_interval() on the node to update the interval.
Implements ACE_Timer_Queue_T. Definition at line 476 of file Timer_Wheel_T.cpp. References ACE_GUARD_RETURN, ACE_MT, ACE_TRACE, find_node, and ACE_Timer_Node_T::set_interval.
00479 {
00480 ACE_TRACE ("ACE_Timer_Wheel_T::reset_interval");
00481 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00482 ACE_Timer_Node_T<TYPE>* n = this->find_node (timer_id);
00483 if (n != 0)
00484 {
00485 // The interval will take effect the next time this node is expired.
00486 n->set_interval (interval);
00487 return 0;
00488 }
00489 return -1;
00490 }
|
|
||||||||||||||||||||||||
|
Schedules a timer. Creates a ACE_Timer_Node_T based on the input parameters. Then inserts the node into the wheel using reschedule (). Then returns a timer_id.
Implements ACE_Timer_Queue_T. Definition at line 379 of file Timer_Wheel_T.cpp. References ACE_GUARD_RETURN, ACE_MT, ACE_TRACE, ACE_Timer_Queue_T::alloc_node, calculate_spoke, generate_timer_id, schedule_i, and ACE_Timer_Node_T::set.
00385 {
00386 ACE_TRACE ("ACE_Timer_Wheel_T::schedule");
00387 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00388
00389 ACE_Timer_Node_T<TYPE>* n = this->alloc_node ();
00390
00391 if (n != 0)
00392 {
00393 u_int spoke = calculate_spoke (future_time);
00394 long id = generate_timer_id (spoke);
00395
00396 //ACE_ERROR((LM_ERROR, "Scheduling %x spoke:%d id:%d\n", (long) n, spoke, id));
00397
00398 if (id != -1)
00399 {
00400 n->set (type, act, future_time, interval, 0, 0, id);
00401 this->schedule_i (n, spoke, future_time);
00402 }
00403 return id;
00404 }
00405
00406 // Failure return
00407 errno = ENOMEM;
00408 return -1;
00409 }
|
|
||||||||||||||||||||
|
The shared scheduling functionality between schedule() and reschedule().
Definition at line 429 of file Timer_Wheel_T.cpp. References ACE_Timer_Node_T::get_next, ACE_Timer_Node_T::get_prev, ACE_Timer_Node_T::get_timer_value, is_empty, ACE_Timer_Node_T::set_next, and ACE_Timer_Node_T::set_prev. Referenced by reschedule, and schedule.
00432 {
00433 // See if we need to update the earliest time
00434 if (this->is_empty() || expire < this->earliest_time ())
00435 this->earliest_spoke_ = spoke;
00436
00437 ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
00438 ACE_Timer_Node_T<TYPE>* last = root->get_prev ();
00439
00440 ++timer_count_;
00441
00442 // If the spoke is empty
00443 if (last == root) {
00444 n->set_prev (root);
00445 n->set_next (root);
00446 root->set_prev (n);
00447 root->set_next (n);
00448 return;
00449 }
00450
00451 // We always want to search backwards from the tail of the list, because
00452 // this minimizes the search in the extreme case when lots of timers are
00453 // scheduled for exactly the same time
00454 ACE_Timer_Node_T<TYPE>* p = root->get_prev ();
00455 while (p != root && p->get_timer_value () > expire)
00456 p = p->get_prev ();
00457
00458 // insert after
00459 n->set_prev (p);
00460 n->set_next (p->get_next ());
00461 p->get_next ()->set_prev (n);
00462 p->set_next (n);
00463 }
|
|
||||||||||
|
Definition at line 691 of file Timer_Wheel_T.cpp. References ACE_TRACE, ACE_Timer_Node_T::get_next, ACE_Timer_Node_T::get_prev, ACE_Timer_Node_T::set_next, ACE_Timer_Node_T::set_prev, and timer_count_. Referenced by cancel_i, and remove_first_expired.
|
|
|||||
|
Iterator is a friend.
Definition at line 96 of file Timer_Wheel_T.h. |
|
|||||
|
Index of the list with the earliest time.
Definition at line 196 of file Timer_Wheel_T.h. Referenced by get_first_i. |
|
|||||
|
Iterator used to expire timers.
Definition at line 198 of file Timer_Wheel_T.h. Referenced by iter, and ~ACE_Timer_Wheel_T. |
|
|||||
|
Maximum number of timers per spoke.
Definition at line 192 of file Timer_Wheel_T.h. |
|
|||||
|
Resolution (in microsoconds) of the timing wheel.
Definition at line 194 of file Timer_Wheel_T.h. |
|
|||||
|
Number of timer_id bits used for the spoke.
Definition at line 190 of file Timer_Wheel_T.h. Referenced by generate_timer_id. |
|
|||||
|
Size of the timing wheel.
Definition at line 188 of file Timer_Wheel_T.h. Referenced by cancel, dump, find_node, generate_timer_id, ACE_Timer_Wheel_Iterator_T::goto_next, open_i, and ~ACE_Timer_Wheel_T. |
|
|||||
|
Timing Wheel.
Definition at line 186 of file Timer_Wheel_T.h. Referenced by cancel, dump, generate_timer_id, get_first_i, ACE_Timer_Wheel_Iterator_T::goto_next, ACE_Timer_Wheel_Iterator_T::next, and ~ACE_Timer_Wheel_T. |
|
|||||
|
The total number of timers currently scheduled.
Definition at line 202 of file Timer_Wheel_T.h. |
|
|||||
|
The total amount of time in one iteration of the wheel. (resolution * spoke_count).
Definition at line 200 of file Timer_Wheel_T.h. |
1.2.14 written by Dimitri van Heesch,
© 1997-2002