fifo: non-throttling reader doesn't see data already written

Test: see the multi-reader interactive test
Change-Id: I0663a8e90efc094fef09401c6e2ecd3391100efa
diff --git a/audio_utils/fifo.cpp b/audio_utils/fifo.cpp
index 8f89318..ee36cbd 100644
--- a/audio_utils/fifo.cpp
+++ b/audio_utils/fifo.cpp
@@ -397,7 +397,16 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 audio_utils_fifo_reader::audio_utils_fifo_reader(audio_utils_fifo& fifo, bool throttlesWriter) :
-    audio_utils_fifo_provider(fifo), mLocalFront(0),
+    audio_utils_fifo_provider(fifo),
+
+    // If we throttle the writer, then initialize our front index to zero so that we see all data
+    // currently in the buffer.
+    // Otherwise, ignore everything currently in the buffer by initializing our front index to the
+    // current value of writer's rear.  This avoids an immediate -EOVERFLOW (overrun) in the case
+    // where reader starts out more than one buffer behind writer.  The initial catch-up does not
+    // contribute towards the totalLost, totalFlushed, or totalReleased counters.
+    mLocalFront(throttlesWriter ? 0 : mFifo.mWriterRear.loadConsume()),
+
     mThrottleFront(throttlesWriter ? mFifo.mThrottleFront : NULL),
     mArmLevel(-1), mTriggerLevel(mFifo.mFrameCount),
     mIsArmed(true), // because initial fill level of zero is > mArmLevel
diff --git a/audio_utils/fifo_index.cpp b/audio_utils/fifo_index.cpp
index ab8292f..d9a200a 100644
--- a/audio_utils/fifo_index.cpp
+++ b/audio_utils/fifo_index.cpp
@@ -42,6 +42,11 @@
     return sys_futex(&mIndex, op, waiters, NULL, NULL, 0);
 }
 
+uint32_t audio_utils_fifo_index::loadConsume()
+{
+    return atomic_load_explicit(&mIndex, std::memory_order_consume);
+}
+
 ////
 
 RefIndexDeferredStoreReleaseDeferredWake::RefIndexDeferredStoreReleaseDeferredWake(
diff --git a/audio_utils/include/audio_utils/fifo.h b/audio_utils/include/audio_utils/fifo.h
index 1b5eef1..2e911ab 100644
--- a/audio_utils/include/audio_utils/fifo.h
+++ b/audio_utils/include/audio_utils/fifo.h
@@ -455,6 +455,8 @@
      * \param fifo Associated FIFO.  Passed by reference because it must be non-NULL.
      * \param throttlesWriter Whether this reader throttles the writer.
      *                        At most one reader can specify throttlesWriter == true.
+     *                        A non-throttling reader does not see any data written
+     *                        prior to construction of the reader.
      */
     explicit audio_utils_fifo_reader(audio_utils_fifo& fifo, bool throttlesWriter = true);
     virtual ~audio_utils_fifo_reader();
diff --git a/audio_utils/include/audio_utils/fifo_index.h b/audio_utils/include/audio_utils/fifo_index.h
index 56de05f..1b8401f 100644
--- a/audio_utils/include/audio_utils/fifo_index.h
+++ b/audio_utils/include/audio_utils/fifo_index.h
@@ -75,6 +75,9 @@
      */
     int wake(int op, int waiters = 1);
 
+    // specialized use only, prefer loadAcquire in most cases
+    uint32_t loadConsume();
+
 private:
     // Linux futex is 32 bits regardless of platform.
     // It would make more sense to declare this as atomic_uint32_t, but there is no such type name.