changeset 2119:1406c9fadbf3

* src/sched/sched.cxx (thread_entry): Fixed a bug which could cause a thread to be started with a non-zero scheduler lock. The previous code only decremented it by 1 so if the previous thread was executing with the lock > 1 the thread ended up with a non-zero lock. This is fixed by decrementing the lock in a loop until it reaches zero. * src/common/thread.cxx (idle_thread_main): Added an assert for a non-zero scheduler lock.
author nickg
date Thu, 19 Jan 2006 17:53:58 +0000
parents ced9249cc916
children 996973b15454
files packages/kernel/current/ChangeLog packages/kernel/current/src/common/thread.cxx packages/kernel/current/src/sched/sched.cxx
diffstat 3 files changed, 18 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,3 +1,15 @@
+2006-01-19  Nick Garnett  <nickg@ecoscentric.com>
+
+	* src/sched/sched.cxx (thread_entry): Fixed a bug which could
+	cause a thread to be started with a non-zero scheduler lock. The
+	previous code only decremented it by 1 so if the previous thread
+	was executing with the lock > 1 the thread ended up with a
+	non-zero lock. This is fixed by decrementing the lock in a loop
+	until it reaches zero.
+
+	* src/common/thread.cxx (idle_thread_main): Added an assert for a
+	non-zero scheduler lock.
+
 2006-01-10  Nick Garnett  <nickg@ecoscentric.com>
 
 	* src/sched/sched.cxx: 
--- a/packages/kernel/current/src/common/thread.cxx
+++ b/packages/kernel/current/src/common/thread.cxx
@@ -1230,6 +1230,7 @@ idle_thread_main( CYG_ADDRESS data )
 
         HAL_IDLE_THREAD_ACTION(idle_thread_loops[CYG_KERNEL_CPU_THIS()]);
 
+        CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 0, "Scheduler lock not zero" );
 #if 0
         // For testing, it is useful to be able to fake
         // clock interrupts in the idle thread.
--- a/packages/kernel/current/src/sched/sched.cxx
+++ b/packages/kernel/current/src/sched/sched.cxx
@@ -326,8 +326,11 @@ void Cyg_Scheduler::thread_entry( Cyg_Th
 #endif
     
     // Finally unlock the scheduler. As well as clearing the scheduler
-    // lock this allows any pending DSRs to execute.
-    unlock();    
+    // lock this allows any pending DSRs to execute. The new thread
+    // must start with a lock of zero, so we keep unlocking until the
+    // lock reaches zero.
+    while( get_sched_lock() != 0 )
+        unlock();    
 }
 
 // -------------------------------------------------------------------------