diff --git a/src/simulator/event-collector.cc b/src/simulator/event-collector.cc new file mode 100644 index 000000000..54ee69a86 --- /dev/null +++ b/src/simulator/event-collector.cc @@ -0,0 +1,120 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Gustavo J. A. M. Carneiro + */ +#include "event-collector.h" +#include + +namespace ns3 { + +inline bool +EventExpiredPredicate (const EventId &event) +{ + return event.IsExpired (); +} + +// Called when a new event was added and the cleanup limit was exceeded in consequence. +void +EventCollector::Cleanup () +{ + m_events.remove_if (EventExpiredPredicate); + + // If after cleanup we are still over the limit, increase the limit. + if (m_events.size () >= m_nextCleanupSize) + m_nextCleanupSize = std::min (std::list::size_type (CLEANUP_CHUNK_MAX_SIZE), + m_nextCleanupSize<<1); +} + + +EventCollector::~EventCollector () +{ + for (std::list::iterator event = m_events.begin (); + event != m_events.end (); event++) + { + Simulator::Cancel (*event); + } +} + +}; // namespace ns3 + + + +#ifdef RUN_SELF_TESTS + +#include "ns3/test.h" + +namespace ns3 { + +class EventCollectorTests : public Test +{ + int m_counter; + EventCollector *m_events; + + void EventCollectorCallback (); + +public: + + EventCollectorTests (); + virtual ~EventCollectorTests (); + virtual bool RunTests (void); +}; + +EventCollectorTests::EventCollectorTests () + : Test ("EventCollector"), m_counter (0), m_events (0) +{} + +EventCollectorTests::~EventCollectorTests () +{} + +void +EventCollectorTests::EventCollectorCallback () +{ + m_counter++; + if (m_counter == 50) + { + // this should cause the remaining (50) events to be cancelled + delete m_events; + m_events = 0; + } +} + +bool EventCollectorTests::RunTests (void) +{ + bool result = true; + + m_events = new EventCollector (); + + for (int n = 0; n < 100; n++) + { + m_events->Track (Simulator::Schedule + (Simulator::Now (), + &EventCollectorTests::EventCollectorCallback, + this)); + } + Simulator::Run (); + NS_TEST_ASSERT_EQUAL (m_events, 0); + NS_TEST_ASSERT_EQUAL (m_counter, 50); + return result; +} + +static EventCollectorTests g_eventCollectorTests; + +}; + +#endif /* RUN_SELF_TESTS */ diff --git a/src/simulator/event-collector.h b/src/simulator/event-collector.h new file mode 100644 index 000000000..7e2c78e65 --- /dev/null +++ b/src/simulator/event-collector.h @@ -0,0 +1,68 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INESC Porto + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Gustavo J. A. M. Carneiro + */ +#ifndef EVENT_COLLECTOR_H +#define EVENT_COLLECTOR_H + +#include +#include "event-id.h" +#include "simulator.h" + +namespace ns3 { + +/** + * \brief An object that tracks scheduled events and automatically + * cancels them when it is destroyed. + */ +class EventCollector +{ +public: + + EventCollector () : + m_nextCleanupSize (CLEANUP_CHUNK_MIN_SIZE) + {} + + /** + * \brief Tracks a new event + */ + void Track (EventId event) + { + m_events.push_back (event); + if (m_events.size () >= m_nextCleanupSize) + Cleanup (); + } + + ~EventCollector (); + +private: + enum { + CLEANUP_CHUNK_MIN_SIZE = 8, + CLEANUP_CHUNK_MAX_SIZE = 1024 + }; + + std::list::size_type m_nextCleanupSize; + std::list m_events; + + void Cleanup (); +}; + +}; // namespace ns3 + +#endif /* EVENT_COLLECTOR_H */ diff --git a/src/simulator/wscript b/src/simulator/wscript index f043d65b6..208828bf3 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -57,6 +57,7 @@ def build(bld): 'time.cc', 'timer.cc', 'event-id.cc', + 'event-collector.cc', 'scheduler.cc', 'scheduler-factory.cc', 'scheduler-list.cc', @@ -74,6 +75,7 @@ def build(bld): 'nstime.h', 'timer.h', 'event-id.h', + 'event-collector.h', 'event-impl.h', 'simulator.h', 'scheduler.h',