//$$CDS-header$$
-#ifndef __CDS_INTRUSIVE_OPTIMISTIC_QUEUE_H
-#define __CDS_INTRUSIVE_OPTIMISTIC_QUEUE_H
+#ifndef CDSLIB_INTRUSIVE_OPTIMISTIC_QUEUE_H
+#define CDSLIB_INTRUSIVE_OPTIMISTIC_QUEUE_H
#include <type_traits>
#include <cds/intrusive/details/base.h>
-#include <cds/cxx11_atomic.h>
+#include <cds/algo/atomic.h>
#include <cds/gc/default_gc.h>
namespace cds { namespace intrusive {
{
assert( pNode->m_pNext.load( atomics::memory_order_relaxed ) == nullptr );
assert( pNode->m_pPrev.load( atomics::memory_order_relaxed ) == nullptr );
+ CDS_UNUSED( pNode );
}
};
{
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; }
void onBadTail() { ++m_BadTail; }
/// Register fix list event
void onFixList() { ++m_FixListCount; }
+ /// Register dequeuing from empty queue
+ void onEmptyDequeue() { ++m_EmptyDequeue; }
//@cond
void reset()
m_AdvanceTailError.reset();
m_BadTail.reset();
m_FixListCount.reset();
+ m_EmptyDequeue.reset();
}
stat& operator +=( stat const& s )
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
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& )
fix_list( pTail, pHead );
continue;
}
- if ( m_pHead.compare_exchange_weak( pHead, pFirstNodePrev, memory_model::memory_order_release, atomics::memory_order_relaxed )) {
+ if ( m_pHead.compare_exchange_weak( pHead, pFirstNodePrev, memory_model::memory_order_acquire, atomics::memory_order_relaxed )) {
// dequeue success
break;
}
}
else {
// the queue is empty
+ m_Stat.onEmptyDequeue();
return false;
}
}
}} // namespace cds::intrusive
-#endif // #ifndef __CDS_INTRUSIVE_OPTIMISTIC_QUEUE_H
+#endif // #ifndef CDSLIB_INTRUSIVE_OPTIMISTIC_QUEUE_H