diff --git a/src/common/buffer.cc b/src/common/buffer.cc index a179e3f67..ad3421df7 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -24,10 +24,10 @@ NS_LOG_COMPONENT_DEFINE ("Buffer"); -#define LOG_INTERNAL_STATE(y) \ - NS_LOG_LOGIC (y << "start="<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++) diff --git a/src/common/buffer.h b/src/common/buffer.h index 452e1b66f..75f93f780 100644 --- a/src/common/buffer.h +++ b/src/common/buffer.h @@ -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