summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog-97a6
-rw-r--r--ace/LSOCK_Stream.h4
-rw-r--r--ace/Timer_Heap.cpp143
-rw-r--r--ace/Timer_Heap.h31
-rw-r--r--ace/Timer_List.cpp6
-rw-r--r--ace/Timer_List.h12
-rw-r--r--ace/Timer_Queue.h2
-rw-r--r--tests/Timer_Queue_Test.cpp94
8 files changed, 195 insertions, 103 deletions
diff --git a/ChangeLog-97a b/ChangeLog-97a
index 6a2006ca745..79d662aa670 100644
--- a/ChangeLog-97a
+++ b/ChangeLog-97a
@@ -1,3 +1,9 @@
+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/LSOCK_Stream.h b/ace/LSOCK_Stream.h
index ac8448fc13d..4903787777e 100644
--- a/ace/LSOCK_Stream.h
+++ b/ace/LSOCK_Stream.h
@@ -19,6 +19,7 @@
#define ACE_LOCAL_SOCK_STREAM_H
#include "ace/SOCK_Stream.h"
+#include "ace/UNIX_Addr.h"
#include "ace/LSOCK.h"
#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS)
@@ -41,6 +42,9 @@ public:
void set_handle (ACE_HANDLE fd);
// Overrides set_handle from the base classes.
+ // = Meta-type info
+ typedef ACE_UNIX_Addr PEER_ADDR;
+
void dump (void) const;
// Dump the state of an object.
diff --git a/ace/Timer_Heap.cpp b/ace/Timer_Heap.cpp
index b69872928eb..f32ab68bf88 100644
--- a/ace/Timer_Heap.cpp
+++ b/ace/Timer_Heap.cpp
@@ -14,15 +14,9 @@ ACE_Timer_Heap_Iterator::next (ACE_Timer_Node *&node,
return 0;
else
{
- node = this->timer_heap_.heap_[0];
+ // Remove the first item and restore the heap property.
- // Transfer the last element in the heap to the front and
- // restore the heap property.
-
- this->timer_heap_.heap_[0] =
- this->timer_heap_.heap_[--this->timer_heap_.cur_size_];
-
- this->timer_heap_.reheap_down ();
+ node = this->timer_heap_.remove (0);
return 1;
}
}
@@ -72,49 +66,93 @@ ACE_Timer_Heap::dump (void) const
this->heap_[index]->dump ();
}
-void
-ACE_Timer_Heap::reheap_down (void)
+ACE_Timer_Node *
+ACE_Timer_Heap::remove (int index)
+{
+ ACE_Timer_Node *result = this->heap_[index];
+
+ this->cur_size_--;
+
+ // Only try to reheapify if we're not deleting the last entry.
+
+ if (index < this->cur_size_)
+ {
+ // Move the end node to the location being removed.
+ this->heap_[index] = this->heap_[this->cur_size_];
+
+ 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);
+
+ // 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);
+
+ // 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);
+ }
+
+ return result;
+}
+
+void
+ACE_Timer_Heap::reheap_down (ACE_Timer_Node *moved_node,
+ int child_index)
{
int parent = 0;
- int child = 1;
- ACE_Timer_Node *temp = this->heap_[parent];
- // Restore the heap property.
+ // Restore the heap property after a deletion.
- while (child < this->cur_size_)
+ for (int child = child_index;
+ child < this->cur_size_;
+ child += child + 1) // Multiple child by 2 and add 1.
{
+ // Choose the smaller of the two children.
if (child + 1 < this->cur_size_
- && this->heap_[child + 1]->timer_value_ > this->heap_[child]->timer_value_)
+ && this->heap_[child + 1]->timer_value_ < this->heap_[child]->timer_value_)
child++;
- if (this->heap_[child]->timer_value_ > temp->timer_value_)
+ // 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;
- // Multiple child by 2 and add 1.
- child += child + 1;
}
else
break;
}
- this->heap_[parent] = temp;
+ // Insert moved_node into its final resting place.
+ this->heap_[parent] = moved_node;
+}
+
+void
+ACE_Timer_Heap::insert (ACE_Timer_Node *new_node)
+{
+ this->reheap_up (new_node);
+ this->cur_size_++;
}
void
-ACE_Timer_Heap::reheap_up (void)
+ACE_Timer_Heap::reheap_up (ACE_Timer_Node *new_node)
{
int parent;
- int child = this->cur_size_ - 1;
- ACE_Timer_Node *temp = this->heap_[child];
-
- // Restore the heap property.
+ int child = this->cur_size_;
+
+ // Restore the heap property after an insertion.
while (child > 0)
{
parent = (child - 1) / 2;
- if (temp->timer_value_ < this->heap_[parent]->timer_value_)
+ if (new_node->timer_value_ < this->heap_[parent]->timer_value_)
{
this->heap_[child] = this->heap_[parent];
child = parent;
@@ -123,7 +161,7 @@ ACE_Timer_Heap::reheap_up (void)
break;
}
- this->heap_[child] = temp;
+ this->heap_[child] = new_node;
}
// Reschedule a periodic timer. This function must be called with the
@@ -134,10 +172,8 @@ ACE_Timer_Heap::reschedule (ACE_Timer_Node *expired)
{
ACE_TRACE ("ACE_Timer_Heap::reschedule");
- // Insert the <expired> node into the end of the heap and restore
- // the heap property.
- this->heap_[this->cur_size_++] = expired;
- this->reheap_up ();
+ // Restore the heap property.
+ this->insert (expired);
}
// Insert a new handler that expires at time future_time; if interval
@@ -174,7 +210,7 @@ ACE_Timer_Heap::schedule (ACE_Event_Handler *handler,
timer_id),
-1);
- this->reheap_up (temp);
+ this->insert (temp);
}
return timer_id;
@@ -184,12 +220,33 @@ ACE_Timer_Heap::schedule (ACE_Event_Handler *handler,
// <timer_id> from the timer queue.
int
-ACE_Timer_Heap::cancel (int timer_id, const void **arg)
+ACE_Timer_Heap::cancel (int timer_id,
+ const void **arg)
{
ACE_TRACE ("ACE_Timer_Heap::cancel");
ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
- return 0;
+ int i;
+
+ // Try to locate the ACE_Timer_Node that matches the 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;
+ else
+ {
+ ACE_Timer_Node *temp = this->remove (i);
+
+ if (arg != 0)
+ *arg = temp->arg_;
+
+ delete temp;
+ return 1;
+ }
}
// Locate and remove all values of <handler> from the timer queue.
@@ -200,5 +257,23 @@ ACE_Timer_Heap::cancel (ACE_Event_Handler *handler)
ACE_TRACE ("ACE_Timer_Heap::cancel");
ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
- return 0;
+ int number_of_cancellations = 0;
+
+ // Try to locate the ACE_Timer_Node that matches the timer_id.
+
+ for (int i = 0;
+ i < this->cur_size_;
+ )
+ {
+ if (this->heap_[i]->handler_ == handler)
+ {
+ ACE_Timer_Node *temp = this->remove (i);
+ delete temp;
+ number_of_cancellations++;
+ }
+ else
+ i++;
+ }
+
+ return number_of_cancellations;
}
diff --git a/ace/Timer_Heap.h b/ace/Timer_Heap.h
index 873b7985509..40e7ea8588a 100644
--- a/ace/Timer_Heap.h
+++ b/ace/Timer_Heap.h
@@ -103,22 +103,6 @@ public:
// Returns 1 if cancellation succeeded and 0 if the <timer_id>
// wasn't found.
- virtual int expire (const ACE_Time_Value &current_time);
- // Run the <handle_timeout> method for all Timers whose values are
- // <= <cur_time>. This does not account for <timer_skew>. Returns
- // the number of <Event_Handler>s for which <handle_timeout> was
- // called.
-
- virtual int expire (void);
- // Run the <handle_timeout> method for all Timers whose values are
- // <= <ACE_OS::gettimeofday>. Also accounts for <timer_skew>.
- // Returns the number of <Event_Handler>s for which <handle_timeout>
- // was called.
-
- virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max);
- // Determine the next event to timeout. Returns <max> if there are
- // no pending timers or if all pending timers are longer than max.
-
virtual void dump (void) const;
// Dump the state of an object.
@@ -130,11 +114,18 @@ protected:
// Returns a pointer to this <ACE_Timer_Queue>'s iterator.
private:
- void reheap_down (void);
- // Called after a deletion to restore the heap property.
+ ACE_Timer_Node *remove (int index);
+ // Remove and return the <index>th <ACE_Timer_Node> and restore the
+ // heap property.
+
+ void insert (ACE_Timer_Node *new_node);
+ // Insert <new_node> into the heap and restore the heap property.
+
+ void reheap_up (ACE_Timer_Node *new_node);
+ // Restore the heap property.
- void reheap_up (void);
- // Called after an insertion to restore the heap property.
+ void reheap_down (ACE_Timer_Node *moved_node, int child_index);
+ // Restore the heap property, starting at <child_index>.
size_t max_size_;
// Maximum size of the heap.
diff --git a/ace/Timer_List.cpp b/ace/Timer_List.cpp
index 5b0be11591a..0d9cdd53047 100644
--- a/ace/Timer_List.cpp
+++ b/ace/Timer_List.cpp
@@ -1,11 +1,5 @@
#include "ace/Timer_List.h"
-int
-ACE_Timer_List::expire (void)
-{
- return this->ACE_Timer_Queue::expire ();
-}
-
ACE_Timer_List_Iterator::ACE_Timer_List_Iterator (ACE_Timer_List &list)
: timer_list_ (list)
{
diff --git a/ace/Timer_List.h b/ace/Timer_List.h
index 14b4c38b6e6..43c6b141f7b 100644
--- a/ace/Timer_List.h
+++ b/ace/Timer_List.h
@@ -109,18 +109,6 @@ public:
// Returns 1 if cancellation succeeded and 0 if the <timer_id>
// wasn't found.
- virtual int expire (const ACE_Time_Value &current_time);
- // Run the <handle_timeout> method for all Timers whose values are
- // <= <cur_time>. This does not account for <timer_skew>. Returns
- // the number of <Event_Handler>s for which <handle_timeout> was
- // called.
-
- virtual int expire (void);
- // Run the <handle_timeout> method for all Timers whose values are
- // <= <ACE_OS::gettimeofday>. Also accounts for <timer_skew>.
- // Returns the number of <Event_Handler>s for which <handle_timeout>
- // was called.
-
private:
virtual void reschedule (ACE_Timer_Node *);
// Reschedule an "interval" <ACE_Timer_Node>.
diff --git a/ace/Timer_Queue.h b/ace/Timer_Queue.h
index 6c70cccd595..454ba44f0e1 100644
--- a/ace/Timer_Queue.h
+++ b/ace/Timer_Queue.h
@@ -150,7 +150,7 @@ public:
// Returns 1 if cancellation succeeded and 0 if the <timer_id>
// wasn't found.
- virtual int expire (const ACE_Time_Value &current_time) = 0;
+ virtual int expire (const ACE_Time_Value &current_time);
// Run the <handle_timeout> method for all Timers whose values are
// <= <cur_time>. This does not account for <timer_skew>. Returns
// the number of <Event_Handler>s for which <handle_timeout> was
diff --git a/tests/Timer_Queue_Test.cpp b/tests/Timer_Queue_Test.cpp
index 2ff194ba59f..356ae3f9add 100644
--- a/tests/Timer_Queue_Test.cpp
+++ b/tests/Timer_Queue_Test.cpp
@@ -16,15 +16,20 @@
// command line arguments are needed to run the test.
//
// = AUTHOR
-// Prashant Jain
+// Prashant Jain and Douglas C. Schmidt
//
// ============================================================================
+#include "ace/Profile_Timer.h"
#include "ace/Timer_List.h"
#include "ace/Timer_Heap.h"
#include "test_config.h"
-const int MAX_ITERATIONS = ACE_DEFAULT_MAX_TIMERS - 1;
+// Number of iterations for the performance tests.
+static const int MAX_ITERATIONS = ACE_DEFAULT_MAX_TIMERS;
+
+// Keep track of the timer ids that were assigned to us.
+static int timer_ids[MAX_ITERATIONS];
class Example_Handler : public ACE_Event_Handler
{
@@ -42,29 +47,29 @@ test_functionality (ACE_Timer_Queue *tq)
{
Example_Handler eh;
- ACE_ASSERT (tq.is_empty ());
+ ACE_ASSERT (tq->is_empty ());
ACE_ASSERT (ACE_Time_Value::zero == ACE_Time_Value (0));
int timer_id;
- timer_id = tq.schedule (&eh, (const void *) 1, ACE_OS::gettimeofday ());
+ timer_id = tq->schedule (&eh, (const void *) 1, ACE_OS::gettimeofday ());
ACE_ASSERT (timer_id != -1);
- ACE_ASSERT (tq.schedule (&eh, (const void *) 42,
+ ACE_ASSERT (tq->schedule (&eh, (const void *) 42,
ACE_OS::gettimeofday ()) != -1);
- ACE_ASSERT (tq.schedule (&eh, (const void *) 42,
+ 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->cancel (timer_id) == 1);
+ ACE_ASSERT (!tq->is_empty ());
- ACE_ASSERT (tq.expire (ACE_OS::gettimeofday () == 1));
+ ACE_ASSERT (tq->expire () == 2);
- ACE_ASSERT (tq.schedule (&eh, (const void *) 4, ACE_OS::gettimeofday
+ ACE_ASSERT (tq->schedule (&eh, (const void *) 4, ACE_OS::gettimeofday
()) != -1);
- ACE_ASSERT (tq.schedule (&eh, (const void *) 5, ACE_OS::gettimeofday
+ ACE_ASSERT (tq->schedule (&eh, (const void *) 5, ACE_OS::gettimeofday
()) != -1);
- ACE_ASSERT (tq.cancel (&eh) == 2);
- ACE_ASSERT (tq.is_empty ());
- ACE_ASSERT (tq.expire (ACE_OS::gettimeofday ()) == 0);
+ ACE_ASSERT (tq->cancel (&eh) == 2);
+ ACE_ASSERT (tq->is_empty ());
+ ACE_ASSERT (tq->expire () == 0);
}
static void
@@ -78,11 +83,19 @@ test_performance (ACE_Timer_Queue *tq,
ACE_ASSERT (tq->is_empty ());
ACE_ASSERT (ACE_Time_Value::zero == ACE_Time_Value (0));
+ // Test the amount of time required to schedule all the timers.
+
timer.start ();
- // Test the amount of time required to schedule all the timers.
for (i = 0; i < MAX_ITERATIONS; i++)
- tq->schedule (&eh, (const void *) 42, ACE_OS::gettimeofday ());
+ {
+ timer_ids[i] = tq->schedule (&eh, (const void *) 42, ACE_OS::gettimeofday ());
+ ACE_ASSERT (timer_ids[i] != -1);
+ }
+
+ ACE_ASSERT (!tq->is_empty ());
+
+ timer.stop ();
ACE_Profile_Timer::ACE_Elapsed_Time et;
@@ -95,21 +108,19 @@ test_performance (ACE_Timer_Queue *tq,
ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n",
(et.real_time / double (MAX_ITERATIONS)) * 1000000));
- timer.start ();
-
- int timer_id = tq->schedule (&eh, (const void *) 42,
- ACE_OS::gettimeofday ());
+ // Test the amount of time required to cancel all the timers. We
+ // start from the "back" in order to measure the worst case
+ // performance for the <ACE_Timer_List> (which uses linear search).
- ACE_ASSERT (timer_id);
+ timer.start ();
- // Test the amount of time required to cancel all the timers (this
- // takes advantage of the fact that <timer_ids> are always allocated
- // contiguously starting at 0.
- for (i = 0; i < MAX_ITERATIONS + 1; i++)
- tq->cancel (timer_id--);
+ for (i = MAX_ITERATIONS - 1; i >= 0; i--)
+ tq->cancel (timer_ids[i]);
ACE_ASSERT (tq->is_empty ());
+ timer.stop ();
+
timer.elapsed_time (et);
ACE_DEBUG ((LM_DEBUG, "time to cancel %d timers for %s\n",
@@ -119,6 +130,29 @@ test_performance (ACE_Timer_Queue *tq,
ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n",
(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++)
+ ACE_ASSERT (tq->schedule (&eh, (const void *) 42, ACE_OS::gettimeofday ()) != -1);
+
+ ACE_ASSERT (!tq->is_empty ());
+
+ // Expire all the timers.
+ tq->expire ();
+
+ timer.stop ();
+
+ timer.elapsed_time (et);
+
+ ACE_DEBUG ((LM_DEBUG, "time to schedule and expire %d timers for %s\n",
+ 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));
}
struct Timer_Queues
@@ -133,9 +167,9 @@ struct Timer_Queues
static Timer_Queues timer_queues[] =
{
{ new ACE_Timer_List, "ACE_Timer_List" },
- { new ACE_Timer_Heap, "ACE_Timer_Queue" },
- { 0, 0 };
-}
+ { new ACE_Timer_Heap, "ACE_Timer_Heap" },
+ { 0, 0 },
+};
int
main (int, char *[])
@@ -145,7 +179,7 @@ main (int, char *[])
for (int i = 0; timer_queues[i].name_ != 0; i++)
{
test_performance (timer_queues[i].queue_, timer_queues[i].name_);
- test_functionality (timer_queues[i].queue_, timer_queues[i].name_);
+ test_functionality (timer_queues[i].queue_);
delete timer_queues[i].queue_;
}