diff --git a/pinos/client/loop.c b/pinos/client/loop.c index a64ef7f49..bbfa7f563 100644 --- a/pinos/client/loop.c +++ b/pinos/client/loop.c @@ -189,9 +189,9 @@ loop_invoke (SpaLoop *loop, res = func (loop, false, seq, size, data, user_data); } else { int32_t filled, avail; - uint32_t offset, l0; + uint32_t idx, offset, l0; - filled = spa_ringbuffer_get_write_index (&impl->buffer, &offset); + filled = spa_ringbuffer_get_write_index (&impl->buffer, &idx); if (filled < 0 || filled > impl->buffer.size) { pinos_log_warn ("data-loop %p: queue xrun %d", impl, filled); return SPA_RESULT_ERROR; @@ -201,7 +201,7 @@ loop_invoke (SpaLoop *loop, pinos_log_warn ("data-loop %p: queue full %d", impl, avail); return SPA_RESULT_ERROR; } - offset &= impl->buffer.mask; + offset = idx & impl->buffer.mask; l0 = offset + avail; if (l0 > impl->buffer.size) @@ -224,7 +224,7 @@ loop_invoke (SpaLoop *loop, } memcpy (item->data, data, size); - spa_ringbuffer_write_advance (&impl->buffer, item->item_size); + spa_ringbuffer_write_update (&impl->buffer, idx + item->item_size); pinos_loop_signal_event (&impl->this, impl->event); @@ -242,12 +242,12 @@ event_func (SpaLoopUtils *utils, void *data) { PinosLoopImpl *impl = data; - uint32_t offset; + uint32_t index; - while (spa_ringbuffer_get_read_index (&impl->buffer, &offset) > 0) { - InvokeItem *item = SPA_MEMBER (impl->buffer_data, offset & impl->buffer.mask, InvokeItem); + while (spa_ringbuffer_get_read_index (&impl->buffer, &index) > 0) { + InvokeItem *item = SPA_MEMBER (impl->buffer_data, index & impl->buffer.mask, InvokeItem); item->func (impl->this.loop, true, item->seq, item->size, item->data, item->user_data); - spa_ringbuffer_read_advance (&impl->buffer, item->item_size); + spa_ringbuffer_read_update (&impl->buffer, index + item->item_size); } } diff --git a/pinos/client/transport.c b/pinos/client/transport.c index 22d7eb99b..b118357bd 100644 --- a/pinos/client/transport.c +++ b/pinos/client/transport.c @@ -39,7 +39,7 @@ typedef struct { size_t offset; SpaEvent current; - uint32_t current_offset; + uint32_t current_index; } PinosTransportImpl; static size_t @@ -223,7 +223,7 @@ pinos_transport_add_event (PinosTransport *trans, index & trans->output_buffer->mask, event, size); - spa_ringbuffer_write_advance (trans->output_buffer, size); + spa_ringbuffer_write_update (trans->output_buffer, index + size); return SPA_RESULT_OK; } @@ -234,20 +234,17 @@ pinos_transport_next_event (PinosTransport *trans, { PinosTransportImpl *impl = (PinosTransportImpl *) trans; int32_t avail; - uint32_t index; if (impl == NULL || event == NULL) return SPA_RESULT_INVALID_ARGUMENTS; - avail = spa_ringbuffer_get_read_index (trans->input_buffer, &index); + avail = spa_ringbuffer_get_read_index (trans->input_buffer, &impl->current_index); if (avail < sizeof (SpaEvent)) return SPA_RESULT_ENUM_END; - impl->current_offset = index & trans->input_buffer->mask; - spa_ringbuffer_read_data (trans->input_buffer, trans->input_data, - impl->current_offset, + impl->current_index & trans->input_buffer->mask, &impl->current, sizeof (SpaEvent)); @@ -270,10 +267,10 @@ pinos_transport_parse_event (PinosTransport *trans, spa_ringbuffer_read_data (trans->input_buffer, trans->input_data, - impl->current_offset, + impl->current_index & trans->input_buffer->mask, event, size); - spa_ringbuffer_read_advance (trans->input_buffer, size); + spa_ringbuffer_read_update (trans->input_buffer, impl->current_index + size); return SPA_RESULT_OK; } diff --git a/spa/include/spa/barrier.h b/spa/include/spa/barrier.h deleted file mode 100644 index 54ae91bdf..000000000 --- a/spa/include/spa/barrier.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Simple Plugin API - * Copyright (C) 2016 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __SPA_BARRIER_H__ -#define __SPA_BARRIER_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#if defined(__GNUC__) -# if defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || defined( __i686__ ) || defined( __x86_64__ ) -# define spa_barrier_full() asm volatile("mfence":::"memory") -# define spa_barrier_read() asm volatile("lfence":::"memory") -# define spa_barrier_write() asm volatile("sfence":::"memory") -# elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) -# define spa_barrier_full() __sync_synchronize() -# define spa_barrier_read() __sync_synchronize() -# define spa_barrier_write() __sync_synchronize() -# endif -#else -# warning no memory barriers support found -# define spa_barrier_full() -# define spa_barrier_read() -# define spa_barrier_write() -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* __SPA_BARRIER_H__ */ diff --git a/spa/include/spa/meson.build b/spa/include/spa/meson.build index d0c0125b5..2a844598c 100644 --- a/spa/include/spa/meson.build +++ b/spa/include/spa/meson.build @@ -1,6 +1,5 @@ spa_headers = [ 'alloc-param.h', - 'barrier.h', 'buffer.h', 'clock.h', 'command.h', diff --git a/spa/include/spa/ringbuffer.h b/spa/include/spa/ringbuffer.h index e559bd6de..538afbd16 100644 --- a/spa/include/spa/ringbuffer.h +++ b/spa/include/spa/ringbuffer.h @@ -32,7 +32,6 @@ typedef struct _SpaRingbuffer SpaRingbuffer; #include #include -#include /** * SpaRingbuffer: @@ -103,9 +102,8 @@ spa_ringbuffer_get_read_index (SpaRingbuffer *rbuf, { int32_t avail; - *index = rbuf->readindex; - avail = (int32_t) (rbuf->writeindex - *index); - spa_barrier_read(); + *index = __atomic_load_n (&rbuf->readindex, __ATOMIC_RELAXED); + avail = (int32_t) (__atomic_load_n (&rbuf->writeindex, __ATOMIC_ACQUIRE) - *index); return avail; } @@ -138,18 +136,17 @@ spa_ringbuffer_read_data (SpaRingbuffer *rbuf, } /** - * spa_ringbuffer_read_advance: + * spa_ringbuffer_read_update: * @rbuf: a #SpaRingbuffer - * @len: number of bytes to advance + * @index: new index * - * Advance the read pointer by @len + * Update the read pointer to @index */ static inline void -spa_ringbuffer_read_advance (SpaRingbuffer *rbuf, - int32_t len) +spa_ringbuffer_read_update (SpaRingbuffer *rbuf, + int32_t index) { - spa_barrier_full(); - rbuf->readindex += len; + __atomic_store_n (&rbuf->readindex, index, __ATOMIC_RELEASE); } /** @@ -169,9 +166,8 @@ spa_ringbuffer_get_write_index (SpaRingbuffer *rbuf, { int32_t filled; - *index = rbuf->writeindex; - filled = (int32_t) (*index - rbuf->readindex); - spa_barrier_full(); + *index = __atomic_load_n (&rbuf->writeindex, __ATOMIC_RELAXED); + filled = (int32_t) (*index - __atomic_load_n (&rbuf->readindex, __ATOMIC_ACQUIRE)); return filled; } @@ -193,19 +189,18 @@ spa_ringbuffer_write_data (SpaRingbuffer *rbuf, } /** - * spa_ringbuffer_write_advance: + * spa_ringbuffer_write_update: * @rbuf: a #SpaRingbuffer - * @len: number of bytes to advance + * @index: new index * - * Advance the write pointer by @len + * Update the write pointer to @index * */ static inline void -spa_ringbuffer_write_advance (SpaRingbuffer *rbuf, - int32_t len) +spa_ringbuffer_write_update (SpaRingbuffer *rbuf, + int32_t index) { - spa_barrier_write(); - rbuf->writeindex += len; + __atomic_store_n (&rbuf->writeindex, index, __ATOMIC_RELEASE); } diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c index 2d4da65dc..70e3940ec 100644 --- a/spa/plugins/alsa/alsa-utils.c +++ b/spa/plugins/alsa/alsa-utils.c @@ -372,7 +372,7 @@ pull_frames (SpaALSAState *state, dst, n_bytes); - spa_ringbuffer_read_advance (ringbuffer, n_bytes); + spa_ringbuffer_read_update (ringbuffer, index + n_bytes); reuse = avail == n_bytes; } else { offs = SPA_MIN (d[0].chunk->offset + state->ready_offset, d[0].maxsize); diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index 883772763..5fc48fb0d 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -324,7 +324,7 @@ audiotestsrc_make_buffer (SpaAudioTestSrc *this) } else { this->render_func (this, SPA_MEMBER (b->outbuf->datas[0].data, offset, void), n_samples); } - spa_ringbuffer_write_advance (&b->rb->ringbuffer, n_bytes); + spa_ringbuffer_write_update (&b->rb->ringbuffer, index + n_bytes); } else { n_samples = n_bytes / this->bpf; this->render_func (this, b->outbuf->datas[0].data, n_samples);