core: "clock-jitter" is in milliseconds
[vlc.git] / src / misc / fifo.c
blob1c6132f2971c79d1cb76c5dcd2084ede1380d58c
1 /*****************************************************************************
2 * fifo.c: FIFO management functions
3 *****************************************************************************
4 * Copyright (C) 2003-2004 VLC authors and VideoLAN
5 * Copyright (C) 2007-2015 RĂ©mi Denis-Courmont
7 * Authors: Laurent Aimar <fenrir@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
28 #include <assert.h>
29 #include <stdlib.h>
31 #include <vlc_common.h>
32 #include <vlc_block.h>
33 #include "libvlc.h"
35 /**
36 * Internal state for block queues
38 struct block_fifo_t
40 vlc_mutex_t lock; /* fifo data lock */
41 vlc_cond_t wait; /**< Wait for data */
43 block_t *p_first;
44 block_t **pp_last;
45 size_t i_depth;
46 size_t i_size;
49 void vlc_fifo_Lock(vlc_fifo_t *fifo)
51 vlc_mutex_lock(&fifo->lock);
54 void vlc_fifo_Unlock(vlc_fifo_t *fifo)
56 vlc_mutex_unlock(&fifo->lock);
59 void vlc_fifo_Signal(vlc_fifo_t *fifo)
61 vlc_cond_signal(&fifo->wait);
64 void vlc_fifo_Wait(vlc_fifo_t *fifo)
66 vlc_fifo_WaitCond(fifo, &fifo->wait);
69 void vlc_fifo_WaitCond(vlc_fifo_t *fifo, vlc_cond_t *condvar)
71 vlc_cond_wait(condvar, &fifo->lock);
74 int vlc_fifo_TimedWaitCond(vlc_fifo_t *fifo, vlc_cond_t *condvar, vlc_tick_t deadline)
76 return vlc_cond_timedwait(condvar, &fifo->lock, deadline);
79 size_t vlc_fifo_GetCount(const vlc_fifo_t *fifo)
81 return fifo->i_depth;
84 size_t vlc_fifo_GetBytes(const vlc_fifo_t *fifo)
86 return fifo->i_size;
89 void vlc_fifo_QueueUnlocked(block_fifo_t *fifo, block_t *block)
91 vlc_assert_locked(&fifo->lock);
92 assert(*(fifo->pp_last) == NULL);
94 *(fifo->pp_last) = block;
96 while (block != NULL)
98 fifo->pp_last = &block->p_next;
99 fifo->i_depth++;
100 fifo->i_size += block->i_buffer;
102 block = block->p_next;
105 vlc_fifo_Signal(fifo);
108 block_t *vlc_fifo_DequeueUnlocked(block_fifo_t *fifo)
110 vlc_assert_locked(&fifo->lock);
112 block_t *block = fifo->p_first;
114 if (block == NULL)
115 return NULL; /* Nothing to do */
117 fifo->p_first = block->p_next;
118 if (block->p_next == NULL)
119 fifo->pp_last = &fifo->p_first;
120 block->p_next = NULL;
122 assert(fifo->i_depth > 0);
123 fifo->i_depth--;
124 assert(fifo->i_size >= block->i_buffer);
125 fifo->i_size -= block->i_buffer;
127 return block;
130 block_t *vlc_fifo_DequeueAllUnlocked(block_fifo_t *fifo)
132 vlc_assert_locked(&fifo->lock);
134 block_t *block = fifo->p_first;
136 fifo->p_first = NULL;
137 fifo->pp_last = &fifo->p_first;
138 fifo->i_depth = 0;
139 fifo->i_size = 0;
141 return block;
144 block_fifo_t *block_FifoNew( void )
146 block_fifo_t *p_fifo = malloc( sizeof( block_fifo_t ) );
147 if( !p_fifo )
148 return NULL;
150 vlc_mutex_init( &p_fifo->lock );
151 vlc_cond_init( &p_fifo->wait );
152 p_fifo->p_first = NULL;
153 p_fifo->pp_last = &p_fifo->p_first;
154 p_fifo->i_depth = p_fifo->i_size = 0;
156 return p_fifo;
159 void block_FifoRelease( block_fifo_t *p_fifo )
161 block_ChainRelease( p_fifo->p_first );
162 vlc_cond_destroy( &p_fifo->wait );
163 vlc_mutex_destroy( &p_fifo->lock );
164 free( p_fifo );
167 void block_FifoEmpty(block_fifo_t *fifo)
169 block_t *block;
171 vlc_fifo_Lock(fifo);
172 block = vlc_fifo_DequeueAllUnlocked(fifo);
173 vlc_fifo_Unlock(fifo);
174 block_ChainRelease(block);
177 void block_FifoPut(block_fifo_t *fifo, block_t *block)
179 vlc_fifo_Lock(fifo);
180 vlc_fifo_QueueUnlocked(fifo, block);
181 vlc_fifo_Unlock(fifo);
184 block_t *block_FifoGet(block_fifo_t *fifo)
186 block_t *block;
188 vlc_testcancel();
190 vlc_fifo_Lock(fifo);
191 while (vlc_fifo_IsEmpty(fifo))
193 vlc_fifo_CleanupPush(fifo);
194 vlc_fifo_Wait(fifo);
195 vlc_cleanup_pop();
197 block = vlc_fifo_DequeueUnlocked(fifo);
198 vlc_fifo_Unlock(fifo);
200 return block;
203 block_t *block_FifoShow( block_fifo_t *p_fifo )
205 block_t *b;
207 vlc_mutex_lock( &p_fifo->lock );
208 assert(p_fifo->p_first != NULL);
209 b = p_fifo->p_first;
210 vlc_mutex_unlock( &p_fifo->lock );
212 return b;
215 /* FIXME: not (really) thread-safe */
216 size_t block_FifoSize (block_fifo_t *fifo)
218 size_t size;
220 vlc_mutex_lock (&fifo->lock);
221 size = fifo->i_size;
222 vlc_mutex_unlock (&fifo->lock);
223 return size;
226 /* FIXME: not (really) thread-safe */
227 size_t block_FifoCount (block_fifo_t *fifo)
229 size_t depth;
231 vlc_mutex_lock (&fifo->lock);
232 depth = fifo->i_depth;
233 vlc_mutex_unlock (&fifo->lock);
234 return depth;