diff --git a/docs/CREDITS b/docs/CREDITS index 14dc1c4769..e70dcab317 100644 --- a/docs/CREDITS +++ b/docs/CREDITS @@ -242,3 +242,4 @@ Adam Gashlin Robert Kukla David Quesada Jared Stafford +Martin Hensel diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h index fcab2d923c..32c052a34d 100644 --- a/firmware/export/kernel.h +++ b/firmware/export/kernel.h @@ -96,6 +96,7 @@ extern void queue_wait_w_tmo(struct event_queue *q, struct event *ev, int ticks) extern void queue_post(struct event_queue *q, long id, void *data); extern bool queue_empty(const struct event_queue* q); void queue_clear(struct event_queue* q); +extern void queue_remove_from_head(struct event_queue *q, long id); extern int queue_broadcast(long id, void *data); extern void mutex_init(struct mutex *m); diff --git a/firmware/kernel.c b/firmware/kernel.c index 4a6d61515a..b18b92327b 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c @@ -184,6 +184,19 @@ void queue_clear(struct event_queue* q) set_irq_level(oldlevel); } +void queue_remove_from_head(struct event_queue *q, long id) +{ + int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); + + while (q->read != q->write && + q->events[(q->read) & QUEUE_LENGTH_MASK].id == id) + { + q->read++; + } + + set_irq_level(oldlevel); +} + int queue_broadcast(long id, void *data) { int i; diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 9fe3df224c..ce1d995461 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c @@ -2760,6 +2760,7 @@ void audio_resume(void) void audio_next(void) { #ifndef SIMULATOR + queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA); queue_post(&mpeg_queue, MPEG_NEXT, NULL); #else /* SIMULATOR */ char* file; @@ -2788,6 +2789,7 @@ void audio_next(void) void audio_prev(void) { #ifndef SIMULATOR + queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA); queue_post(&mpeg_queue, MPEG_PREV, NULL); #else /* SIMULATOR */ char* file;