diff options
| author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-01-14 06:30:06 +0000 |
|---|---|---|
| committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-01-14 06:30:06 +0000 |
| commit | 6c2d206d92e1a65206097b8b1ceb5ee2b26c614e (patch) | |
| tree | 33bd534b39f1e5bf30c4f56bf7f08e17dd5329ad | |
| parent | 150dd3b206f682eab457909da327025f08e46e3a (diff) | |
| download | ATCD-6c2d206d92e1a65206097b8b1ceb5ee2b26c614e.tar.gz | |
foo
| -rw-r--r-- | ChangeLog-97a | 26 | ||||
| -rw-r--r-- | ace/Event_Handler.h | 18 | ||||
| -rw-r--r-- | ace/Memory_Pool.cpp | 2 | ||||
| -rw-r--r-- | ace/Synch.h | 10 | ||||
| -rw-r--r-- | ace/Synch.i | 16 | ||||
| -rw-r--r-- | ace/Timer_Heap.cpp | 206 | ||||
| -rw-r--r-- | ace/Timer_Heap.h | 30 | ||||
| -rw-r--r-- | ace/Timer_List.cpp | 22 | ||||
| -rw-r--r-- | ace/Timer_List.h | 14 | ||||
| -rw-r--r-- | ace/Timer_Queue.cpp | 12 | ||||
| -rw-r--r-- | ace/Timer_Queue.h | 11 | ||||
| -rw-r--r-- | ace/Timer_Queue.i | 12 | ||||
| -rw-r--r-- | ace/config-mvs.h | 3 | ||||
| -rw-r--r-- | examples/Reactor/Misc/test_timer_queue.cpp | 9 | ||||
| -rw-r--r-- | tests/Timer_Queue_Test.cpp | 39 |
15 files changed, 318 insertions, 112 deletions
diff --git a/ChangeLog-97a b/ChangeLog-97a index bf09132645c..f2b71a2c210 100644 --- a/ChangeLog-97a +++ b/ChangeLog-97a @@ -1,3 +1,23 @@ +Tue Jan 14 00:18:20 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> + + * ace/Timer_Heap: Implemented the spiffy new timer cancellation + algorithm that requires only O(log N) time to remove a timer + from the ACE_Timer_Heap. This is about 50 to 100 times faster + than using the ACE_Timer_List implementation. + +Mon Jan 13 17:57:50 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> + + * ace/Synch: Added lock() accessor methods to both + ACE_Process_Semaphore and ACE_Process_Mutex. Thanks to Hamutal + Yanay <Hamutal_Yanay@mail.icomverse.com> for suggesting this. + + * ace/config-mvs.h: Added a #define for ACE_HAS_GETPAGESIZE. + Thanks to Chuck Gehr for this information. + + * ace/LSOCK_Stream.h: Added a new typedef for PEER_ADDR that is + associated with ACE_UNIX_Addr. Thanks to Mark Rabotnikov + <mark@usp.elscintcorp.co.il> for suggesting this. + Mon Jan 13 22:24:09 1997 David L. Levine <levine@cs.wustl.edu> * ace/OS.h: Added #undefs of sigemptyset and sigfillset on Linux @@ -7,12 +27,6 @@ Mon Jan 13 22:24:09 1997 David L. Levine <levine@cs.wustl.edu> * tests/tests_config.h: Dropped ACE_MAX_ITERATIONS back to 10. -Mon Jan 13 00:17:50 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> - - * ace/LSOCK_Stream.h: Added a new typedef for PEER_ADDR that is - associated with ACE_UNIX_Addr. Thanks to Mark Rabotnikov - <mark@usp.elscintcorp.co.il> for suggesting this. - Sun Jan 12 16:59:52 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> * ace/Timer_List.cpp (schedule): Cleanup the code so that (1) diff --git a/ace/Event_Handler.h b/ace/Event_Handler.h index 78166e921d4..6d7ba541cfe 100644 --- a/ace/Event_Handler.h +++ b/ace/Event_Handler.h @@ -33,10 +33,9 @@ class ACE_Export ACE_Event_Handler // I/O, timer, and signal events. // // = DESCRIPTION - // Derived classes read/write input/output on an I/O - // descriptor, handle an exception raised on an I/O - // descriptor, handle a timer's expiration, or handle a - // signal. + // Subclasses read/write input/output on an I/O descriptor, + // handle an exception raised on an I/O descriptor, handle a + // timer's expiration, or handle a signal. { public: enum @@ -62,14 +61,15 @@ public: virtual ~ACE_Event_Handler (void); // Destructor is virtual to enable proper cleanup. - // = The following methods must be supplied by subclasses in order - // to specialize the behavior of an Event_Handler. virtual ACE_HANDLE get_handle (void) const; // Get the I/O handle. virtual void set_handle (ACE_HANDLE); // Set the I/O handle. - // = Priority runs from MIN_PRIORITY (which is the "lowest priority") to MAX_PRIORITY (which is the "highest priority"). + // = Get/set priority + + // Priorities run from MIN_PRIORITY (which is the "lowest priority") + // to MAX_PRIORITY (which is the "highest priority"). virtual int priority (void) const; // Get the priority of the Event_Handler. virtual void priority (int priority); @@ -97,7 +97,9 @@ public: // Called when object is signaled by OS (either via UNIX signals or // when a Win32 object becomes signaled). - // = <ACE_Proactor> callbacks. These are Win32 specific. An + // = ACE_Proactor callbacks. + + // At the moment, these methods are Win32 specific. An // Event_Handler can be given to a Proactor with a {RECV,SEND}_MASK. // The Proactor calls back <get_message> and <get_handle> to perform // the correct operations (send/recv). When the send/recv is diff --git a/ace/Memory_Pool.cpp b/ace/Memory_Pool.cpp index b43dde52c85..2392655b3d3 100644 --- a/ace/Memory_Pool.cpp +++ b/ace/Memory_Pool.cpp @@ -492,6 +492,7 @@ ACE_Shared_Memory_Pool::handle_signal (int , siginfo_t *siginfo, ucontext_t *) siginfo->si_addr), -1); } #endif /* ACE_HAS_SIGINFO_T && !defined (ACE_LACKS_SI_ADDR) */ + this->commit_backing_store_name (this->round_up (ACE_DEFAULT_SEGMENT_SIZE), offset); return 0; @@ -597,6 +598,7 @@ ACE_Shared_Memory_Pool::init_acquire (size_t nbytes, st[0].key_ = this->base_shm_key_; st[0].shmid_ = shmid; + st[0].used_ = 1; for (counter = 1; // Skip over the first entry... diff --git a/ace/Synch.h b/ace/Synch.h index eb65c76b570..9c8214da13a 100644 --- a/ace/Synch.h +++ b/ace/Synch.h @@ -271,6 +271,11 @@ public: // <tryacquire> and is only here to make the <ACE_Process_Semaphore> // interface consistent with the other synchronization APIs. +#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) + const ACE_sema_t &lock (void) const; + // Return the underlying lock. +#endif /* ACE_WIN32 */ + void dump (void) const; // Dump the state of an object. @@ -451,6 +456,11 @@ public: int tryacquire_write (void); // Conditionally acquire a lock (i.e., won't block). +#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) + const ACE_mutex_t &lock (void) const; + // Return the underlying mutex. +#endif /* ACE_WIN32 */ + void dump (void) const; // Dump the state of an object. diff --git a/ace/Synch.i b/ace/Synch.i index 2da2feba59a..7e95e4afb98 100644 --- a/ace/Synch.i +++ b/ace/Synch.i @@ -275,6 +275,22 @@ ACE_Semaphore::tryacquire_write (void) return this->tryacquire (); } +#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) +ACE_INLINE const ACE_mutex_t & +ACE_Process_Mutex::lock (void) const +{ +// ACE_TRACE ("ACE_Process_Mutex::lock"); + return this->lock_.lock (); +} + +ACE_INLINE const ACE_sema_t & +ACE_Process_Semaphore::lock (void) const +{ +// ACE_TRACE ("ACE_Process_Semaphore::lock"); + return this->lock_.lock (); +} +#endif /* ACE_WIN32 */ + // Acquire semaphore ownership. This calls <acquire> and is only here // to make the <ACE_Process_Semaphore> interface consistent with the // other synchronization APIs. diff --git a/ace/Timer_Heap.cpp b/ace/Timer_Heap.cpp index f32ab68bf88..1a1250f9748 100644 --- a/ace/Timer_Heap.cpp +++ b/ace/Timer_Heap.cpp @@ -3,12 +3,15 @@ ACE_Timer_Heap_Iterator::ACE_Timer_Heap_Iterator (ACE_Timer_Heap &heap) : timer_heap_ (heap) { + ACE_TRACE ("ACE_Timer_Heap_Iterator::ACE_Timer_Heap_Iterator"); } int ACE_Timer_Heap_Iterator::next (ACE_Timer_Node *&node, - const ACE_Time_Value &cur_time) + const ACE_Time_Value &cur_time) { + ACE_TRACE ("ACE_Timer_Heap_Iterator::next"); + if (this->timer_heap_.cur_size_ == 0 || this->timer_heap_.heap_[0]->timer_value_ > cur_time) return 0; @@ -24,15 +27,62 @@ ACE_Timer_Heap_Iterator::next (ACE_Timer_Node *&node, ACE_Timer_Heap::ACE_Timer_Heap (size_t size) : max_size_ (size), cur_size_ (0), - iterator_ (*this) + iterator_ (*this), + freelist_ (0) { - ACE_NEW (this->heap_, - ACE_Timer_Node *[size]); + ACE_TRACE ("ACE_Timer_Heap::ACE_Timer_Heap"); + + // Create the heap array. + ACE_NEW (this->heap_, ACE_Timer_Node *[size]); + + // Create the parallel + ACE_NEW (this->timer_ids_, int[size]); + + // Initialize the "freelist," which uses negative values to + // distinguish freelist elements from "pointers" into the <heap_> + // array. + for (int i = 0; i < size; i++) + this->timer_ids_[i] = -(i + 1); } ACE_Timer_Heap::~ACE_Timer_Heap (void) { + ACE_TRACE ("ACE_Timer_Heap::~ACE_Timer_Heap"); delete [] this->heap_; + delete [] this->timer_ids_; +} + +int +ACE_Timer_Heap::pop_freelist (void) +{ + ACE_TRACE ("ACE_Timer_Heap::pop_freelist"); + + int new_id = this->freelist_; + // The freelist values in the <timer_ids_> are negative, so we need + // to negate them to get the next freelist "pointer." + this->freelist_ = -this->timer_ids_[this->freelist_]; + ACE_ASSERT (this->freelist_ != this->max_size_); + return new_id; +} + +void +ACE_Timer_Heap::push_freelist (int old_id) +{ + ACE_TRACE ("ACE_Timer_Heap::push_freelist"); + + // The freelist values in the <timer_ids_> are negative, so we need + // to negate them to get the next freelist "pointer." + this->timer_ids_[old_id] = -this->freelist_; + this->freelist_ = old_id; +} + +int +ACE_Timer_Heap::timer_id (void) +{ + ACE_TRACE ("ACE_Timer_Heap::timer_id"); + + // Return the next item off the freelist and use it as the timer id. + return this->pop_freelist (); } // Checks if queue is empty. @@ -62,15 +112,37 @@ ACE_Timer_Heap::earliest_time (void) const void ACE_Timer_Heap::dump (void) const { - for (size_t index = 0; index < this->cur_size_; index++) - this->heap_[index]->dump (); + ACE_TRACE ("ACE_Timer_Heap::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, "\nmax_size_ = %d", this->max_size_)); + ACE_DEBUG ((LM_DEBUG, "\ncur_size_ = %d", this->cur_size_)); + ACE_DEBUG ((LM_DEBUG, "\nheap_ = \n")); + + for (size_t i = 0; i < this->cur_size_; i++) + { + ACE_DEBUG ((LM_DEBUG, "%d\n", i)); + this->heap_[i]->dump (); + } + + ACE_DEBUG ((LM_DEBUG, "\ntimer_ids_ = \n")); + + for (size_t j = 0; j < this->cur_size_; j++) + ACE_DEBUG ((LM_DEBUG, "%d\t%d\n", j, this->timer_ids_[j])); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } ACE_Timer_Node * -ACE_Timer_Heap::remove (int index) +ACE_Timer_Heap::remove (size_t index) { ACE_Timer_Node *result = this->heap_[index]; + // Return this timer id to the freelist. + this->push_freelist (result->timer_id_); + + // Decrement the size of the heap by one since we're removing the + // "index"th node. this->cur_size_--; // Only try to reheapify if we're not deleting the last entry. @@ -80,22 +152,26 @@ ACE_Timer_Heap::remove (int index) // Move the end node to the location being removed. this->heap_[index] = this->heap_[this->cur_size_]; + // Update the corresponding slot in the parallel <timer_ids> + // array. + this->timer_ids_[this->heap_[this->cur_size_]->timer_id_] = index; + ACE_Timer_Node *moved_node = this->heap_[index]; // If we're at the top there's no place to go but down! if (index == 0) - this->reheap_down (moved_node, 1); + this->reheap_down (moved_node, 1); // If the moved_node->time_value_ is smaller than its parent it // needs be moved up the heap. else if (moved_node->timer_value_ < this->heap_[(index - 1) / 2]->timer_value_) - this->reheap_up (moved_node); + this->reheap_up (moved_node); // Call <reheap_down>, which will reheapify if the // moved_node->time_value_ is larger than either of its children // (who start at location <index + index>). else - this->reheap_down (moved_node, index + index); + this->reheap_down (moved_node, index + index); } return result; @@ -103,7 +179,7 @@ ACE_Timer_Heap::remove (int index) void ACE_Timer_Heap::reheap_down (ACE_Timer_Node *moved_node, - int child_index) + size_t child_index) { int parent = 0; @@ -115,22 +191,32 @@ ACE_Timer_Heap::reheap_down (ACE_Timer_Node *moved_node, { // Choose the smaller of the two children. if (child + 1 < this->cur_size_ - && this->heap_[child + 1]->timer_value_ < this->heap_[child]->timer_value_) - child++; + && this->heap_[child + 1]->timer_value_ < this->heap_[child]->timer_value_) + child++; // Perform a swap if the child has a larger timeout value than // the front node. if (this->heap_[child]->timer_value_ < moved_node->timer_value_) - { - this->heap_[parent] = this->heap_[child]; - parent = child; - } + { + // Insert the child node into its new location in the heap. + this->heap_[parent] = this->heap_[child]; + + // Update the corresponding slot in the parallel <timer_ids> + // array. + this->timer_ids_[this->heap_[child]->timer_id_] = parent; + + parent = child; + } else - break; + break; } // Insert moved_node into its final resting place. this->heap_[parent] = moved_node; + + // Update the corresponding slot in the parallel <timer_ids> + // array. + this->timer_ids_[moved_node->timer_id_] = parent; } void @@ -152,16 +238,27 @@ ACE_Timer_Heap::reheap_up (ACE_Timer_Node *new_node) { parent = (child - 1) / 2; + // If the parent node is great than the new node we need to swap + // them. if (new_node->timer_value_ < this->heap_[parent]->timer_value_) - { - this->heap_[child] = this->heap_[parent]; - child = parent; - } + { + // Insert the parent node into its new location in the heap. + this->heap_[child] = this->heap_[parent]; + + // Update the corresponding slot in the parallel <timer_ids> + // array. + this->timer_ids_[this->heap_[parent]->timer_id_] = child; + child = parent; + } else - break; + break; } + // Insert the new node into its proper resting place in the heap. this->heap_[child] = new_node; + + // Update the corresponding slot in the parallel <timer_ids> array. + this->timer_ids_[new_node->timer_id_] = child; } // Reschedule a periodic timer. This function must be called with the @@ -181,34 +278,33 @@ ACE_Timer_Heap::reschedule (ACE_Timer_Node *expired) int ACE_Timer_Heap::schedule (ACE_Event_Handler *handler, - const void *arg, - const ACE_Time_Value &future_time, - const ACE_Time_Value &interval) + const void *arg, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval) { ACE_TRACE ("ACE_Timer_Heap::schedule"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); - // Increment the sequence number (it will wrap around). - int timer_id = this->timer_id (); + int timer_id = -1; if (this->cur_size_ >= this->max_size_) - { - errno = ENOMEM; - return -1; - } + errno = ENOMEM; else { + // Obtain the next unique sequence number. + timer_id = this->timer_id (); + ACE_Timer_Node *temp; ACE_NEW_RETURN (temp, - ACE_Timer_Node (handler, - arg, - future_time, - interval, - 0, - timer_id), - -1); + ACE_Timer_Node (handler, + arg, + future_time, + interval, + 0, + timer_id), + -1); this->insert (temp); } @@ -221,28 +317,26 @@ ACE_Timer_Heap::schedule (ACE_Event_Handler *handler, int ACE_Timer_Heap::cancel (int timer_id, - const void **arg) + const void **arg) { ACE_TRACE ("ACE_Timer_Heap::cancel"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); - int i; + // Locate the ACE_Timer_Node that corresponds to the timer_id. - // Try to locate the ACE_Timer_Node that matches the timer_id. + int timer_node_slot = this->timer_ids_[timer_id]; - for (i = 0; - i < this->cur_size_ && this->heap_[i]->timer_id_ != timer_id; - i++) - continue; - - if (i == this->cur_size_) - return 0; + if (timer_id != this->heap_[timer_node_slot]->timer_id_) + { + ACE_ASSERT (timer_id == this->heap_[timer_node_slot]->timer_id_); + return 0; + } else { - ACE_Timer_Node *temp = this->remove (i); + ACE_Timer_Node *temp = this->remove (timer_node_slot); if (arg != 0) - *arg = temp->arg_; + *arg = temp->arg_; delete temp; return 1; @@ -266,11 +360,11 @@ ACE_Timer_Heap::cancel (ACE_Event_Handler *handler) ) { if (this->heap_[i]->handler_ == handler) - { - ACE_Timer_Node *temp = this->remove (i); - delete temp; - number_of_cancellations++; - } + { + ACE_Timer_Node *temp = this->remove (i); + delete temp; + number_of_cancellations++; + } else i++; } diff --git a/ace/Timer_Heap.h b/ace/Timer_Heap.h index c3b1559b769..63f8e27faf3 100644 --- a/ace/Timer_Heap.h +++ b/ace/Timer_Heap.h @@ -114,7 +114,7 @@ protected: // Returns a pointer to this <ACE_Timer_Queue>'s iterator. private: - ACE_Timer_Node *remove (int index); + ACE_Timer_Node *remove (size_t index); // Remove and return the <index>th <ACE_Timer_Node> and restore the // heap property. @@ -124,9 +124,21 @@ private: void reheap_up (ACE_Timer_Node *new_node); // Restore the heap property. - void reheap_down (ACE_Timer_Node *moved_node, int child_index); + void reheap_down (ACE_Timer_Node *moved_node, size_t child_index); // Restore the heap property, starting at <child_index>. + int timer_id (void); + // Returns a timer id that uniquely identifies this timer. This id + // can be used to cancel a timer via the <cancel (int)> method. The + // timer id returned from this method will never == -1 to avoid + // conflicts with other failure return values. + + int pop_freelist (void); + // Pops and returns a new timer id from the freelist. + + void push_freelist (int old_id); + // Pushes <old_id> onto the freelist. + size_t max_size_; // Maximum size of the heap. @@ -141,6 +153,20 @@ private: // <ACE_Timer_Node> *'s. In this context, a heap is a "partially // ordered, almost complete" binary tree, which is stored in an // array. + + int *timer_ids_; + // An array of "pointers" that allows each <ACE_Timer_Node> in the + // <heap_> to be located in O(1) time. Basically, <timer_id_[i]> + // contains the index in the <heap_> array where an <ACE_Timer_Node> + // * with timer id <i> resides. Thus, the timer id passed back from + // <schedule> is really an index into the <timer_ids> array. The + // <timer_ids_> array serves two purposes: negative values are + // treated as "pointers" for the <freelist_>, whereas positive + // values are treated as "pointers" into the <heap_> array. + + int freelist_; + // "Pointer" to the first element in the freelist contained within + // the <timer_ids_> array. }; #endif /* ACE_TIMER_HEAP_H */ diff --git a/ace/Timer_List.cpp b/ace/Timer_List.cpp index 0d9cdd53047..deef677f0c4 100644 --- a/ace/Timer_List.cpp +++ b/ace/Timer_List.cpp @@ -72,6 +72,16 @@ ACE_Timer_List::~ACE_Timer_List (void) } } +void +ACE_Timer_List::dump (void) const +{ + ACE_TRACE ("ACE_Timer_List::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\nhead_ = %d", this->head_)); + ACE_DEBUG ((LM_DEBUG, "\ntimer_id_ = %d", this->timer_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + // Reschedule a periodic timer. This function must be called with the // mutex lock held. @@ -158,6 +168,18 @@ ACE_Timer_List::schedule (ACE_Event_Handler *handler, } } +int +ACE_Timer_List::timer_id (void) +{ + this->timer_id_++; + + // Make sure this never == -1 + if (this->timer_id_ == -1) + this->timer_id_ = 0; + + return this->timer_id_; +} + // Locate and remove the single <ACE_Event_Handler> with a value of // <timer_id> from the timer queue. diff --git a/ace/Timer_List.h b/ace/Timer_List.h index 43c6b141f7b..624fdab67db 100644 --- a/ace/Timer_List.h +++ b/ace/Timer_List.h @@ -109,7 +109,16 @@ public: // Returns 1 if cancellation succeeded and 0 if the <timer_id> // wasn't found. + virtual void dump (void) const; + // Dump the state of an object. + private: + int timer_id (void); + // Returns a timer id that uniquely identifies this timer. This id + // can be used to cancel a timer via the <cancel (int)> method. The + // timer id returned from this method will never == -1 to avoid + // conflicts with other failure return values. + virtual void reschedule (ACE_Timer_Node *); // Reschedule an "interval" <ACE_Timer_Node>. @@ -121,6 +130,11 @@ private: ACE_Timer_List_Iterator iterator_; // Iterator used to expire timers. + + int timer_id_; + // Keeps track of the timer id that uniquely identifies each timer. + // This id can be used to cancel a timer via the <cancel (int)> + // method. }; #endif /* ACE_TIMER_LIST_H */ diff --git a/ace/Timer_Queue.cpp b/ace/Timer_Queue.cpp index 5e9dd26e6ed..d59464a9932 100644 --- a/ace/Timer_Queue.cpp +++ b/ace/Timer_Queue.cpp @@ -14,6 +14,14 @@ void ACE_Timer_Node::dump (void) const { ACE_TRACE ("ACE_Timer_Node::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\nhandler_ = %x", this->handler_)); + ACE_DEBUG ((LM_DEBUG, "\narg_ = %x", this->arg_)); + this->timer_value_.dump (); + this->interval_.dump (); + ACE_DEBUG ((LM_DEBUG, "\nnext_ = %x", this->next_)); + ACE_DEBUG ((LM_DEBUG, "\ntimer_id_ = %d", this->timer_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } ACE_Timer_Node::ACE_Timer_Node (ACE_Event_Handler *h, @@ -82,13 +90,13 @@ ACE_Timer_Queue::dump (void) const { ACE_TRACE ("ACE_Timer_Queue::dump"); ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->timeout_.dump (); this->timer_skew_.dump (); ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } ACE_Timer_Queue::ACE_Timer_Queue (void) - : timer_id_ (0), - timer_skew_ (0, ACE_TIMER_SKEW) + : timer_skew_ (0, ACE_TIMER_SKEW) { ACE_TRACE ("ACE_Timer_Queue::ACE_Timer_Queue"); diff --git a/ace/Timer_Queue.h b/ace/Timer_Queue.h index 454ba44f0e1..f44abd3edaf 100644 --- a/ace/Timer_Queue.h +++ b/ace/Timer_Queue.h @@ -183,23 +183,12 @@ protected: virtual ACE_Timer_Queue_Iterator &iterator (void) = 0; // Returns a pointer to this <ACE_Timer_Queue>'s iterator. - virtual int timer_id (void); - // Returns a timer id that uniquely identifies this timer. This id - // can be used to cancel a timer via the <cancel (int)> method. The - // timer id returned from this method will never == -1 to avoid - // conflicts with other failure return values. - #if defined (ACE_MT_SAFE) ACE_Recursive_Thread_Mutex lock_; // Synchronization variable for the MT_SAFE ACE_Reactor #endif /* ACE_MT_SAFE */ private: - int timer_id_; - // Keeps track of the timer id that uniquely identifies each timer. - // This id can be used to cancel a timer via the <cancel (int)> - // method. - ACE_Time_Value timeout_; // Returned by <calculate_timeout>. diff --git a/ace/Timer_Queue.i b/ace/Timer_Queue.i index 7d344138d23..480103b0062 100644 --- a/ace/Timer_Queue.i +++ b/ace/Timer_Queue.i @@ -9,18 +9,6 @@ ACE_Timer_Queue::timer_skew (const ACE_Time_Value &skew) timer_skew_ = skew; } -ACE_INLINE int -ACE_Timer_Queue::timer_id (void) -{ - this->timer_id_++; - - // Make sure this never == -1 - if (this->timer_id_ == -1) - this->timer_id_ = 0; - - return this->timer_id_; -} - ACE_INLINE const ACE_Time_Value & ACE_Timer_Queue::timer_skew (void) const { diff --git a/ace/config-mvs.h b/ace/config-mvs.h index c6f13364a32..4bd501e1419 100644 --- a/ace/config-mvs.h +++ b/ace/config-mvs.h @@ -4,6 +4,9 @@ #if !defined (ACE_CONFIG_H) #define ACE_CONFIG_H +// Platform supports getpagesize() call. +#define ACE_HAS_GETPAGESIZE + // The following #defines are hacks to get around things // that seem to be missing or different in MVS land #define MAXPATHLEN 1024 /* sys/param.h not on MVS */ diff --git a/examples/Reactor/Misc/test_timer_queue.cpp b/examples/Reactor/Misc/test_timer_queue.cpp index c30525c1edb..ac2a026abf0 100644 --- a/examples/Reactor/Misc/test_timer_queue.cpp +++ b/examples/Reactor/Misc/test_timer_queue.cpp @@ -52,6 +52,15 @@ test_functionality (ACE_Timer_Queue *tq) ACE_ASSERT (tq->expire () == 0); } +struct Timer_Queues +{ + ACE_Timer_Queue *queue_; + // Pointer to the subclass of <ACE_Timer_Queue> that we're testing. + + const char *name_; + // Name of the Queue that we're testing. +}; + static Timer_Queues timer_queues[] = { { new ACE_Timer_List, "ACE_Timer_List" }, diff --git a/tests/Timer_Queue_Test.cpp b/tests/Timer_Queue_Test.cpp index 356ae3f9add..662da195e4c 100644 --- a/tests/Timer_Queue_Test.cpp +++ b/tests/Timer_Queue_Test.cpp @@ -26,10 +26,10 @@ #include "test_config.h" // Number of iterations for the performance tests. -static const int MAX_ITERATIONS = ACE_DEFAULT_MAX_TIMERS; +static int max_iterations = ACE_DEFAULT_MAX_TIMERS; // Keep track of the timer ids that were assigned to us. -static int timer_ids[MAX_ITERATIONS]; +static int *timer_ids; class Example_Handler : public ACE_Event_Handler { @@ -59,7 +59,7 @@ test_functionality (ACE_Timer_Queue *tq) ACE_ASSERT (tq->schedule (&eh, (const void *) 42, ACE_OS::gettimeofday ()) != -1); ACE_ASSERT (tq->cancel (timer_id) == 1); - ACE_ASSERT (!tq->is_empty ()); + ACE_ASSERT (tq->is_empty () == 0); ACE_ASSERT (tq->expire () == 2); @@ -87,13 +87,13 @@ test_performance (ACE_Timer_Queue *tq, timer.start (); - for (i = 0; i < MAX_ITERATIONS; i++) + for (i = 0; i < max_iterations; i++) { timer_ids[i] = tq->schedule (&eh, (const void *) 42, ACE_OS::gettimeofday ()); ACE_ASSERT (timer_ids[i] != -1); } - ACE_ASSERT (!tq->is_empty ()); + ACE_ASSERT (tq->is_empty () == 0); timer.stop (); @@ -102,11 +102,11 @@ test_performance (ACE_Timer_Queue *tq, timer.elapsed_time (et); ACE_DEBUG ((LM_DEBUG, "time to schedule %d timers for %s\n", - MAX_ITERATIONS, test_name)); + max_iterations, test_name)); ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", et.real_time, et.user_time, et.system_time)); ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", - (et.real_time / double (MAX_ITERATIONS)) * 1000000)); + (et.real_time / double (max_iterations)) * 1000000)); // Test the amount of time required to cancel all the timers. We // start from the "back" in order to measure the worst case @@ -114,7 +114,7 @@ test_performance (ACE_Timer_Queue *tq, timer.start (); - for (i = MAX_ITERATIONS - 1; i >= 0; i--) + for (i = max_iterations - 1; i >= 0; i--) tq->cancel (timer_ids[i]); ACE_ASSERT (tq->is_empty ()); @@ -124,21 +124,21 @@ test_performance (ACE_Timer_Queue *tq, timer.elapsed_time (et); ACE_DEBUG ((LM_DEBUG, "time to cancel %d timers for %s\n", - MAX_ITERATIONS, test_name)); + max_iterations, test_name)); ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", et.real_time, et.user_time, et.system_time)); ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", - (et.real_time / double (MAX_ITERATIONS)) * 1000000)); + (et.real_time / double (max_iterations)) * 1000000)); // Test the amount of time required to schedule and expire all the // timers. timer.start (); - for (i = 0; i < MAX_ITERATIONS; i++) + for (i = 0; i < max_iterations; i++) ACE_ASSERT (tq->schedule (&eh, (const void *) 42, ACE_OS::gettimeofday ()) != -1); - ACE_ASSERT (!tq->is_empty ()); + ACE_ASSERT (tq->is_empty () == 0); // Expire all the timers. tq->expire (); @@ -148,11 +148,11 @@ test_performance (ACE_Timer_Queue *tq, timer.elapsed_time (et); ACE_DEBUG ((LM_DEBUG, "time to schedule and expire %d timers for %s\n", - MAX_ITERATIONS, test_name)); + max_iterations, test_name)); ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", et.real_time, et.user_time, et.system_time)); ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", - (et.real_time / double (MAX_ITERATIONS)) * 1000000)); + (et.real_time / double (max_iterations)) * 1000000)); } struct Timer_Queues @@ -172,12 +172,21 @@ static Timer_Queues timer_queues[] = }; int -main (int, char *[]) +main (int argc, char *argv[]) { ACE_START_TEST ("Timer_Queue_Test"); + if (argc > 1) + max_iterations = ACE_OS::atoi (argv[1]); + + ACE_NEW_RETURN (timer_ids, + int[max_iterations], + -1); + for (int i = 0; timer_queues[i].name_ != 0; i++) { + ACE_DEBUG ((LM_DEBUG, "**** starting test of %s\n", + timer_queues[i].name_)); test_performance (timer_queues[i].queue_, timer_queues[i].name_); test_functionality (timer_queues[i].queue_); delete timer_queues[i].queue_; |
