network: Make packets thread-safe
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -23,9 +23,12 @@
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
#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.
|
||||
*/
|
||||
|
||||
@@ -19,11 +19,15 @@
|
||||
*/
|
||||
#include "byte-tag-list.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/atomic-counter.h"
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
#ifndef NS3_MTP
|
||||
#define USE_FREE_LIST 1
|
||||
#endif
|
||||
|
||||
#define FREE_LIST_SIZE 1000
|
||||
#define OFFSET_MAX (std::numeric_limits<int32_t>::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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <stdint.h>
|
||||
#include <ostream>
|
||||
#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 ();
|
||||
|
||||
Reference in New Issue
Block a user