From: tho Date: Wed, 19 Oct 2011 08:15:09 +0000 (+0000) Subject: PPI: optimized internal connector packet handling (queuing only if necessary, pass... X-Git-Url: http://g0dil.de/git?p=senf.git;a=commitdiff_plain;h=69c137120ce26b83cf37b125c5c54e1eb61f39a3 PPI: optimized internal connector packet handling (queuing only if necessary, pass by reference) git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1815 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/PPI/AnnotationRouter.ct b/senf/PPI/AnnotationRouter.ct index 2b3fade..8cc6ea1 100644 --- a/senf/PPI/AnnotationRouter.ct +++ b/senf/PPI/AnnotationRouter.ct @@ -56,7 +56,7 @@ connectorSetup(connector::ActiveOutput<> & conn, AnnotationType const & key) template prefix_ void senf::ppi::module::AnnotationRouter::request() { - Packet p (input()); + Packet const & p (input()); typename AnnotationRouter::ContainerType::iterator i ( this->connectors().find(p.annotation())); if (i == this->connectors().end()) diff --git a/senf/PPI/Connectors.cc b/senf/PPI/Connectors.cc index 90c593c..7290e01 100644 --- a/senf/PPI/Connectors.cc +++ b/senf/PPI/Connectors.cc @@ -364,19 +364,28 @@ prefix_ void senf::ppi::connector::ActiveConnector::unregisterRoute(ForwardingRo //-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::InputConnector -prefix_ senf::Packet senf::ppi::connector::InputConnector::operator()() +prefix_ senf::Packet const & senf::ppi::connector::InputConnector::operator()() { + static Packet nullPacket; + if (empty()) v_requestEvent(); - if (! empty()) { - Packet p ( queue_.back()); + if (fastPacket_) { + Packet const * p = fastPacket_; + fastPacket_ = NULL; + v_dequeueEvent(); + SENF_PPI_TRACE(*p, "IN "); + return *p; + } + if (! queue_.empty()) { + slowPacket_ = queue_.back(); queue_.pop_back(); v_dequeueEvent(); - SENF_PPI_TRACE(p, "IN "); - return p; + SENF_PPI_TRACE(slowPacket_, "IN "); + return slowPacket_; } else { - SENF_PPI_TRACE(Packet(), "IN "); - return Packet(); + SENF_PPI_TRACE(nullPacket, "IN "); + return nullPacket; } } diff --git a/senf/PPI/Connectors.cci b/senf/PPI/Connectors.cci index b6407fb..957f15c 100644 --- a/senf/PPI/Connectors.cci +++ b/senf/PPI/Connectors.cci @@ -213,7 +213,7 @@ prefix_ senf::ppi::connector::ActiveConnector::ActiveConnector() //-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::InputConnector -prefix_ senf::Packet senf::ppi::connector::InputConnector::read() +prefix_ senf::Packet const & senf::ppi::connector::InputConnector::read() { return operator()(); } @@ -225,46 +225,24 @@ prefix_ senf::ppi::connector::OutputConnector & senf::ppi::connector::InputConne return *peer_; } -prefix_ senf::ppi::connector::InputConnector::queue_iterator -senf::ppi::connector::InputConnector::begin() - const -{ - return queue_.begin(); -} - -prefix_ senf::ppi::connector::InputConnector::queue_iterator -senf::ppi::connector::InputConnector::end() - const -{ - return queue_.end(); -} - -prefix_ senf::Packet senf::ppi::connector::InputConnector::peek() - const -{ - // Cannot peek() head of empty queue - SENF_ASSERT( ! queue_.empty(), - "senf::ppi::connector::InputConnector: cannot call peek() on empty queue" ); - return queue_.back(); -} - prefix_ senf::ppi::connector::InputConnector::size_type senf::ppi::connector::InputConnector::queueSize() const { - return queue_.size(); + return queue_.size() + (fastPacket_ ? 1 : 0); } prefix_ bool senf::ppi::connector::InputConnector::empty() const { - return queue_.empty(); + return fastPacket_ == NULL && queue_.empty(); } //-///////////////////////////////////////////////////////////////////////////////////////////////// // protected members prefix_ senf::ppi::connector::InputConnector::InputConnector() + : fastPacket_(NULL) {} //-///////////////////////////////////////////////////////////////////////////////////////////////// @@ -272,8 +250,22 @@ prefix_ senf::ppi::connector::InputConnector::InputConnector() prefix_ void senf::ppi::connector::InputConnector::enqueue(Packet const & p) { - queue_.push_front(p); - v_enqueueEvent(); + if (queue_.empty()) { + fastPacket_ = &p; + try { + v_enqueueEvent(); + } catch (Exception & e) { + queue_.push_front(p); + throw e; + } + if (fastPacket_) { + queue_.push_front(p); + fastPacket_ = NULL; + } + } else { + queue_.push_front(p); + v_enqueueEvent(); + } } //-///////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/senf/PPI/Connectors.cti b/senf/PPI/Connectors.cti index 225f8e2..82d7bd9 100644 --- a/senf/PPI/Connectors.cti +++ b/senf/PPI/Connectors.cti @@ -42,7 +42,7 @@ template prefix_ typename senf::ppi::connector::detail::TypedInputMixin::Type senf::ppi::connector::detail::TypedInputMixin::operator()() { - Packet p (static_cast(this)->InputConnector::operator()()); + Packet const & p (static_cast(this)->InputConnector::operator()()); return p ? p.as() : Type(); } @@ -57,13 +57,13 @@ senf::ppi::connector::detail::TypedInputMixin::read() // senf::ppi::connector::detail::TypedOutputMixin template -prefix_ void senf::ppi::connector::detail::TypedOutputMixin::operator()(Type p) +prefix_ void senf::ppi::connector::detail::TypedOutputMixin::operator()(Type const & p) { static_cast(this)->OutputConnector::operator()(p); } template -prefix_ void senf::ppi::connector::detail::TypedOutputMixin::write(Type p) +prefix_ void senf::ppi::connector::detail::TypedOutputMixin::write(Type const & p) { static_cast(this)->OutputConnector::write(p); } diff --git a/senf/PPI/Connectors.hh b/senf/PPI/Connectors.hh index ff44b48..bbe8eb5 100644 --- a/senf/PPI/Connectors.hh +++ b/senf/PPI/Connectors.hh @@ -399,7 +399,7 @@ namespace connector { typedef Queue::size_type size_type; ///< Unsigned type for counting queue elements - Packet operator()(); ///< Get a packet + Packet const & operator()(); ///< Get a packet /**< This member is the primary method to access received data. On passive connectors, this operator will just dequeue a packet from the packet queue. If the @@ -408,14 +408,10 @@ namespace connector { request cannot be fulfilled an in-valid Packet is returned. */ - Packet read(); ///< Alias for operator()() + Packet const & read(); ///< Alias for operator()() OutputConnector & peer() const; - queue_iterator begin() const; ///< Access queue begin (head) - queue_iterator end() const; ///< Access queue past-the-end (tail) - Packet peek() const; ///< Return head element from the queue - size_type queueSize() const; ///< Return number of elements in the queue bool empty() const; ///< Return queueSize() == 0 @@ -434,6 +430,8 @@ namespace connector { OutputConnector * peer_; Queue queue_; + Packet const * fastPacket_; + Packet slowPacket_; friend class OutputConnector; }; diff --git a/senf/PPI/Connectors.ih b/senf/PPI/Connectors.ih index b8d1597..82873b1 100644 --- a/senf/PPI/Connectors.ih +++ b/senf/PPI/Connectors.ih @@ -56,8 +56,8 @@ namespace detail { public: typedef PacketType Type; - void operator()(Type p); - void write(Type p); + void operator()(Type const & p); + void write(Type const & p); }; }}}} diff --git a/senf/PPI/Connectors.test.cc b/senf/PPI/Connectors.test.cc index 1e82306..eae2acd 100644 --- a/senf/PPI/Connectors.test.cc +++ b/senf/PPI/Connectors.test.cc @@ -142,7 +142,6 @@ SENF_AUTO_UNIT_TEST(inputConnector) BOOST_CHECK_EQUAL ( & target.input.peer(), & source.output ); - BOOST_CHECK( target.input.begin() == target.input.end() ); BOOST_CHECK_EQUAL( target.input.queueSize(), 0u ); BOOST_CHECK( target.input.empty() ); } diff --git a/senf/PPI/ThrottleBarrier.cc b/senf/PPI/ThrottleBarrier.cc index 8bbc23d..4a79660 100644 --- a/senf/PPI/ThrottleBarrier.cc +++ b/senf/PPI/ThrottleBarrier.cc @@ -45,7 +45,7 @@ prefix_ senf::ppi::module::ThrottleBarrier::ThrottleBarrier() prefix_ void senf::ppi::module::ThrottleBarrier::request() { - Packet p (input()); + Packet const & p (input()); if (output) output(p); } diff --git a/site_scons/SparseTestHack.py b/site_scons/SparseTestHack.py index 025bb6b..7242786 100644 --- a/site_scons/SparseTestHack.py +++ b/site_scons/SparseTestHack.py @@ -80,6 +80,8 @@ def setup(env): env['BUILDERS']['RealBoostUnitTest'] = env['BUILDERS']['BoostUnitTest'] env['BUILDERS']['BoostUnitTest'] = AutoObjectBoostUnitTest env['_UNIT_TEST_LIST'] = [] + env.Append(EXTRA_LIBS = [ '$BOOSTREGEXLIB', '$BOOSTSIGNALSLIB', + '$BOOSTFSLIB', '$BOOSTSYSTEMLIB' ]) # This needs to be called after all build targets have been set # up. This is important since the list of object targets needs to be