Undo changeset 3163 (breaks multicast)
This commit is contained in:
@@ -24,10 +24,10 @@
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("Buffer");
|
||||
|
||||
#define LOG_INTERNAL_STATE(y) \
|
||||
NS_LOG_LOGIC (y << "start="<<m_start<<", end="<<m_end<<", zero start="<<m_zeroAreaStart<< \
|
||||
", zero end="<<m_zeroAreaEnd<<", count="<<m_data->m_count<<", size="<<m_data->m_size<< \
|
||||
", ownerId=" << m_ownerId << ", data owner=" << m_data->m_ownerId)
|
||||
#define LOG_INTERNAL_STATE(y) \
|
||||
NS_LOG_LOGIC (y << "start="<<m_start<<", end="<<m_end<<", zero start="<<m_zeroAreaStart<< \
|
||||
", zero end="<<m_zeroAreaEnd<<", count="<<m_data->m_count<<", size="<<m_data->m_size<< \
|
||||
", dirty start="<<m_data->m_dirtyStart<<", dirty end="<<m_data->m_dirtyEnd)
|
||||
|
||||
#ifdef BUFFER_HEURISTICS
|
||||
#define HEURISTICS(x) x
|
||||
@@ -58,10 +58,17 @@ struct BufferData {
|
||||
* Each buffer which references an instance holds a count.
|
||||
*/
|
||||
uint32_t m_count;
|
||||
uint32_t m_ownerId;
|
||||
/* the size of the m_data field below.
|
||||
*/
|
||||
uint32_t m_size;
|
||||
/* offset from the start of the m_data field below to the
|
||||
* start of the area in which user bytes were written.
|
||||
*/
|
||||
uint32_t m_dirtyStart;
|
||||
/* offset from the start of the m_data field below to the
|
||||
* end of the area in which user bytes were written.
|
||||
*/
|
||||
uint32_t m_dirtyEnd;
|
||||
/* The real data buffer holds _at least_ one byte.
|
||||
* Its real size is stored in the m_size field.
|
||||
*/
|
||||
@@ -130,7 +137,6 @@ BufferAllocate (uint32_t reqSize)
|
||||
struct BufferData *data = reinterpret_cast<struct BufferData*>(b);
|
||||
data->m_size = reqSize;
|
||||
data->m_count = 1;
|
||||
data->m_ownerId = 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -214,15 +220,19 @@ Buffer::CheckInternalState (void) const
|
||||
m_start <= m_zeroAreaStart &&
|
||||
m_zeroAreaStart <= m_zeroAreaEnd &&
|
||||
m_zeroAreaEnd <= m_end;
|
||||
bool dirtyOk =
|
||||
m_start >= m_data->m_dirtyStart &&
|
||||
m_end <= m_data->m_dirtyEnd;
|
||||
bool internalSizeOk = m_end - (m_zeroAreaEnd - m_zeroAreaStart) <= m_data->m_size &&
|
||||
m_start <= m_data->m_size &&
|
||||
m_zeroAreaStart <= m_data->m_size;
|
||||
|
||||
bool ok = m_data->m_count > 0 && offsetsOk && internalSizeOk;
|
||||
bool ok = m_data->m_count > 0 && offsetsOk && dirtyOk && internalSizeOk;
|
||||
if (!ok)
|
||||
{
|
||||
LOG_INTERNAL_STATE ("check " << this <<
|
||||
", " << (offsetsOk?"true":"false") <<
|
||||
", " << (dirtyOk?"true":"false") <<
|
||||
", " << (internalSizeOk?"true":"false") << " ");
|
||||
}
|
||||
return ok;
|
||||
@@ -233,7 +243,6 @@ Buffer::Initialize (uint32_t zeroSize)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << zeroSize);
|
||||
m_data = Buffer::Create (0);
|
||||
m_ownerId = m_data->m_ownerId;
|
||||
#ifdef BUFFER_HEURISTICS
|
||||
m_start = std::min (m_data->m_size, g_recommendedStart);
|
||||
m_maxZeroAreaStart = m_start;
|
||||
@@ -243,12 +252,13 @@ Buffer::Initialize (uint32_t zeroSize)
|
||||
m_zeroAreaStart = m_start;
|
||||
m_zeroAreaEnd = m_zeroAreaStart + zeroSize;
|
||||
m_end = m_zeroAreaEnd;
|
||||
m_data->m_dirtyStart = m_start;
|
||||
m_data->m_dirtyEnd = m_end;
|
||||
NS_ASSERT (CheckInternalState ());
|
||||
}
|
||||
|
||||
Buffer::Buffer (Buffer const&o)
|
||||
: m_data (o.m_data),
|
||||
m_ownerId (o.m_ownerId),
|
||||
#ifdef BUFFER_HEURISTICS
|
||||
m_maxZeroAreaStart (o.m_zeroAreaStart),
|
||||
#endif
|
||||
@@ -276,7 +286,6 @@ Buffer::operator = (Buffer const&o)
|
||||
Recycle (m_data);
|
||||
}
|
||||
m_data = o.m_data;
|
||||
m_ownerId = o.m_ownerId;
|
||||
m_data->m_count++;
|
||||
}
|
||||
HEURISTICS (
|
||||
@@ -340,7 +349,7 @@ Buffer::AddAtStart (uint32_t start)
|
||||
NS_LOG_FUNCTION (this << start);
|
||||
bool dirty;
|
||||
NS_ASSERT (CheckInternalState ());
|
||||
bool isDirty = m_data->m_count > 1 && m_ownerId != m_data->m_ownerId;
|
||||
bool isDirty = m_data->m_count > 1 && m_start > m_data->m_dirtyStart;
|
||||
if (m_start >= start && !isDirty)
|
||||
{
|
||||
/* enough space in the buffer and not dirty.
|
||||
@@ -348,11 +357,9 @@ Buffer::AddAtStart (uint32_t start)
|
||||
* Before: |*****---------***|
|
||||
* After: |***..---------***|
|
||||
*/
|
||||
NS_ASSERT (m_data->m_count == 1 || m_ownerId == m_data->m_ownerId);
|
||||
NS_ASSERT (m_data->m_count == 1 || m_start == m_data->m_dirtyStart);
|
||||
m_start -= start;
|
||||
dirty = m_ownerId != m_data->m_ownerId;
|
||||
m_ownerId++;
|
||||
m_data->m_ownerId = m_ownerId;
|
||||
dirty = m_start > m_data->m_dirtyStart;
|
||||
HEURISTICS (g_nAddNoRealloc++);
|
||||
}
|
||||
else
|
||||
@@ -366,7 +373,6 @@ Buffer::AddAtStart (uint32_t start)
|
||||
Buffer::Recycle (m_data);
|
||||
}
|
||||
m_data = newData;
|
||||
m_ownerId = newData->m_ownerId;
|
||||
|
||||
int32_t delta = start - m_start;
|
||||
m_start += delta;
|
||||
@@ -380,6 +386,9 @@ Buffer::AddAtStart (uint32_t start)
|
||||
HEURISTICS (g_nAddRealloc++);
|
||||
}
|
||||
HEURISTICS (m_maxZeroAreaStart = std::max (m_maxZeroAreaStart, m_zeroAreaStart));
|
||||
// update dirty area
|
||||
m_data->m_dirtyStart = m_start;
|
||||
m_data->m_dirtyEnd = m_end;
|
||||
LOG_INTERNAL_STATE ("add start=" << start << ", ");
|
||||
NS_ASSERT (CheckInternalState ());
|
||||
return dirty;
|
||||
@@ -390,7 +399,7 @@ Buffer::AddAtEnd (uint32_t end)
|
||||
NS_LOG_FUNCTION (this << end);
|
||||
bool dirty;
|
||||
NS_ASSERT (CheckInternalState ());
|
||||
bool isDirty = m_data->m_count > 1 && m_ownerId != m_data->m_ownerId;
|
||||
bool isDirty = m_data->m_count > 1 && m_end < m_data->m_dirtyEnd;
|
||||
if (GetInternalEnd () + end <= m_data->m_size && !isDirty)
|
||||
{
|
||||
/* enough space in buffer and not dirty
|
||||
@@ -398,12 +407,10 @@ Buffer::AddAtEnd (uint32_t end)
|
||||
* Before: |**----*****|
|
||||
* After: |**----...**|
|
||||
*/
|
||||
NS_ASSERT (m_data->m_count == 1 || m_ownerId == m_data->m_ownerId);
|
||||
NS_ASSERT (m_data->m_count == 1 || m_end == m_data->m_dirtyEnd);
|
||||
m_end += end;
|
||||
|
||||
dirty = m_ownerId != m_data->m_ownerId;
|
||||
m_ownerId++;
|
||||
m_data->m_ownerId = m_ownerId;
|
||||
dirty = m_end < m_data->m_dirtyEnd;
|
||||
|
||||
HEURISTICS (g_nAddNoRealloc++);
|
||||
}
|
||||
@@ -418,7 +425,6 @@ Buffer::AddAtEnd (uint32_t end)
|
||||
Buffer::Recycle (m_data);
|
||||
}
|
||||
m_data = newData;
|
||||
m_ownerId = newData->m_ownerId;
|
||||
|
||||
int32_t delta = -m_start;
|
||||
m_zeroAreaStart += delta;
|
||||
@@ -432,6 +438,9 @@ Buffer::AddAtEnd (uint32_t end)
|
||||
HEURISTICS (g_nAddRealloc++);
|
||||
}
|
||||
HEURISTICS (m_maxZeroAreaStart = std::max (m_maxZeroAreaStart, m_zeroAreaStart));
|
||||
// update dirty area
|
||||
m_data->m_dirtyStart = m_start;
|
||||
m_data->m_dirtyEnd = m_end;
|
||||
LOG_INTERNAL_STATE ("add end=" << end << ", ");
|
||||
NS_ASSERT (CheckInternalState ());
|
||||
|
||||
@@ -444,7 +453,7 @@ Buffer::AddAtEnd (const Buffer &o)
|
||||
NS_LOG_FUNCTION (this << &o);
|
||||
if (m_data->m_count == 1 &&
|
||||
m_end == m_zeroAreaEnd &&
|
||||
m_ownerId == m_data->m_ownerId &&
|
||||
m_end == m_data->m_dirtyEnd &&
|
||||
o.m_start == o.m_zeroAreaStart &&
|
||||
o.m_zeroAreaEnd - o.m_zeroAreaStart > 0)
|
||||
{
|
||||
@@ -456,6 +465,7 @@ Buffer::AddAtEnd (const Buffer &o)
|
||||
uint32_t zeroSize = o.m_zeroAreaEnd - o.m_zeroAreaStart;
|
||||
m_zeroAreaEnd += zeroSize;
|
||||
m_end = m_zeroAreaEnd;
|
||||
m_data->m_dirtyEnd = m_zeroAreaEnd;
|
||||
uint32_t endData = o.m_end - o.m_zeroAreaEnd;
|
||||
AddAtEnd (endData);
|
||||
Buffer::Iterator dst = End ();
|
||||
@@ -740,6 +750,7 @@ Buffer::Iterator::Write (Iterator start, Iterator end)
|
||||
NS_ASSERT (start.m_current <= end.m_current);
|
||||
NS_ASSERT (start.m_zeroStart == end.m_zeroStart);
|
||||
NS_ASSERT (start.m_zeroEnd == end.m_zeroEnd);
|
||||
NS_ASSERT (m_data != start.m_data);
|
||||
uint32_t size = end.m_current - start.m_current;
|
||||
Iterator cur = start;
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
|
||||
@@ -58,13 +58,8 @@ namespace ns3 {
|
||||
* BufferData. If the BufferData::m_count field is one, it means that
|
||||
* there exist only one instance of Buffer which references the
|
||||
* BufferData instance so, it is safe to modify it. It is also
|
||||
* safe to modify the content of a BufferData if someone has not yet
|
||||
* made incompatible changes to the BufferData and we detect that
|
||||
* case when the m_ownerId field is equal to the m_ownerId of the
|
||||
* BufferData itself. Whenever a change potentially incompatible
|
||||
* with other users is made to a BufferData object, we update the
|
||||
* m_ownerId field of the BufferData to ensure that the other users
|
||||
* will detect out modification.
|
||||
* safe to modify the content of a BufferData if the modification
|
||||
* falls outside of the "dirty area" defined by the BufferData.
|
||||
* In every other case, the BufferData must be copied before
|
||||
* being modified.
|
||||
*
|
||||
@@ -486,13 +481,6 @@ private:
|
||||
/* This structure is described in the buffer.cc file.
|
||||
*/
|
||||
struct BufferData *m_data;
|
||||
/* id of the owner of the BufferData object.
|
||||
* If this id matches the id stored in the BufferData object,
|
||||
* we are the current owner of the data. If we are not the owner,
|
||||
* and we need to acquire ownership before making modifications
|
||||
* by doing a copy.
|
||||
*/
|
||||
uint32_t m_ownerId;
|
||||
#ifdef BUFFER_HEURISTICS
|
||||
/* keep track of the maximum value of m_zeroAreaStart across
|
||||
* the lifetime of a Buffer instance. This variable is used
|
||||
|
||||
Reference in New Issue
Block a user