From 5110ade9ed8f6dc8e87afd9631ed73d35cfce4d7 Mon Sep 17 00:00:00 2001 From: F5 Date: Tue, 25 Oct 2022 17:08:33 +0800 Subject: [PATCH] network: Make packets thread-safe --- src/network/model/buffer.cc | 15 +++++++-------- src/network/model/buffer.h | 7 +++++++ src/network/model/byte-tag-list.cc | 14 ++++++++++++-- src/network/model/packet-metadata.cc | 10 ++++++++-- src/network/model/packet-metadata.h | 11 +++++++---- src/network/model/packet-tag-list.h | 11 +++++++++-- 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/network/model/buffer.cc b/src/network/model/buffer.cc index f5698cfd9..ecfe98e39 100644 --- a/src/network/model/buffer.cc +++ b/src/network/model/buffer.cc @@ -148,6 +148,9 @@ Buffer::Recycle (struct Buffer::Data *data) { NS_LOG_FUNCTION (data); NS_ASSERT (data->m_count == 0); +#ifdef NS3_MTP + std::atomic_thread_fence (std::memory_order_acquire); +#endif Deallocate (data); } @@ -262,8 +265,7 @@ Buffer::operator = (Buffer const&o) if (m_data != o.m_data) { // not assignment to self. - m_data->m_count--; - if (m_data->m_count == 0) + if (m_data->m_count-- == 1) { Recycle (m_data); } @@ -285,8 +287,7 @@ Buffer::~Buffer () NS_LOG_FUNCTION (this); NS_ASSERT (CheckInternalState ()); g_recommendedStart = std::max (g_recommendedStart, m_maxZeroAreaStart); - m_data->m_count--; - if (m_data->m_count == 0) + if (m_data->m_count-- == 1) { Recycle (m_data); } @@ -328,8 +329,7 @@ Buffer::AddAtStart (uint32_t start) uint32_t newSize = GetInternalSize () + start; struct Buffer::Data *newData = Buffer::Create (newSize); memcpy (newData->m_data + start, m_data->m_data + m_start, GetInternalSize ()); - m_data->m_count--; - if (m_data->m_count == 0) + if (m_data->m_count-- == 1) { Buffer::Recycle (m_data); } @@ -373,8 +373,7 @@ Buffer::AddAtEnd (uint32_t end) uint32_t newSize = GetInternalSize () + end; struct Buffer::Data *newData = Buffer::Create (newSize); memcpy (newData->m_data, m_data->m_data + m_start, GetInternalSize ()); - m_data->m_count--; - if (m_data->m_count == 0) + if (m_data->m_count-- == 1) { Buffer::Recycle (m_data); } diff --git a/src/network/model/buffer.h b/src/network/model/buffer.h index 1ce67ff5f..04322308e 100644 --- a/src/network/model/buffer.h +++ b/src/network/model/buffer.h @@ -23,9 +23,12 @@ #include #include #include +#include "ns3/atomic-counter.h" #include "ns3/assert.h" +#ifndef NS3_MTP #define BUFFER_FREE_LIST 1 +#endif namespace ns3 { @@ -663,7 +666,11 @@ private: * The reference count of an instance of this data structure. * Each buffer which references an instance holds a count. */ +#ifdef NS3_MTP + AtomicCounter m_count; +#else uint32_t m_count; +#endif /** * the size of the m_data field below. */ diff --git a/src/network/model/byte-tag-list.cc b/src/network/model/byte-tag-list.cc index a9822a15c..cbf368999 100644 --- a/src/network/model/byte-tag-list.cc +++ b/src/network/model/byte-tag-list.cc @@ -19,11 +19,15 @@ */ #include "byte-tag-list.h" #include "ns3/log.h" +#include "ns3/atomic-counter.h" #include #include #include +#ifndef NS3_MTP #define USE_FREE_LIST 1 +#endif + #define FREE_LIST_SIZE 1000 #define OFFSET_MAX (std::numeric_limits::max ()) @@ -40,7 +44,11 @@ NS_LOG_COMPONENT_DEFINE ("ByteTagList"); */ struct ByteTagListData { uint32_t size; //!< size of the data +#ifdef NS3_MTP + AtomicCounter count; +#else uint32_t count; //!< use counter (for smart deallocation) +#endif uint32_t dirty; //!< number of bytes actually in use uint8_t data[4]; //!< data }; @@ -414,9 +422,11 @@ ByteTagList::Deallocate (struct ByteTagListData *data) { return; } - data->count--; - if (data->count == 0) + if (data->count-- == 0) { +#ifdef NS3_MTP + std::atomic_thread_fence (std::memory_order_acquire); +#endif uint8_t *buffer = (uint8_t *)data; delete [] buffer; } diff --git a/src/network/model/packet-metadata.cc b/src/network/model/packet-metadata.cc index d92314cc3..bf106420f 100644 --- a/src/network/model/packet-metadata.cc +++ b/src/network/model/packet-metadata.cc @@ -59,7 +59,9 @@ PacketMetadata::Enable (void) "after sending any packets. One way to fix this problem is " "to call ns3::PacketMetadata::Enable () near the beginning of" " the program, before any packets are sent."); +#ifndef NS3_MTP m_enable = true; +#endif } void @@ -67,7 +69,9 @@ PacketMetadata::EnableChecking (void) { NS_LOG_FUNCTION_NOARGS (); Enable (); +#ifndef NS3_MTP m_enableChecking = true; +#endif } void @@ -77,8 +81,7 @@ PacketMetadata::ReserveCopy (uint32_t size) struct PacketMetadata::Data *newData = PacketMetadata::Create (m_used + size); memcpy (newData->m_data, m_data->m_data, m_used); newData->m_dirtyEnd = m_used; - m_data->m_count--; - if (m_data->m_count == 0) + if (m_data->m_count-- == 1) { PacketMetadata::Recycle (m_data); } @@ -596,6 +599,9 @@ void PacketMetadata::Recycle (struct PacketMetadata::Data *data) { NS_LOG_FUNCTION (data); +#ifdef NS3_MTP + std::atomic_thread_fence (std::memory_order_acquire); +#endif if (!m_enable) { PacketMetadata::Deallocate (data); diff --git a/src/network/model/packet-metadata.h b/src/network/model/packet-metadata.h index 2dfd35a62..7bd0ad2c5 100644 --- a/src/network/model/packet-metadata.h +++ b/src/network/model/packet-metadata.h @@ -26,6 +26,7 @@ #include "ns3/callback.h" #include "ns3/assert.h" #include "ns3/type-id.h" +#include "ns3/atomic-counter.h" #include "buffer.h" namespace ns3 { @@ -413,7 +414,11 @@ private: */ struct Data { /** number of references to this struct Data instance. */ +#ifdef NS3_MTP + AtomicCounter m_count; +#else uint32_t m_count; +#endif /** size (in bytes) of m_data buffer below */ uint16_t m_size; /** max of the m_used field over all objects which @@ -722,8 +727,7 @@ PacketMetadata::operator = (PacketMetadata const& o) { // not self assignment NS_ASSERT (m_data != 0); - m_data->m_count--; - if (m_data->m_count == 0) + if (m_data->m_count-- == 1) { PacketMetadata::Recycle (m_data); } @@ -740,8 +744,7 @@ PacketMetadata::operator = (PacketMetadata const& o) PacketMetadata::~PacketMetadata () { NS_ASSERT (m_data != 0); - m_data->m_count--; - if (m_data->m_count == 0) + if (m_data->m_count-- == 1) { PacketMetadata::Recycle (m_data); } diff --git a/src/network/model/packet-tag-list.h b/src/network/model/packet-tag-list.h index c32690db1..1588f4cbd 100644 --- a/src/network/model/packet-tag-list.h +++ b/src/network/model/packet-tag-list.h @@ -28,6 +28,7 @@ #include #include #include "ns3/type-id.h" +#include "ns3/atomic-counter.h" namespace ns3 { @@ -141,7 +142,11 @@ public: struct TagData { struct TagData * next; /**< Pointer to next in list */ +#ifdef NS3_MTP + AtomicCounter count; +#else uint32_t count; /**< Number of incoming links */ +#endif TypeId tid; /**< Type of the tag serialized into #data */ uint32_t size; /**< Size of the \c data buffer */ uint8_t data[1]; /**< Serialization buffer */ @@ -358,11 +363,13 @@ PacketTagList::RemoveAll (void) struct TagData *prev = 0; for (struct TagData *cur = m_next; cur != 0; cur = cur->next) { - cur->count--; - if (cur->count > 0) + if (cur->count-- > 1) { break; } +#ifdef NS3_MTP + std::atomic_thread_fence (std::memory_order_acquire); +#endif if (prev != 0) { prev->~TagData ();