core: Make reference counting thread-safe
This commit is contained in:
@@ -229,6 +229,7 @@ set(header_files
|
|||||||
model/ascii-file.h
|
model/ascii-file.h
|
||||||
model/ascii-test.h
|
model/ascii-test.h
|
||||||
model/assert.h
|
model/assert.h
|
||||||
|
model/atomic-counter.h
|
||||||
model/attribute-accessor-helper.h
|
model/attribute-accessor-helper.h
|
||||||
model/attribute-construction-list.h
|
model/attribute-construction-list.h
|
||||||
model/attribute-container-accessor-helper.h
|
model/attribute-container-accessor-helper.h
|
||||||
|
|||||||
49
src/core/model/atomic-counter.h
Normal file
49
src/core/model/atomic-counter.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||||
|
#ifndef ATOMIC_COUNTER_H
|
||||||
|
#define ATOMIC_COUNTER_H
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace ns3 {
|
||||||
|
|
||||||
|
class AtomicCounter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline AtomicCounter ()
|
||||||
|
{
|
||||||
|
m_count.store (0, std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline AtomicCounter (uint32_t count)
|
||||||
|
{
|
||||||
|
m_count.store (count, std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator uint32_t () const
|
||||||
|
{
|
||||||
|
return m_count.load (std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t operator = (const uint32_t count)
|
||||||
|
{
|
||||||
|
m_count.store (count, std::memory_order_release);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t operator++ (int)
|
||||||
|
{
|
||||||
|
return m_count.fetch_add (1, std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t operator-- (int)
|
||||||
|
{
|
||||||
|
return m_count.fetch_sub (1, std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic<uint32_t> m_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ns3
|
||||||
|
|
||||||
|
#endif /* ATOMIC_COUNTER_H */
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
#ifndef SIMPLE_REF_COUNT_H
|
#ifndef SIMPLE_REF_COUNT_H
|
||||||
#define SIMPLE_REF_COUNT_H
|
#define SIMPLE_REF_COUNT_H
|
||||||
|
|
||||||
|
#include "atomic-counter.h"
|
||||||
#include "empty.h"
|
#include "empty.h"
|
||||||
#include "default-deleter.h"
|
#include "default-deleter.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
@@ -112,9 +113,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline void Unref (void) const
|
inline void Unref (void) const
|
||||||
{
|
{
|
||||||
m_count--;
|
if (m_count-- == 1)
|
||||||
if (m_count == 0)
|
|
||||||
{
|
{
|
||||||
|
#ifdef NS3_MTP
|
||||||
|
std::atomic_thread_fence (std::memory_order_acquire);
|
||||||
|
#endif
|
||||||
DELETER::Delete (static_cast<T*> (const_cast<SimpleRefCount *> (this)));
|
DELETER::Delete (static_cast<T*> (const_cast<SimpleRefCount *> (this)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,7 +141,11 @@ private:
|
|||||||
* Note we make this mutable so that the const methods can still
|
* Note we make this mutable so that the const methods can still
|
||||||
* change it.
|
* change it.
|
||||||
*/
|
*/
|
||||||
|
#ifdef NS3_MTP
|
||||||
|
mutable AtomicCounter m_count;
|
||||||
|
#else
|
||||||
mutable uint32_t m_count;
|
mutable uint32_t m_count;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ns3
|
} // namespace ns3
|
||||||
|
|||||||
Reference in New Issue
Block a user