From 165f62d0cd771660e4b8d2ba7475e14d0d6f2e9f Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Mon, 26 Mar 2007 03:24:36 +0000 Subject: Fix a hole in the scheduler where collisions between waking blocked threads in mutexes with interrupts waking blocked threads in message queues can occur. Queue posts will put the threads on a separate list that is then added to the running list with IRQs disabled on the next task switch or CPU wakeup. Basically no overhead for other operations. Seems a likely cause of my occasional observation of the backlight fade causing playback threads to stop running and a recently reported blocking violation upon USB plugging. Time will tell but banging the backlight on and off frequently hasn't hiccuped again for me on H120. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12915 a1c6a512-1295-4272-9138-f99709370657 --- firmware/kernel.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'firmware/kernel.c') diff --git a/firmware/kernel.c b/firmware/kernel.c index c5e47a81ff..e09edeff77 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c @@ -126,7 +126,7 @@ static void queue_release_sender(struct thread_entry **sender, intptr_t retval) { (*sender)->retval = retval; - wakeup_thread(sender); + wakeup_thread_irq_safe(sender); #if 0 /* This should _never_ happen - there must never be multiple threads in this list and it is a corrupt state */ @@ -289,11 +289,14 @@ void queue_post(struct event_queue *q, long id, intptr_t data) } #endif - wakeup_thread(&q->thread); + wakeup_thread_irq_safe(&q->thread); set_irq_level(oldlevel); } #ifdef HAVE_EXTENDED_MESSAGING_AND_NAME +/* No wakeup_thread_irq_safe here because IRQ handlers are not allowed + use of this function - we only aim to protect the queue integrity by + turning them off. */ intptr_t queue_send(struct event_queue *q, long id, intptr_t data) { int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); -- cgit v1.2.3