]> Repos - portaudio/commitdiff
moved memory barriers as per this thread: http://music.columbia.edu/pipermail/portaud...
authorrossb <rossb@0f58301d-fd10-0410-b4af-bbb618454e57>
Thu, 18 Aug 2011 11:19:36 +0000 (11:19 +0000)
committerrossb <rossb@0f58301d-fd10-0410-b4af-bbb618454e57>
Thu, 18 Aug 2011 11:19:36 +0000 (11:19 +0000)
src/common/pa_ringbuffer.c
src/common/pa_ringbuffer.h

index a0a522529f95014bcc96ed947252175317381615..0047e705fefa5f581982c2d92ce9d936117306b2 100644 (file)
@@ -79,14 +79,12 @@ ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buf
 ** Return number of elements available for reading. */
 ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf )
 {
-    PaUtil_ReadMemoryBarrier();
     return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
 }
 /***************************************************************************
 ** Return number of elements available for writing. */
 ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf )
 {
-    /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
     return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
 }
 
@@ -128,6 +126,12 @@ ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, rin
         *dataPtr2 = NULL;
         *sizePtr2 = 0;
     }
+
+    /* fixme: do we want a memory barrier here for write-after-read / acquire ? 
+    if( available )
+        PaUtil_ReadMemoryBarrier(); / * (read-after-read / acquire) * /
+    */
+
     return elementCount;
 }
 
@@ -136,7 +140,9 @@ ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, rin
 */
 ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
 {
-    /* we need to ensure that previous writes are seen before we update the write index */
+    /* we need to ensure that previous writes are seen before we update the write index 
+       (write after write / release)
+    */
     PaUtil_WriteMemoryBarrier();
     return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask;
 }
@@ -152,7 +158,7 @@ ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring
                                 void **dataPtr2, ring_buffer_size_t *sizePtr2 )
 {
     ring_buffer_size_t   index;
-    ring_buffer_size_t   available = PaUtil_GetRingBufferReadAvailable( rbuf );
+    ring_buffer_size_t   available = PaUtil_GetRingBufferReadAvailable( rbuf ); /* doesn't use memory barrier */
     if( elementCount > available ) elementCount = available;
     /* Check to see if read is not contiguous. */
     index = rbuf->readIndex & rbuf->smallMask;
@@ -172,13 +178,19 @@ ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring
         *dataPtr2 = NULL;
         *sizePtr2 = 0;
     }
+    
+    if( available )
+        PaUtil_ReadMemoryBarrier(); /* (read-after-read / acquire) */
+
     return elementCount;
 }
 /***************************************************************************
 */
 ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
 {
-    /* we need to ensure that previous writes are always seen before updating the index. */
+    /* ensure that previous reads (copies out of the ring buffer) are always completed before updating the read index. 
+       (write-after-read / release)
+    */
     PaUtil_WriteMemoryBarrier();
     return rbuf->readIndex = (rbuf->readIndex + elementCount) & rbuf->bigMask;
 }
index 34a8d5caac833d1964633f3f6717cce23008dae6..004fdd5c6565adb4a2289e1f25d9e9eb646194cd 100644 (file)
@@ -90,8 +90,8 @@ extern "C"
 typedef struct PaUtilRingBuffer
 {
     ring_buffer_size_t  bufferSize; /**< Number of elements in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
-    ring_buffer_size_t  writeIndex; /**< Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */
-    ring_buffer_size_t  readIndex;  /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */
+    volatile ring_buffer_size_t  writeIndex; /**< Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */
+    volatile ring_buffer_size_t  readIndex;  /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */
     ring_buffer_size_t  bigMask;    /**< Used for wrapping indices with extra bit to distinguish full/empty. */
     ring_buffer_size_t  smallMask;  /**< Used for fitting indices to buffer. */
     ring_buffer_size_t  elementSizeBytes; /**< Number of bytes per element. */