[vlc-devel] [PATCH 4/4] fifo: use the queue API
RĂ©mi Denis-Courmont
remi at remlab.net
Sat Apr 11 20:41:06 CEST 2020
---
include/vlc_block.h | 45 ++++++++++++++-------
src/misc/fifo.c | 95 +++++++++++----------------------------------
2 files changed, 54 insertions(+), 86 deletions(-)
diff --git a/include/vlc_block.h b/include/vlc_block.h
index 2c98499db0..b57b4698cb 100644
--- a/include/vlc_block.h
+++ b/include/vlc_block.h
@@ -438,6 +438,8 @@ static inline block_t *block_ChainGather( block_t *p_list )
* @{
*/
+#include <vlc_queue.h>
+
/**
* Creates a thread-safe FIFO queue of blocks.
*
@@ -480,6 +482,11 @@ VLC_API block_t *block_FifoShow(block_fifo_t *);
typedef struct block_fifo_t vlc_fifo_t;
+static inline vlc_queue_t *vlc_fifo_queue(const vlc_fifo_t *fifo)
+{
+ return (vlc_queue_t *)fifo;
+}
+
/**
* Locks a block FIFO.
*
@@ -493,7 +500,10 @@ typedef struct block_fifo_t vlc_fifo_t;
* @warning Recursively locking a single FIFO is undefined. Locking more than
* one FIFO at a time may lead to lock inversion; mind the locking order.
*/
-VLC_API void vlc_fifo_Lock(vlc_fifo_t *);
+static inline void vlc_fifo_Lock(vlc_fifo_t *fifo)
+{
+ vlc_queue_Lock(vlc_fifo_queue(fifo));
+}
/**
* Unlocks a block FIFO.
@@ -503,7 +513,10 @@ VLC_API void vlc_fifo_Lock(vlc_fifo_t *);
*
* @note This function is not a cancellation point.
*/
-VLC_API void vlc_fifo_Unlock(vlc_fifo_t *);
+static inline void vlc_fifo_Unlock(vlc_fifo_t *fifo)
+{
+ vlc_queue_Unlock(vlc_fifo_queue(fifo));
+}
/**
* Wakes up one thread waiting on the FIFO, if any.
@@ -513,7 +526,10 @@ VLC_API void vlc_fifo_Unlock(vlc_fifo_t *);
* @warning For race-free operations, the FIFO should be locked by the calling
* thread. The function can be called on a unlocked FIFO however.
*/
-VLC_API void vlc_fifo_Signal(vlc_fifo_t *);
+static inline void vlc_fifo_Signal(vlc_fifo_t *fifo)
+{
+ vlc_queue_Signal(vlc_fifo_queue(fifo));
+}
/**
* Waits on the FIFO.
@@ -526,9 +542,17 @@ VLC_API void vlc_fifo_Signal(vlc_fifo_t *);
* @note This function is a cancellation point. In case of cancellation, the
* the FIFO will be locked before cancellation cleanup handlers are processed.
*/
-VLC_API void vlc_fifo_Wait(vlc_fifo_t *);
+static inline void vlc_fifo_Wait(vlc_fifo_t *fifo)
+{
+ vlc_queue_Wait(vlc_fifo_queue(fifo));
+}
-VLC_API void vlc_fifo_WaitCond(vlc_fifo_t *, vlc_cond_t *);
+static inline void vlc_fifo_WaitCond(vlc_fifo_t *fifo, vlc_cond_t *condvar)
+{
+ vlc_queue_t *q = vlc_fifo_queue(fifo);
+
+ vlc_cond_wait(condvar, &q->lock);
+}
/**
* Queues a linked-list of blocks into a locked FIFO.
@@ -541,7 +565,7 @@ VLC_API void vlc_fifo_WaitCond(vlc_fifo_t *, vlc_cond_t *);
* @warning The FIFO must be locked by the calling thread using
* vlc_fifo_Lock(). Otherwise behaviour is undefined.
*/
-VLC_API void vlc_fifo_QueueUnlocked(vlc_fifo_t *, block_t *);
+VLC_API void vlc_fifo_QueueUnlocked(vlc_fifo_t *fifo, block_t *);
/**
* Dequeues the first block from a locked FIFO, if any.
@@ -604,7 +628,7 @@ VLC_API size_t vlc_fifo_GetBytes(const vlc_fifo_t *) VLC_USED;
VLC_USED static inline bool vlc_fifo_IsEmpty(const vlc_fifo_t *fifo)
{
- return vlc_fifo_GetCount(fifo) == 0;
+ return vlc_queue_IsEmpty(vlc_fifo_queue(fifo));
}
static inline void vlc_fifo_Cleanup(void *fifo)
@@ -618,12 +642,7 @@ static inline void vlc_fifo_Cleanup(void *fifo)
*/
static inline void block_FifoEmpty(block_fifo_t *fifo)
{
- block_t *block;
-
- vlc_fifo_Lock(fifo);
- block = vlc_fifo_DequeueAllUnlocked(fifo);
- vlc_fifo_Unlock(fifo);
- block_ChainRelease(block);
+ block_ChainRelease((block_t *)vlc_queue_DequeueAll(vlc_fifo_queue(fifo)));
}
/**
diff --git a/src/misc/fifo.c b/src/misc/fifo.c
index 522d52d167..e829bfc8c9 100644
--- a/src/misc/fifo.c
+++ b/src/misc/fifo.c
@@ -37,118 +37,67 @@
*/
struct block_fifo_t
{
- vlc_mutex_t lock; /* fifo data lock */
- vlc_cond_t wait; /**< Wait for data */
-
- block_t *p_first;
- block_t **pp_last;
+ vlc_queue_t q;
size_t i_depth;
size_t i_size;
};
-void vlc_fifo_Lock(vlc_fifo_t *fifo)
-{
- vlc_mutex_lock(&fifo->lock);
-}
-
-void vlc_fifo_Unlock(vlc_fifo_t *fifo)
-{
- vlc_mutex_unlock(&fifo->lock);
-}
-
-void vlc_fifo_Signal(vlc_fifo_t *fifo)
-{
- vlc_cond_signal(&fifo->wait);
-}
+static const ptrdiff_t offset = offsetof (block_t, p_next);
-void vlc_fifo_Wait(vlc_fifo_t *fifo)
-{
- vlc_fifo_WaitCond(fifo, &fifo->wait);
-}
-
-void vlc_fifo_WaitCond(vlc_fifo_t *fifo, vlc_cond_t *condvar)
-{
- vlc_cond_wait(condvar, &fifo->lock);
-}
+static_assert (offsetof (block_fifo_t, q) == 0, "Problems in <vlc_block.h>");
size_t vlc_fifo_GetCount(const vlc_fifo_t *fifo)
{
- vlc_mutex_assert(&fifo->lock);
+ vlc_mutex_assert(&fifo->q.lock);
return fifo->i_depth;
}
size_t vlc_fifo_GetBytes(const vlc_fifo_t *fifo)
{
- vlc_mutex_assert(&fifo->lock);
+ vlc_mutex_assert(&fifo->q.lock);
return fifo->i_size;
}
void vlc_fifo_QueueUnlocked(block_fifo_t *fifo, block_t *block)
{
- vlc_mutex_assert(&fifo->lock);
- assert(*(fifo->pp_last) == NULL);
-
- *(fifo->pp_last) = block;
-
- while (block != NULL)
- {
- fifo->pp_last = &block->p_next;
+ for (block_t *b = block; b != NULL; b = b->p_next) {
fifo->i_depth++;
fifo->i_size += block->i_buffer;
-
- block = block->p_next;
}
- vlc_fifo_Signal(fifo);
+ vlc_queue_EnqueueUnlocked(&fifo->q, block, offset);
}
block_t *vlc_fifo_DequeueUnlocked(block_fifo_t *fifo)
{
- vlc_mutex_assert(&fifo->lock);
-
- block_t *block = fifo->p_first;
-
- if (block == NULL)
- return NULL; /* Nothing to do */
-
- fifo->p_first = block->p_next;
- if (block->p_next == NULL)
- fifo->pp_last = &fifo->p_first;
- block->p_next = NULL;
+ block_t *block = vlc_queue_DequeueUnlocked(&fifo->q, offset);
- assert(fifo->i_depth > 0);
- fifo->i_depth--;
- assert(fifo->i_size >= block->i_buffer);
- fifo->i_size -= block->i_buffer;
+ if (block != NULL) {
+ assert(fifo->i_depth > 0);
+ assert(fifo->i_size >= block->i_buffer);
+ fifo->i_depth--;
+ fifo->i_size -= block->i_buffer;
+ }
return block;
}
block_t *vlc_fifo_DequeueAllUnlocked(block_fifo_t *fifo)
{
- vlc_mutex_assert(&fifo->lock);
-
- block_t *block = fifo->p_first;
-
- fifo->p_first = NULL;
- fifo->pp_last = &fifo->p_first;
fifo->i_depth = 0;
fifo->i_size = 0;
-
- return block;
+ return vlc_queue_DequeueAllUnlocked(&fifo->q);
}
block_fifo_t *block_FifoNew( void )
{
block_fifo_t *p_fifo = malloc( sizeof( block_fifo_t ) );
- if( !p_fifo )
- return NULL;
- vlc_mutex_init( &p_fifo->lock );
- vlc_cond_init( &p_fifo->wait );
- p_fifo->p_first = NULL;
- p_fifo->pp_last = &p_fifo->p_first;
- p_fifo->i_depth = p_fifo->i_size = 0;
+ if (likely(p_fifo != NULL)) {
+ vlc_queue_Init(&p_fifo->q);
+ p_fifo->i_depth = 0;
+ p_fifo->i_size = 0;
+ }
return p_fifo;
}
@@ -183,8 +132,8 @@ block_t *block_FifoShow( block_fifo_t *p_fifo )
block_t *b;
vlc_fifo_Lock(p_fifo);
- assert(p_fifo->p_first != NULL);
- b = p_fifo->p_first;
+ assert(p_fifo->q.first != NULL);
+ b = (block_t *)p_fifo->q.first;
vlc_fifo_Unlock(p_fifo);
return b;
--
2.26.0
More information about the vlc-devel
mailing list