From: Pan Xiuli xiuli.pan@linux.intel.com
We may have irq to modify buffer when are modifing the buffer. Add the spin lock to make modify atomic.
Signed-off-by: Pan Xiuli xiuli.pan@linux.intel.com
--- Test with: Mininow max rt5651 SOF master: 019637ab250daa53c15da0a0a98c54f1c58d8ca3 SOF-Tool master: 33e4b0cc6f6a44e3e7ee849c04c515a5537242c7 https://github.com/plbossart/sound/tree/topic/sof-v4.14: 6fa721a8b7c6567eea0a2181bf9a3d2a12c31b00
Signed-off-by: Pan Xiuli xiuli.pan@linux.intel.com --- src/audio/buffer.c | 2 ++ src/include/reef/audio/buffer.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/src/audio/buffer.c b/src/audio/buffer.c index 0acf660..6ae7d92 100644 --- a/src/audio/buffer.c +++ b/src/audio/buffer.c @@ -84,6 +84,8 @@ struct comp_buffer *buffer_new(struct sof_ipc_buffer *desc) buffer->avail = 0; buffer->connected = 0;
+ spinlock_init(&buffer->lock); + return buffer; }
diff --git a/src/include/reef/audio/buffer.h b/src/include/reef/audio/buffer.h index 2bb2033..3e6d9e9 100644 --- a/src/include/reef/audio/buffer.h +++ b/src/include/reef/audio/buffer.h @@ -71,6 +71,8 @@ struct comp_buffer { /* lists */ struct list_item source_list; /* list in comp buffers */ struct list_item sink_list; /* list in comp buffers */ + + spinlock_t lock; };
/* pipeline buffer creation and destruction */ @@ -81,6 +83,10 @@ void buffer_free(struct comp_buffer *buffer); static inline void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes) { + uint32_t flags; + + spin_lock_irq(&buffer->lock, flags); + buffer->w_ptr += bytes;
/* check for pointer wrap */ @@ -98,6 +104,8 @@ static inline void comp_update_buffer_produce(struct comp_buffer *buffer, /* calculate free bytes */ buffer->free = buffer->size - buffer->avail;
+ spin_unlock_irq(&buffer->lock, flags); + tracev_buffer("pro"); tracev_value((buffer->avail << 16) | buffer->free); tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size); @@ -108,6 +116,10 @@ static inline void comp_update_buffer_produce(struct comp_buffer *buffer, static inline void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes) { + uint32_t flags; + + spin_lock_irq(&buffer->lock, flags); + buffer->r_ptr += bytes;
/* check for pointer wrap */ @@ -125,6 +137,8 @@ static inline void comp_update_buffer_consume(struct comp_buffer *buffer, /* calculate free bytes */ buffer->free = buffer->size - buffer->avail;
+ spin_unlock_irq(&buffer->lock, flags); + tracev_buffer("con"); tracev_value((buffer->avail << 16) | buffer->free); tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size);