Undo changeset 3163 (breaks multicast)
authorTom Henderson <tomh@tomh.org>
Wed, 28 May 2008 22:06:14 -0700
changeset 3170 d3438b415a8c
parent 3169 2598ea90f9db
child 3171 e74786aa54ae
Undo changeset 3163 (breaks multicast)
src/common/buffer.cc
src/common/buffer.h
--- a/src/common/buffer.cc	Wed May 28 13:59:53 2008 -0700
+++ b/src/common/buffer.cc	Wed May 28 22:06:14 2008 -0700
@@ -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 @@
    * 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 @@
   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 @@
     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 @@
 {
   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 @@
   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 @@
           Recycle (m_data);
         }
       m_data = o.m_data;
-      m_ownerId = o.m_ownerId;
       m_data->m_count++;
     }
   HEURISTICS (
@@ -340,7 +349,7 @@
   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 @@
        * 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::Recycle (m_data);
         }
       m_data = newData;
-      m_ownerId = newData->m_ownerId;
 
       int32_t delta = start - m_start;
       m_start += delta;
@@ -380,6 +386,9 @@
       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 @@
   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 @@
        * 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::Recycle (m_data);
         }
       m_data = newData;
-      m_ownerId = newData->m_ownerId;
 
       int32_t delta = -m_start;
       m_zeroAreaStart += delta;
@@ -432,6 +438,9 @@
       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 @@
   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 @@
       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 @@
   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++)
--- a/src/common/buffer.h	Wed May 28 13:59:53 2008 -0700
+++ b/src/common/buffer.h	Wed May 28 22:06:14 2008 -0700
@@ -58,13 +58,8 @@
  * 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 @@
   /* 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