changeset 2310:4be03fe7814d

* cdl/synch.cdl: Added CYGIMP_MBOX_USE_MBOXT_PLAIN option. This is tested in various places but was not actually defined. It now is and defaults to 1 so that the plain version of mail boxes is selected. * include/mboxt.inl: * include/mboxt2.inl: Moved various CYG_ASSERTCLASS() calls to be within scheduler locked regions. Race conditions could have caused them to fail before. * tests/mbox1.cxx: * tests/kmbox1.cxx: Updated tests to work with mboxt implementation. This requires thread 1 to run at lower priority than thread 0.
author nickg
date Thu, 12 Oct 2006 15:41:49 +0000
parents 21a641579915
children 750c1f65057b
files packages/kernel/current/ChangeLog packages/kernel/current/cdl/synch.cdl packages/kernel/current/include/mboxt.inl packages/kernel/current/include/mboxt2.inl packages/kernel/current/tests/kmbox1.c packages/kernel/current/tests/mbox1.cxx
diffstat 6 files changed, 71 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,3 +1,20 @@
+2006-10-12  Nick Garnett  <nickg@ecoscentric.com>
+
+	* cdl/synch.cdl: Added CYGIMP_MBOX_USE_MBOXT_PLAIN option. This is
+	tested in various places but was not actually defined. It now is
+	and defaults to 1 so that the plain version of mail boxes is
+	selected.
+
+	* include/mboxt.inl: 
+	* include/mboxt2.inl: Moved various CYG_ASSERTCLASS() calls to be
+	within scheduler locked regions. Race conditions could have caused
+	them to fail before.
+
+	* tests/mbox1.cxx:
+	* tests/kmbox1.cxx: Updated tests to work with mboxt
+	implementation. This requires thread 1 to run at lower priority
+	than thread 0.
+
 2006-08-21  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* doc/kernel.sgml: Use reinterpret_cast, not static cast
--- a/packages/kernel/current/cdl/synch.cdl
+++ b/packages/kernel/current/cdl/synch.cdl
@@ -9,6 +9,7 @@
 ## -------------------------------------------
 ## This file is part of eCos, the Embedded Configurable Operating System.
 ## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2006 eCosCentric Ltd.
 ##
 ## eCos is free software; you can redistribute it and/or modify it under
 ## the terms of the GNU General Public License as published by the Free
@@ -32,9 +33,6 @@
 ##
 ## This exception does not invalidate any other reasons why a work based on
 ## this file might be covered by the GNU General Public License.
-##
-## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-## at http://sources.redhat.com/ecos/ecos-license/
 ## -------------------------------------------
 #####ECOSGPLCOPYRIGHTEND####
 # ====================================================================
@@ -141,6 +139,16 @@ cdl_component CYGSEM_KERNEL_SYNCH_MUTEX_
     
 }
 
+cdl_option CYGIMP_MBOX_USE_MBOXT_PLAIN {
+    display       "Use mboxt_plain mbox implementation"
+    default_value 1
+    description   "
+       Use the plain mboxt implementation instead of the mboxt2
+       implementation. The mboxt2 version is designed to provide
+       semantics compatible with UITRON, the plain implementation
+       is adquate in most other situations."
+}
+
 cdl_option CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT {
     display       "Message box blocking put support"
     doc           ref/kernel-mail-boxes.html
--- a/packages/kernel/current/include/mboxt.inl
+++ b/packages/kernel/current/include/mboxt.inl
@@ -11,6 +11,7 @@
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
@@ -34,9 +35,6 @@
 //
 // This exception does not invalidate any other reasons why a work based on
 // this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //==========================================================================
@@ -223,11 +221,11 @@ Cyg_Mboxt<T,QUEUE_SIZE>::get( T &ritem )
 
         CYG_INSTRUMENT_MBOXT(WAIT, this, count);
         
+        CYG_ASSERTCLASS( this, "Bad this pointer");        
+
         // Allow other threads to run
         Cyg_Scheduler::reschedule();
 
-        CYG_ASSERTCLASS( this, "Bad this pointer");        
-
         switch( self->get_wake_reason() )
         {
         case Cyg_Thread::DESTRUCT:
@@ -259,10 +257,11 @@ Cyg_Mboxt<T,QUEUE_SIZE>::get( T &ritem )
 #endif
     }
 
+    CYG_ASSERTCLASS( this, "Bad this pointer");
+
     // Unlock the scheduler and maybe switch threads
     Cyg_Scheduler::unlock();
 
-    CYG_ASSERTCLASS( this, "Bad this pointer");
     CYG_REPORT_RETVAL( result );
     return result;
 }
@@ -309,7 +308,7 @@ Cyg_Mboxt<T,QUEUE_SIZE>::get( T &ritem, 
         get_threadq.enqueue( self );
 
         CYG_INSTRUMENT_MBOXT(WAIT, this, count);
-        
+
         // Allow other threads to run
         Cyg_Scheduler::reschedule();
 
@@ -355,10 +354,11 @@ Cyg_Mboxt<T,QUEUE_SIZE>::get( T &ritem, 
 #endif
     }
 
+    CYG_ASSERTCLASS( this, "Bad this pointer");
+
     // Unlock the scheduler and maybe switch threads
     Cyg_Scheduler::unlock();
 
-    CYG_ASSERTCLASS( this, "Bad this pointer");
     CYG_REPORT_RETVAL( result );
     return result;
 }
@@ -373,11 +373,11 @@ Cyg_Mboxt<T,QUEUE_SIZE>::tryget( T &rite
 {
     CYG_REPORT_FUNCTION();
         
-    CYG_ASSERTCLASS( this, "Bad this pointer");
-    
     // Prevent preemption
     Cyg_Scheduler::lock();
 
+    CYG_ASSERTCLASS( this, "Bad this pointer");
+    
     CYG_INSTRUMENT_MBOXT(TRY, this, count);
     
     cyg_bool result = ( 0 < count );
@@ -408,11 +408,11 @@ Cyg_Mboxt<T,QUEUE_SIZE>::peek_item( T &r
 {
     CYG_REPORT_FUNCTION();
         
-    CYG_ASSERTCLASS( this, "Bad this pointer");
-    
     // Prevent preemption
     Cyg_Scheduler::lock();
 
+    CYG_ASSERTCLASS( this, "Bad this pointer");
+    
     CYG_INSTRUMENT_MBOXT(TRY, this, count);
     
     cyg_bool result = ( 0 < count );
--- a/packages/kernel/current/include/mboxt2.inl
+++ b/packages/kernel/current/include/mboxt2.inl
@@ -11,6 +11,7 @@
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
@@ -34,9 +35,6 @@
 //
 // This exception does not invalidate any other reasons why a work based on
 // this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //==========================================================================
@@ -261,10 +259,11 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::get( T &ritem 
         wakeup_putter();
 #endif
 
+        CYG_ASSERTCLASS( this, "Bad this pointer");
+
         // Unlock the scheduler and definitely switch threads
         Cyg_Scheduler::unlock();
 
-        CYG_ASSERTCLASS( this, "Bad this pointer");
         CYG_REPORT_RETVAL( true );
         return true;
     }
@@ -275,7 +274,9 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::get( T &ritem 
     get_threadq.enqueue( self );
 
     CYG_INSTRUMENT_MBOXT(WAIT, this, count);
-        
+
+    CYG_ASSERTCLASS( this, "Bad this pointer");
+
     // Unlock scheduler and allow other threads to run
     Cyg_Scheduler::unlock_reschedule();
 
@@ -294,7 +295,7 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::get( T &ritem 
     default:
         break;
     }
-    CYG_ASSERTCLASS( this, "Bad this pointer");    
+
     CYG_REPORT_RETVAL( result );
     return result;
 }
@@ -333,10 +334,11 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::get( T &ritem,
         wakeup_putter();
 #endif
 
+        CYG_ASSERTCLASS( this, "Bad this pointer");
+
         // Unlock the scheduler and maybe switch threads
         Cyg_Scheduler::unlock();
 
-        CYG_ASSERTCLASS( this, "Bad this pointer");
         CYG_REPORT_RETVAL( true );
         return true;
     }
@@ -356,14 +358,14 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::get( T &ritem,
         CYG_INSTRUMENT_MBOXT(WAIT, this, count);
     }
 
+    CYG_ASSERTCLASS( this, "Bad this pointer");        
+
     // Unlock scheduler and allow other threads to run
     Cyg_Scheduler::unlock_reschedule();
 
     // clear the timer; if it actually fired, no worries.
     self->clear_timer();
 
-    CYG_ASSERTCLASS( this, "Bad this pointer");        
-
     cyg_bool result = true;
     switch( self->get_wake_reason() )
     {
@@ -399,11 +401,11 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::tryget( T &rit
 {
     CYG_REPORT_FUNCTION();
         
-    CYG_ASSERTCLASS( this, "Bad this pointer");
-    
     // Prevent preemption
     Cyg_Scheduler::lock();
 
+    CYG_ASSERTCLASS( this, "Bad this pointer");
+    
     CYG_INSTRUMENT_MBOXT(TRY, this, count);
     
     cyg_bool result = ( 0 < count );
@@ -434,11 +436,11 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::peek_item( T &
 {
     CYG_REPORT_FUNCTION();
         
-    CYG_ASSERTCLASS( this, "Bad this pointer");
-    
     // Prevent preemption
     Cyg_Scheduler::lock();
 
+    CYG_ASSERTCLASS( this, "Bad this pointer");
+    
     CYG_INSTRUMENT_MBOXT(TRY, this, count);
     
     cyg_bool result = ( 0 < count );
@@ -480,11 +482,11 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::put( const T i
 
         CYG_INSTRUMENT_MBOXT(WAIT, this, count);
         
+        CYG_ASSERTCLASS( this, "Bad this pointer");    
+
         // when this returns, our item is in the queue.
         Cyg_Scheduler::unlock_reschedule();        // unlock, switch threads
 
-        CYG_ASSERTCLASS( this, "Bad this pointer");    
-
         cyg_bool result = true;
         switch( self->get_wake_reason() )
         {
@@ -506,8 +508,8 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::put( const T i
 
     if ( !get_threadq.empty() ) {
         wakeup_winner( item );
+        CYG_ASSERTCLASS( this, "Bad this pointer");    
         Cyg_Scheduler::unlock();        // unlock, maybe switch threads
-        CYG_ASSERTCLASS( this, "Bad this pointer");    
         CYG_REPORT_RETVAL( true );
         return true;
     }
@@ -568,6 +570,8 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::put( const T i
             CYG_INSTRUMENT_MBOXT(WAIT, this, count);
         }
 
+        CYG_ASSERTCLASS( this, "Bad this pointer");    
+
         // when this returns, our item is in the queue.
         Cyg_Scheduler::unlock_reschedule();        // unlock, switch threads
 
@@ -595,7 +599,6 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::put( const T i
             break;
         }
 
-        CYG_ASSERTCLASS( this, "Bad this pointer");    
         CYG_REPORT_RETVAL( result );
         return result;
     }
@@ -603,8 +606,8 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::put( const T i
 
     if ( !get_threadq.empty() ) {
         wakeup_winner( item );
+        CYG_ASSERTCLASS( this, "Bad this pointer");    
         Cyg_Scheduler::unlock();        // unlock, maybe switch threads
-        CYG_ASSERTCLASS( this, "Bad this pointer");    
         CYG_REPORT_RETVAL( true );
         return true;
     }
@@ -619,9 +622,10 @@ Cyg_Mboxt2<T,QUEUE_SIZE>::put( const T i
 
     itemqueue[ in ] = item;
 
+    CYG_ASSERTCLASS( this, "Bad this pointer");    
+
     // Unlock the scheduler and maybe switch threads
     Cyg_Scheduler::unlock();
-    CYG_ASSERTCLASS( this, "Bad this pointer");    
     CYG_REPORT_RETVAL( true );
     return true;
 }
--- a/packages/kernel/current/tests/kmbox1.c
+++ b/packages/kernel/current/tests/kmbox1.c
@@ -9,6 +9,7 @@
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
@@ -32,9 +33,6 @@
 //
 // This exception does not invalidate any other reasons why a work based on
 // this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //==========================================================================
@@ -187,7 +185,7 @@ void kmbox1_main( void )
         (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
     cyg_thread_resume(thread[0]);
 
-    cyg_thread_create(4, entry1 , (cyg_addrword_t)1, "kmbox1-1",
+    cyg_thread_create(5, entry1 , (cyg_addrword_t)1, "kmbox1-1",
         (void *)stack[1], STACKSIZE, &thread[1], &thread_obj[1]);
     cyg_thread_resume(thread[1]);
 
--- a/packages/kernel/current/tests/mbox1.cxx
+++ b/packages/kernel/current/tests/mbox1.cxx
@@ -9,6 +9,7 @@
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
@@ -32,9 +33,6 @@
 //
 // This exception does not invalidate any other reasons why a work based on
 // this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //==========================================================================
@@ -76,6 +74,8 @@ static void entry0( CYG_ADDRWORD data )
 {
     cyg_count8 u,i;
 
+    Cyg_Thread::self()->set_priority(4);
+    
     CYG_TEST_INFO("Testing put() and tryput() without wakeup");
     CYG_TEST_CHECK(!m0.waiting_to_get(), "mbox not initialized properly");
     CYG_TEST_CHECK(0==m0.peek(), "mbox not initialized properly");
@@ -151,6 +151,9 @@ static void entry0( CYG_ADDRWORD data )
 static void entry1( CYG_ADDRWORD data )
 {
     cyg_count8 i;
+
+    Cyg_Thread::self()->set_priority(5);
+    
     i = (cyg_count8)m1.get();
     CYG_TEST_CHECK(1==q++, "bad synchronization");
     m0.PUT((void *)3);                  // wake t0