From: khizmax Date: Sat, 17 Jan 2015 10:44:08 +0000 (+0300) Subject: added "pop from empty queue" counter to queue statistics X-Git-Tag: v2.1.0~305^2~101^2~2 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=libcds.git;a=commitdiff_plain;h=ef31ba8d26d9ee421e635c9bb5c4504f56b64a6c added "pop from empty queue" counter to queue statistics --- diff --git a/cds/intrusive/basket_queue.h b/cds/intrusive/basket_queue.h index bdcf27a3..da402502 100644 --- a/cds/intrusive/basket_queue.h +++ b/cds/intrusive/basket_queue.h @@ -122,23 +122,27 @@ namespace cds { namespace intrusive { counter_type m_BadTail; ///< Count of events "Tail is not pointed to the last item in the queue" counter_type m_TryAddBasket; ///< Count of attemps adding new item to a basket (only or BasketQueue, for other queue this metric is not used) counter_type m_AddBasketCount; ///< Count of events "Enqueue a new item into basket" (only or BasketQueue, for other queue this metric is not used) + counter_type m_EmptyDequeue; ///< Count of dequeue from empty queue /// Register enqueue call - void onEnqueue() { ++m_EnqueueCount; } + void onEnqueue() { ++m_EnqueueCount; } /// Register dequeue call - void onDequeue() { ++m_DequeueCount; } + void onDequeue() { ++m_DequeueCount; } /// Register enqueue race event - void onEnqueueRace() { ++m_EnqueueRace; } + void onEnqueueRace() { ++m_EnqueueRace; } /// Register dequeue race event - void onDequeueRace() { ++m_DequeueRace; } + void onDequeueRace() { ++m_DequeueRace; } /// Register "advance tail failed" event - void onAdvanceTailFailed() { ++m_AdvanceTailError; } + void onAdvanceTailFailed() { ++m_AdvanceTailError; } /// Register event "Tail is not pointed to last item in the queue" - void onBadTail() { ++m_BadTail; } + void onBadTail() { ++m_BadTail; } /// Register an attempt t add new item to basket void onTryAddBasket() { ++m_TryAddBasket; } /// Register event "Enqueue a new item into basket" (only or BasketQueue, for other queue this metric is not used) void onAddBasket() { ++m_AddBasketCount; } + /// Register dequeuing from empty queue + void onEmptyDequeue() { ++m_EmptyDequeue; } + //@cond void reset() @@ -151,6 +155,7 @@ namespace cds { namespace intrusive { m_BadTail.reset(); m_TryAddBasket.reset(); m_AddBasketCount.reset(); + m_EmptyDequeue.reset(); } stat& operator +=( stat const& s ) @@ -163,6 +168,7 @@ namespace cds { namespace intrusive { m_BadTail += s.m_BadTail.get(); m_TryAddBasket += s.m_TryAddBasket.get(); m_AddBasketCount += s.m_AddBasketCount.get(); + m_EmptyDequeue += s.m_EmptyDequeue.get(); return *this; } //@endcond @@ -172,14 +178,15 @@ namespace cds { namespace intrusive { struct empty_stat { //@cond - void onEnqueue() {} - void onDequeue() {} - void onEnqueueRace() {} - void onDequeueRace() {} - void onAdvanceTailFailed() {} - void onBadTail() {} - void onTryAddBasket() {} - void onAddBasket() {} + void onEnqueue() const {} + void onDequeue() const {} + void onEnqueueRace() const {} + void onDequeueRace() const {} + void onAdvanceTailFailed() const {} + void onBadTail() const {} + void onTryAddBasket() const {} + void onAddBasket() const {} + void onEmptyDequeue() const {} void reset() {} empty_stat& operator +=( empty_stat const& ) @@ -494,8 +501,10 @@ namespace cds { namespace intrusive { if ( h == m_pHead.load( memory_model::memory_order_acquire ) ) { if ( h.ptr() == t.ptr() ) { - if ( !pNext.ptr() ) + if ( !pNext.ptr() ) { + m_Stat.onEmptyDequeue(); return false; + } { typename gc::Guard g; diff --git a/cds/intrusive/moir_queue.h b/cds/intrusive/moir_queue.h index 0d2d62a8..0f0607df 100644 --- a/cds/intrusive/moir_queue.h +++ b/cds/intrusive/moir_queue.h @@ -117,8 +117,10 @@ namespace cds { namespace intrusive { h = res.guards.protect( 0, base_class::m_pHead, node_to_value() ); pNext = res.guards.protect( 1, h->m_pNext, node_to_value() ); - if ( pNext == nullptr ) - return false ; // queue is empty + if ( pNext == nullptr ) { + base_class::m_Stat.onEmptyDequeue(); + return false; // queue is empty + } if ( base_class::m_pHead.compare_exchange_strong( h, pNext, memory_model::memory_order_release, atomics::memory_order_relaxed )) { node_type * t = base_class::m_pTail.load(memory_model::memory_order_acquire); diff --git a/cds/intrusive/msqueue.h b/cds/intrusive/msqueue.h index 2fad6f96..7a636391 100644 --- a/cds/intrusive/msqueue.h +++ b/cds/intrusive/msqueue.h @@ -75,6 +75,7 @@ namespace cds { namespace intrusive { counter_type m_DequeueRace ; ///< Count of dequeue race conditions encountered counter_type m_AdvanceTailError ; ///< Count of "advance tail failed" events counter_type m_BadTail ; ///< Count of events "Tail is not pointed to the last item in the queue" + counter_type m_EmptyDequeue ; ///< Count of dequeue from empty queue /// Register enqueue call void onEnqueue() { ++m_EnqueueCount; } @@ -88,6 +89,8 @@ namespace cds { namespace intrusive { void onAdvanceTailFailed() { ++m_AdvanceTailError; } /// Register event "Tail is not pointed to last item in the queue" void onBadTail() { ++m_BadTail; } + /// Register dequeuing from empty queue + void onEmptyDequeue() { ++m_EmptyDequeue; } //@cond void reset() @@ -98,6 +101,7 @@ namespace cds { namespace intrusive { m_DequeueRace.reset(); m_AdvanceTailError.reset(); m_BadTail.reset(); + m_EmptyDequeue.reset(); } stat& operator +=( stat const& s ) @@ -108,6 +112,7 @@ namespace cds { namespace intrusive { m_DequeueRace += s.m_DequeueRace.get(); m_AdvanceTailError += s.m_AdvanceTailError.get(); m_BadTail += s.m_BadTail.get(); + m_EmptyDequeue += s.m_EmptyDequeue.get(); return *this; } @@ -118,12 +123,13 @@ namespace cds { namespace intrusive { struct empty_stat { //@cond - void onEnqueue() {} - void onDequeue() {} - void onEnqueueRace() {} - void onDequeueRace() {} - void onAdvanceTailFailed() {} - void onBadTail() {} + void onEnqueue() const {} + void onDequeue() const {} + void onEnqueueRace() const {} + void onDequeueRace() const {} + void onAdvanceTailFailed() const {} + void onBadTail() const {} + void onEmptyDequeue() const {} void reset() {} empty_stat& operator +=( empty_stat const& ) @@ -371,8 +377,10 @@ namespace cds { namespace intrusive { if ( m_pHead.load(memory_model::memory_order_acquire) != h ) continue; - if ( pNext == nullptr ) - return false ; // empty queue + if ( pNext == nullptr ) { + m_Stat.onEmptyDequeue(); + return false; // empty queue + } node_type * t = m_pTail.load(memory_model::memory_order_acquire); if ( h == t ) { diff --git a/cds/intrusive/optimistic_queue.h b/cds/intrusive/optimistic_queue.h index f2b42543..43f676c8 100644 --- a/cds/intrusive/optimistic_queue.h +++ b/cds/intrusive/optimistic_queue.h @@ -159,13 +159,14 @@ namespace cds { namespace intrusive { { typedef Counter counter_type; ///< Counter type - counter_type m_EnqueueCount; ///< Enqueue call count - counter_type m_DequeueCount; ///< Dequeue call count - counter_type m_EnqueueRace; ///< Count of enqueue race conditions encountered - counter_type m_DequeueRace; ///< Count of dequeue race conditions encountered - counter_type m_AdvanceTailError; ///< Count of "advance tail failed" events - counter_type m_BadTail; ///< Count of events "Tail is not pointed to the last item in the queue" - counter_type m_FixListCount; ///< Count of fix list event + counter_type m_EnqueueCount; ///< Enqueue call count + counter_type m_DequeueCount; ///< Dequeue call count + counter_type m_EnqueueRace; ///< Count of enqueue race conditions encountered + counter_type m_DequeueRace; ///< Count of dequeue race conditions encountered + counter_type m_AdvanceTailError; ///< Count of "advance tail failed" events + counter_type m_BadTail; ///< Count of events "Tail is not pointed to the last item in the queue" + counter_type m_FixListCount; ///< Count of fix list event + counter_type m_EmptyDequeue; ///< Count of dequeue from empty queue /// Register enqueue call void onEnqueue() { ++m_EnqueueCount; } @@ -181,6 +182,8 @@ namespace cds { namespace intrusive { void onBadTail() { ++m_BadTail; } /// Register fix list event void onFixList() { ++m_FixListCount; } + /// Register dequeuing from empty queue + void onEmptyDequeue() { ++m_EmptyDequeue; } //@cond void reset() @@ -192,6 +195,7 @@ namespace cds { namespace intrusive { m_AdvanceTailError.reset(); m_BadTail.reset(); m_FixListCount.reset(); + m_EmptyDequeue.reset(); } stat& operator +=( stat const& s ) @@ -203,6 +207,8 @@ namespace cds { namespace intrusive { m_AdvanceTailError += s.m_AdvanceTailError.get(); m_BadTail += s.m_BadTail.get(); m_FixListCount += s.m_FixListCount.get(); + m_EmptyDequeue += s.m_EmptyDequeue.get(); + return *this; } //@endcond @@ -212,13 +218,14 @@ namespace cds { namespace intrusive { struct empty_stat { //@cond - void onEnqueue() {} - void onDequeue() {} - void onEnqueueRace() {} - void onDequeueRace() {} - void onAdvanceTailFailed() {} - void onBadTail() {} - void onFixList() {} + void onEnqueue() const {} + void onDequeue() const {} + void onEnqueueRace() const {} + void onDequeueRace() const {} + void onAdvanceTailFailed() const {} + void onBadTail() const {} + void onFixList() const {} + void onEmptyDequeue() const {} void reset() {} empty_stat& operator +=( empty_stat const& ) @@ -473,6 +480,7 @@ namespace cds { namespace intrusive { } else { // the queue is empty + m_Stat.onEmptyDequeue(); return false; } } diff --git a/tests/unit/queue/queue_type.h b/tests/unit/queue/queue_type.h index 818e05fe..a1a58ec9 100644 --- a/tests/unit/queue/queue_type.h +++ b/tests/unit/queue/queue_type.h @@ -511,24 +511,6 @@ namespace queue { // ********************************************* // Queue statistics namespace std { - /* - template - static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_stat const& s) - { - return o - << "\tStatistics:\n" - << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n" - << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n" - << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n" - << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n" - << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n" - << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"; - } - static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_dummy_stat const& s) - { - return o; - } - */ template static inline std::ostream& operator <<(std::ostream& o, cds::container::basket_queue::stat const& s) @@ -538,6 +520,7 @@ namespace std { << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n" << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n" << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n" + << "\t\t Dequeue empty: " << s.m_EmptyDequeue.get() << "\n" << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n" << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n" << "\t\t Bad tail: " << s.m_BadTail.get() << "\n" @@ -557,6 +540,7 @@ namespace std { << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n" << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n" << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n" + << "\t\t Dequeue empty: " << s.m_EmptyDequeue.get() << "\n" << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n" << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n" << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"; @@ -581,6 +565,7 @@ namespace std { << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n" << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n" << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n" + << "\t\t Dequeue empty: " << s.m_EmptyDequeue.get() << "\n" << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n" << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n" << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"