aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/core/seq/seq_prioq.c28
-rw-r--r--sound/core/seq/seq_prioq.h6
-rw-r--r--sound/core/seq/seq_queue.c28
3 files changed, 25 insertions, 37 deletions
diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c
index bc1c8488fc2a..2bc6759e4adc 100644
--- a/sound/core/seq/seq_prioq.c
+++ b/sound/core/seq/seq_prioq.c
@@ -87,7 +87,7 @@ void snd_seq_prioq_delete(struct snd_seq_prioq **fifo)
87 if (f->cells > 0) { 87 if (f->cells > 0) {
88 /* drain prioQ */ 88 /* drain prioQ */
89 while (f->cells > 0) 89 while (f->cells > 0)
90 snd_seq_cell_free(snd_seq_prioq_cell_out(f)); 90 snd_seq_cell_free(snd_seq_prioq_cell_out(f, NULL));
91 } 91 }
92 92
93 kfree(f); 93 kfree(f);
@@ -214,8 +214,18 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f,
214 return 0; 214 return 0;
215} 215}
216 216
217/* return 1 if the current time >= event timestamp */
218static int event_is_ready(struct snd_seq_event *ev, void *current_time)
219{
220 if ((ev->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK)
221 return snd_seq_compare_tick_time(current_time, &ev->time.tick);
222 else
223 return snd_seq_compare_real_time(current_time, &ev->time.time);
224}
225
217/* dequeue cell from prioq */ 226/* dequeue cell from prioq */
218struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f) 227struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f,
228 void *current_time)
219{ 229{
220 struct snd_seq_event_cell *cell; 230 struct snd_seq_event_cell *cell;
221 unsigned long flags; 231 unsigned long flags;
@@ -227,6 +237,8 @@ struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f)
227 spin_lock_irqsave(&f->lock, flags); 237 spin_lock_irqsave(&f->lock, flags);
228 238
229 cell = f->head; 239 cell = f->head;
240 if (cell && current_time && !event_is_ready(&cell->event, current_time))
241 cell = NULL;
230 if (cell) { 242 if (cell) {
231 f->head = cell->next; 243 f->head = cell->next;
232 244
@@ -252,18 +264,6 @@ int snd_seq_prioq_avail(struct snd_seq_prioq * f)
252 return f->cells; 264 return f->cells;
253} 265}
254 266
255
256/* peek at cell at the head of the prioq */
257struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f)
258{
259 if (f == NULL) {
260 pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n");
261 return NULL;
262 }
263 return f->head;
264}
265
266
267static inline int prioq_match(struct snd_seq_event_cell *cell, 267static inline int prioq_match(struct snd_seq_event_cell *cell,
268 int client, int timestamp) 268 int client, int timestamp)
269{ 269{
diff --git a/sound/core/seq/seq_prioq.h b/sound/core/seq/seq_prioq.h
index d38bb78d9345..2c315ca10fc4 100644
--- a/sound/core/seq/seq_prioq.h
+++ b/sound/core/seq/seq_prioq.h
@@ -44,14 +44,12 @@ void snd_seq_prioq_delete(struct snd_seq_prioq **fifo);
44int snd_seq_prioq_cell_in(struct snd_seq_prioq *f, struct snd_seq_event_cell *cell); 44int snd_seq_prioq_cell_in(struct snd_seq_prioq *f, struct snd_seq_event_cell *cell);
45 45
46/* dequeue cell from prioq */ 46/* dequeue cell from prioq */
47struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f); 47struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f,
48 void *current_time);
48 49
49/* return number of events available in prioq */ 50/* return number of events available in prioq */
50int snd_seq_prioq_avail(struct snd_seq_prioq *f); 51int snd_seq_prioq_avail(struct snd_seq_prioq *f);
51 52
52/* peek at cell at the head of the prioq */
53struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq *f);
54
55/* client left queue */ 53/* client left queue */
56void snd_seq_prioq_leave(struct snd_seq_prioq *f, int client, int timestamp); 54void snd_seq_prioq_leave(struct snd_seq_prioq *f, int client, int timestamp);
57 55
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 0428e9061b47..b377f5048352 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -277,30 +277,20 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop)
277 277
278 __again: 278 __again:
279 /* Process tick queue... */ 279 /* Process tick queue... */
280 while ((cell = snd_seq_prioq_cell_peek(q->tickq)) != NULL) { 280 for (;;) {
281 if (snd_seq_compare_tick_time(&q->timer->tick.cur_tick, 281 cell = snd_seq_prioq_cell_out(q->tickq,
282 &cell->event.time.tick)) { 282 &q->timer->tick.cur_tick);
283 cell = snd_seq_prioq_cell_out(q->tickq); 283 if (!cell)
284 if (cell)
285 snd_seq_dispatch_event(cell, atomic, hop);
286 } else {
287 /* event remains in the queue */
288 break; 284 break;
289 } 285 snd_seq_dispatch_event(cell, atomic, hop);
290 } 286 }
291 287
292
293 /* Process time queue... */ 288 /* Process time queue... */
294 while ((cell = snd_seq_prioq_cell_peek(q->timeq)) != NULL) { 289 for (;;) {
295 if (snd_seq_compare_real_time(&q->timer->cur_time, 290 cell = snd_seq_prioq_cell_out(q->timeq, &q->timer->cur_time);
296 &cell->event.time.time)) { 291 if (!cell)
297 cell = snd_seq_prioq_cell_out(q->timeq);
298 if (cell)
299 snd_seq_dispatch_event(cell, atomic, hop);
300 } else {
301 /* event remains in the queue */
302 break; 292 break;
303 } 293 snd_seq_dispatch_event(cell, atomic, hop);
304 } 294 }
305 295
306 /* free lock */ 296 /* free lock */