summaryrefslogtreecommitdiff
path: root/cesar/ecos/packages/kernel/current/tests
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/ecos/packages/kernel/current/tests')
-rw-r--r--cesar/ecos/packages/kernel/current/tests/bin_sem0.cxx89
-rw-r--r--cesar/ecos/packages/kernel/current/tests/bin_sem1.cxx130
-rw-r--r--cesar/ecos/packages/kernel/current/tests/bin_sem2.cxx224
-rw-r--r--cesar/ecos/packages/kernel/current/tests/bin_sem3.cxx138
-rw-r--r--cesar/ecos/packages/kernel/current/tests/clock0.cxx286
-rw-r--r--cesar/ecos/packages/kernel/current/tests/clock1.cxx132
-rw-r--r--cesar/ecos/packages/kernel/current/tests/clockcnv.cxx287
-rw-r--r--cesar/ecos/packages/kernel/current/tests/clocktruth.cxx155
-rw-r--r--cesar/ecos/packages/kernel/current/tests/cnt_sem0.cxx89
-rw-r--r--cesar/ecos/packages/kernel/current/tests/cnt_sem1.cxx135
-rw-r--r--cesar/ecos/packages/kernel/current/tests/dhrystone.c1176
-rw-r--r--cesar/ecos/packages/kernel/current/tests/except1.cxx271
-rw-r--r--cesar/ecos/packages/kernel/current/tests/flag0.cxx88
-rw-r--r--cesar/ecos/packages/kernel/current/tests/flag1.cxx219
-rw-r--r--cesar/ecos/packages/kernel/current/tests/fptest.c364
-rw-r--r--cesar/ecos/packages/kernel/current/tests/intr0.cxx209
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kalarm0.c191
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kcache1.c422
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kcache2.c920
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kclock0.c274
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kclock1.c153
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kexcept1.c288
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kflag0.c99
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kflag1.c244
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kill.cxx199
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kintr0.c230
-rw-r--r--cesar/ecos/packages/kernel/current/tests/klock.c318
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kmbox1.c217
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kmutex0.c98
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kmutex1.c188
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kmutex3.c639
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kmutex4.c526
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kphilo.c236
-rw-r--r--cesar/ecos/packages/kernel/current/tests/ksched1.c103
-rw-r--r--cesar/ecos/packages/kernel/current/tests/ksem0.c100
-rw-r--r--cesar/ecos/packages/kernel/current/tests/ksem1.c169
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kthread0.c120
-rw-r--r--cesar/ecos/packages/kernel/current/tests/kthread1.c136
-rw-r--r--cesar/ecos/packages/kernel/current/tests/mbox1.cxx201
-rw-r--r--cesar/ecos/packages/kernel/current/tests/mqueue1.cxx411
-rw-r--r--cesar/ecos/packages/kernel/current/tests/mutex0.cxx96
-rw-r--r--cesar/ecos/packages/kernel/current/tests/mutex1.cxx162
-rw-r--r--cesar/ecos/packages/kernel/current/tests/mutex2.cxx272
-rw-r--r--cesar/ecos/packages/kernel/current/tests/mutex3.cxx631
-rw-r--r--cesar/ecos/packages/kernel/current/tests/philo.cxx241
-rw-r--r--cesar/ecos/packages/kernel/current/tests/release.cxx129
-rw-r--r--cesar/ecos/packages/kernel/current/tests/sched1.cxx111
-rw-r--r--cesar/ecos/packages/kernel/current/tests/smp.cxx474
-rw-r--r--cesar/ecos/packages/kernel/current/tests/stress_threads.c859
-rw-r--r--cesar/ecos/packages/kernel/current/tests/sync2.cxx201
-rw-r--r--cesar/ecos/packages/kernel/current/tests/sync3.cxx232
-rw-r--r--cesar/ecos/packages/kernel/current/tests/tcdiag.cxx97
-rw-r--r--cesar/ecos/packages/kernel/current/tests/testaux.h62
-rw-r--r--cesar/ecos/packages/kernel/current/tests/testaux.hxx110
-rw-r--r--cesar/ecos/packages/kernel/current/tests/thread0.cxx114
-rw-r--r--cesar/ecos/packages/kernel/current/tests/thread1.cxx172
-rw-r--r--cesar/ecos/packages/kernel/current/tests/thread2.cxx236
-rw-r--r--cesar/ecos/packages/kernel/current/tests/thread_gdb.c413
-rw-r--r--cesar/ecos/packages/kernel/current/tests/timeslice.c282
-rw-r--r--cesar/ecos/packages/kernel/current/tests/tm_basic.cxx1880
60 files changed, 17248 insertions, 0 deletions
diff --git a/cesar/ecos/packages/kernel/current/tests/bin_sem0.cxx b/cesar/ecos/packages/kernel/current/tests/bin_sem0.cxx
new file mode 100644
index 0000000000..06de873bc2
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/bin_sem0.cxx
@@ -0,0 +1,89 @@
+//==========================================================================
+//
+// bin_sem0.cxx
+//
+// Binary semaphore test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-24
+// Description: Limited to checking constructors/destructors
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include "testaux.hxx"
+
+static Cyg_Binary_Semaphore sema0, sema1(false), sema2(true);
+
+
+static bool flash( void )
+{
+ Cyg_Binary_Semaphore s0;
+
+ Cyg_Binary_Semaphore s1(true);
+
+ Cyg_Binary_Semaphore s2(false);
+
+ return true;
+}
+
+void bin_sem0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ CYG_TEST_PASS_FINISH("Binary Semaphore 0 OK");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ bin_sem0_main();
+}
+// EOF bin_sem0.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/bin_sem1.cxx b/cesar/ecos/packages/kernel/current/tests/bin_sem1.cxx
new file mode 100644
index 0000000000..3bfd7deb4f
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/bin_sem1.cxx
@@ -0,0 +1,130 @@
+//==========================================================================
+//
+// bin_sem1.cxx
+//
+// Binary semaphore test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-24
+// Description: Tests basic binary semaphore functionality.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+#include <cyg/kernel/thread.inl>
+
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+#define NTHREADS 2
+
+#include "testaux.hxx"
+
+static Cyg_Binary_Semaphore s0(true), s1(false), s2;
+
+static volatile cyg_ucount8 q = 0;
+
+static void entry0( CYG_ADDRWORD data )
+{
+ s0.wait();
+ CHECK( 0 == q++ );
+ s1.post();
+ s0.wait();
+ CHECK( 2 == q++ );
+ CHECK( ! s0.posted() );
+ CHECK( ! s0.trywait() );
+ s0.post();
+ CHECK( 3 == q++ );
+ CHECK( s0.posted() );
+ s1.post();
+ CHECK( ! s2.posted() );
+ s2.wait();
+ CHECK( 5 == q++ );
+ CYG_TEST_PASS_FINISH("Binary Semaphore 1 OK");
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ CHECK( s1.posted() );
+ s1.wait();
+ CHECK( 1 == q++ );
+ CHECK( ! s0.posted() );
+ s0.post();
+ s1.wait();
+ CHECK( 4 == q++ );
+ CHECK( s0.posted() );
+ CHECK( s0.trywait() );
+ CHECK( ! s0.posted() );
+ s2.post();
+ s0.wait();
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+void bin_sem1_main( void )
+{
+ CYG_TEST_INIT();
+
+ new_thread( entry0, 0);
+ new_thread( entry1, 1);
+
+#ifdef CYGIMP_THREAD_PRIORITY
+ thread[0]->set_priority( 4 );
+ thread[1]->set_priority( 5 ); // make sure the threads execute as intended
+#endif
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ bin_sem1_main();
+}
+// EOF bin_sem1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/bin_sem2.cxx b/cesar/ecos/packages/kernel/current/tests/bin_sem2.cxx
new file mode 100644
index 0000000000..7be38e8fc9
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/bin_sem2.cxx
@@ -0,0 +1,224 @@
+//==========================================================================
+//
+// bin_sem2.cxx
+//
+// Binary semaphore test 2
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg,dsm
+// Contributors: dsm
+// Date: 1998-03-10
+// Description:
+// Dining philosophers test. Based on philo.cxx
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/mutex.hxx>
+
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+static cyg_ucount16 PHILO_LOOPS = 1000;
+
+#define PHILOSOPHERS 15
+#define NTHREADS PHILOSOPHERS
+#include "testaux.hxx"
+
+static Cyg_Binary_Semaphore chopstick[PHILOSOPHERS];
+
+static char pstate[PHILOSOPHERS+1]; // state of each philosopher
+
+static cyg_ucount16 state_changes = 0;
+// state_changes keep track of number of changes to pstate so
+// we can exit after we've seen enough.
+
+
+static Cyg_Mutex pstate_mutex;
+static Cyg_Mutex cycle_mutex;
+
+static inline int left(cyg_count8 i)
+{
+ return (0 == i) ? PHILOSOPHERS-1 : i-1 ;
+}
+static inline int right(cyg_count8 i)
+{
+ return (PHILOSOPHERS == i+1) ? 0 : i+1 ;
+}
+
+void change_state(int id, char newstate)
+{
+ if (PHILO_LOOPS == state_changes++)
+ CYG_TEST_PASS_FINISH("Binary Semaphore 2 OK");
+
+
+ pstate_mutex.lock(); {
+ pstate[id] = newstate;
+ bool all_hungry = true; // until proved otherwise
+ for(cyg_ucount8 i=0; i < PHILOSOPHERS; i++) {
+ if('E' == pstate[i]) {
+ CHECK('E' != pstate[left(i)]);
+ CHECK('E' != pstate[right(i)]);
+ }
+ if('H' != pstate[i]) {
+ all_hungry = false;
+ }
+ }
+ // Theoretically it is possible for all the philosophers to be
+ // hungry but not waiting on semaphores. But in practice this
+ // means something is wrong.
+ CHECK(false == all_hungry);
+ } pstate_mutex.unlock();
+}
+
+char get_state(int id)
+{
+ pstate_mutex.lock();
+
+ char s = pstate[id];
+
+ pstate_mutex.unlock();
+
+ return s;
+}
+
+// -------------------------------------------------------------------------
+// Thread to behave like a philosopher
+
+void Philosopher( CYG_ADDRESS id )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+ Cyg_Binary_Semaphore *first_stick = &chopstick[id];
+ Cyg_Binary_Semaphore *second_stick = &chopstick[(id+1)%PHILOSOPHERS];
+
+ CHECK( id >= 0 && id < PHILOSOPHERS);
+
+ // Deadlock avoidance. The easiest way to make the philosophers
+ // behave is to make each pick up the lowest numbered stick
+ // first. This is how it works out anyway for all the philosophers
+ // except the last, who must have his sticks swapped.
+
+ if( id == PHILOSOPHERS-1 )
+ {
+ Cyg_Binary_Semaphore *t = first_stick;
+ first_stick = second_stick;
+ second_stick = t;
+ }
+
+
+ // The following variable is shared by all philosophers.
+ // It is incremented unprotected, but this does not matter
+ // since it is only present to introduce a little variability
+ // into the think and eat times.
+
+ static int cycle = 0;
+
+ for(;;)
+ {
+ // Think for a bit
+
+ self->delay((id+cycle++)%12); // Cogito ergo sum...
+
+ // I am now hungry, try to get the chopsticks
+ change_state(id,'H');
+
+ // Get the sticks
+ first_stick->wait();
+ second_stick->wait();
+
+ // Got them, now eat
+ change_state(id,'E');
+
+ // Check that the world is as I think it is...
+ CYG_TEST_CHECK( !first_stick->posted(),
+ "Not got first stick");
+ CYG_TEST_CHECK( !second_stick->posted(),
+ "Not got second stick");
+ CYG_TEST_CHECK( get_state(left(id)) != 'E',
+ "Left neighbour also eating!!");
+ CYG_TEST_CHECK( get_state(right(id)) != 'E',
+ "Right neighbour also eating!!");
+
+ self->delay((id+cycle++)%6); // munch munch
+
+ // Finished eating, put down sticks.
+
+ change_state(id,'T');
+
+ // put sticks back on table
+ first_stick->post();
+ second_stick->post();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+void bin_sem2_main( void )
+{
+ CYG_TEST_INIT();
+
+ if (cyg_test_is_simulator)
+ PHILO_LOOPS = 100;
+
+ for( int i = 0; i < PHILOSOPHERS; i++ )
+ {
+ pstate[i] = 'T'; // starting state
+ new_thread(Philosopher, i);
+
+ // make the matching chopstick present
+ chopstick[i].post();
+ }
+
+ Cyg_Scheduler::scheduler.start();
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ bin_sem2_main();
+}
+// EOF bin_sem2.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/bin_sem3.cxx b/cesar/ecos/packages/kernel/current/tests/bin_sem3.cxx
new file mode 100644
index 0000000000..b72e1396e8
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/bin_sem3.cxx
@@ -0,0 +1,138 @@
+//==========================================================================
+//
+// bin_sem3.cxx
+//
+// Binary semaphore test 3
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): David Brennan
+// Contributors: David Brennan
+// Date: 2003-06-06
+// Description: Tests basic binary semaphore timeout functionality.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+#include <cyg/kernel/thread.inl>
+
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+#define NTHREADS 2
+
+#include "testaux.hxx"
+
+static Cyg_Binary_Semaphore s0(true), s1(false), s2;
+
+static volatile cyg_ucount8 q = 0;
+
+static void entry0( CYG_ADDRWORD data )
+{
+ s0.wait();
+ CHECK( 0 == q++ );
+ s1.post();
+ s0.wait();
+ CHECK( 2 == q++ );
+ CHECK( ! s0.posted() );
+#ifndef CYGFUN_KERNEL_THREADS_TIMER
+ CHECK( ! s0.trywait() );
+#else // !CYGFUN_KERNEL_THREADS_TIMER
+ CHECK( ! s0.wait(10) );
+#endif // !CYGFUN_KERNEL_THREADS_TIMER
+ s0.post();
+ CHECK( 3 == q++ );
+ CHECK( s0.posted() );
+ s1.post();
+ CHECK( ! s2.posted() );
+ s2.wait();
+ CHECK( 5 == q++ );
+ CYG_TEST_PASS_FINISH("Binary Semaphore 3 OK");
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ CHECK( s1.posted() );
+ s1.wait();
+ CHECK( 1 == q++ );
+ CHECK( ! s0.posted() );
+ s0.post();
+ s1.wait();
+ CHECK( 4 == q++ );
+ CHECK( s0.posted() );
+#ifndef CYGFUN_KERNEL_THREADS_TIMER
+ CHECK( s0.trywait() );
+#else // !CYGFUN_KERNEL_THREADS_TIMER
+ CHECK( s0.wait(10) );
+#endif // !CYGFUN_KERNEL_THREADS_TIMER
+ CHECK( ! s0.posted() );
+ s2.post();
+ s0.wait();
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+void bin_sem3_main( void )
+{
+ CYG_TEST_INIT();
+
+ new_thread( entry0, 0);
+ new_thread( entry1, 1);
+
+#ifdef CYGIMP_THREAD_PRIORITY
+ thread[0]->set_priority( 4 );
+ thread[1]->set_priority( 5 ); // make sure the threads execute as intended
+#endif
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ bin_sem3_main();
+}
+// EOF bin_sem1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/clock0.cxx b/cesar/ecos/packages/kernel/current/tests/clock0.cxx
new file mode 100644
index 0000000000..42bdbb3fd8
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/clock0.cxx
@@ -0,0 +1,286 @@
+//==========================================================================
+//
+// clock0.cxx
+//
+// Clock test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-13
+// Description: Tests some basic clock functions.
+// Omissions: Doesn't test likely boundary conditions for
+// CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE
+// Real Time Clock Testing is limited
+// Options:
+// CYGIMP_KERNEL_COUNTERS_SINGLE_LIST
+// CYGIMP_KERNEL_COUNTERS_MULTI_LIST
+// CYGVAR_KERNEL_COUNTERS_CLOCK
+// CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE
+// Assumptions: This assumes we have long long support and
+// that counters are 64 bits.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/clock.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/clock.inl>
+
+#include "testaux.hxx"
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+
+cyg_alarm_fn call_me;
+
+bool flash( void )
+{
+ Cyg_Counter counter0 = Cyg_Counter();
+ Cyg_Counter counter1 = Cyg_Counter(723);
+
+ CYG_ASSERTCLASSO( counter0, "error" );
+ CYG_ASSERTCLASSO( counter1, "error" );
+
+ Cyg_Alarm alarm0 = Cyg_Alarm(&counter0, call_me, 12);
+
+ CYG_ASSERTCLASSO( alarm0, "error" );
+
+ Cyg_Clock::cyg_resolution res = {1,2};
+
+ Cyg_Clock clock0(res);
+
+ CYG_ASSERTCLASSO( clock0, "error" );
+
+ return true;
+}
+
+// Testing alarms
+//
+// call_me is a function that will be called when an alarm is
+// triggered. It updates a global variable called which is CHECKed
+// explicitly to see if the approriate alarms have been called.
+
+cyg_uint16 called = 0x0;
+
+void call_me(Cyg_Alarm *alarm, CYG_ADDRWORD data)
+{
+ called ^= data;
+}
+
+void call_me2(Cyg_Alarm *alarm, CYG_ADDRWORD data)
+{
+ call_me(alarm, data^0x10);
+}
+
+
+void clock0_main(void)
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ const cyg_uint32 big_number = 3333222111u;
+ Cyg_Counter counter0 = Cyg_Counter();
+
+ CHECK( 0 == counter0.current_value() );
+ CHECK( 0 == counter0.current_value_lo() );
+ CHECK( 0 == counter0.current_value_hi() );
+
+ counter0.tick();
+
+ CHECK( 1 == counter0.current_value() );
+ CHECK( 1 == counter0.current_value_lo() );
+ CHECK( 0 == counter0.current_value_hi() );
+
+ counter0.tick(6);
+
+ CHECK( 7 == counter0.current_value() );
+ CHECK( 7 == counter0.current_value_lo() );
+ CHECK( 0 == counter0.current_value_hi() );
+
+ counter0.set_value( 0xfffffffc );
+
+ CHECK( 0xfffffffc == counter0.current_value() );
+ CHECK( 0xfffffffc == counter0.current_value_lo() );
+ CHECK( 0 == counter0.current_value_hi() );
+
+ counter0.tick( 0x13 ); // Overflows 32 bits
+
+ CHECK( 0x10000000fULL == counter0.current_value() );
+ CHECK( 0xf == counter0.current_value_lo() );
+ CHECK( 0x1 == counter0.current_value_hi() );
+
+
+ Cyg_Counter counter1 = Cyg_Counter(big_number);
+
+ CHECK( 0 == counter1.current_value() );
+ CHECK( 0 == counter1.current_value_lo() );
+ CHECK( 0 == counter1.current_value_hi() );
+
+ counter1.tick(2);
+
+ CHECK( 2ll*big_number == counter1.current_value() );
+ CHECK( ((2ll*big_number) & 0xffffffff) ==
+ counter1.current_value_lo() );
+ CHECK( ((2ll*big_number) >> 32) == counter1.current_value_hi() );
+
+ counter1.tick();
+
+ CHECK( 3ll*big_number == counter1.current_value() );
+ CHECK( ((3ll*big_number) & 0xffffffff) ==
+ counter1.current_value_lo() );
+ CHECK( ((3ll*big_number) >> 32) == counter1.current_value_hi() );
+
+ counter1.tick();
+
+ CHECK( 4ll*big_number == counter1.current_value() );
+ CHECK( ((4ll*big_number) & 0xffffffff) ==
+ counter1.current_value_lo() );
+ CHECK( ((4ll*big_number) >> 32) == counter1.current_value_hi() );
+
+ counter1.set_value(1222333444555ll);
+ CHECK( 1222333444555ll == counter1.current_value() );
+
+ counter0.set_value(11);
+ CHECK( 11 == counter0.current_value() );
+
+ // the call_me functions cause the "called" bits to toggle
+ // CHECKing the value of called TEST_CHECKs the parity of # of calls
+ // made by each alarm.
+
+ Cyg_Alarm alarm0 = Cyg_Alarm(&counter0, call_me, 0x1);
+ Cyg_Alarm alarm1 = Cyg_Alarm(&counter0, call_me, 0x2);
+ Cyg_Alarm alarm2 = Cyg_Alarm(&counter0, call_me2, 0x4);
+
+ CHECK( 0x00 == called );
+ alarm0.initialize(12,3);
+ alarm2.initialize(21,2);
+ CHECK( 0x00 == called );
+
+ counter0.tick(); // 12 a0
+ CHECK( 0x01 == called );
+
+ alarm1.initialize(13,0);
+ counter0.tick(); // 13 a1
+ CHECK( 0x03 == called );
+
+ alarm1.initialize(17,0);
+ counter0.tick(); // 14
+ CHECK( 0x03 == called );
+
+ counter0.tick(); // 15 a0
+ CHECK( 0x02 == called );
+
+ counter0.tick(2); // 17 a1
+ CHECK( 0x00 == called );
+
+ counter0.tick(); // 18 a0
+ CHECK( 0x01 == called );
+
+ counter0.tick(3); // 21 a0 a2
+ CHECK( 0x14 == called );
+
+ counter0.tick(2); // 23 a2
+ CHECK( 0x00 == called );
+
+ alarm2.disable();
+
+ counter0.tick(2); // 25 a0(24)
+ CHECK( 0x01 == called );
+
+ alarm2.enable(); // a2 (enabled at 25)
+ CHECK( 0x15 == called );
+
+ counter0.tick(); // 26
+ CHECK( 0x15 == called );
+
+ counter0.tick(2); // 28 a0(27) a2(27)
+ CHECK( 0x00 == called );
+
+ counter0.tick(3); // 31 a0(30) a2(29 31)
+ CHECK( 0x01 == called );
+
+ Cyg_Clock::cyg_resolution res0;
+
+ res0.dividend = 100;
+ res0.divisor = 3;
+
+ Cyg_Clock::cyg_resolution res1;
+
+ Cyg_Clock clock0 = Cyg_Clock(res0);
+
+ res1 = clock0.get_resolution();
+ CHECK( res0.dividend == res1.dividend );
+ CHECK( res0.divisor == res1.divisor );
+
+ res1.dividend = 12;
+ res1.divisor = 25;
+
+ clock0.set_resolution(res1);
+ res0 = clock0.get_resolution();
+ CHECK( res0.dividend == res1.dividend );
+ CHECK( res0.divisor == res1.divisor );
+
+ res0 = Cyg_Clock::real_time_clock->get_resolution();
+
+ CYG_TEST_PASS_FINISH("Clock 0 OK");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ clock0_main();
+}
+
+#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( "Kernel real-time clock disabled");
+}
+
+#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
+// EOF clock0.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/clock1.cxx b/cesar/ecos/packages/kernel/current/tests/clock1.cxx
new file mode 100644
index 0000000000..bb8b2ae637
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/clock1.cxx
@@ -0,0 +1,132 @@
+//==========================================================================
+//
+// clock1.cxx
+//
+// Clock test 1 - Real Time Clock
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-16
+// Description: Tests the Kernel Real Time Clock
+// This test creates a thread, starts the scheduler and
+// delays for a time of about 5 seconds. This test should
+// be expected to run for about this length of time.
+// Omissions:
+// Doesn't test alarms attached to RTC.
+// Assumptions:
+// CYGVAR_KERNEL_COUNTERS_CLOCK must be set.
+// Resolution of clock small compared with 5s.
+// Overhead small compared with 5s.
+// Options:
+// CYGIMP_KERNEL_COUNTERS_SINGLE_LIST
+// CYGIMP_KERNEL_COUNTERS_MULTI_LIST
+// CYGVAR_KERNEL_COUNTERS_CLOCK
+// CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/clock.hxx>
+#include <cyg/kernel/thread.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/clock.inl>
+#include <cyg/kernel/thread.inl>
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+
+
+#define NTHREADS 1
+#include "testaux.hxx"
+
+static cyg_uint32 ticks; // Number of ticks thread[0] will delay for
+
+static cyg_uint64 TEST_DELAY;
+
+static void entry0( CYG_ADDRWORD data )
+{
+ ((Cyg_Thread *)data)->delay(ticks);
+
+ CYG_TEST_PASS_FINISH("Clock 1 OK");
+}
+
+void clock1_main( void )
+{
+ CYG_TEST_INIT();
+
+ if (cyg_test_is_simulator) {
+ TEST_DELAY = 100000000ll;
+ } else {
+ TEST_DELAY = 3000000000ll;
+ }
+
+ new_thread(entry0, (CYG_ADDRWORD)&thread_obj[0]);
+
+ Cyg_Clock::cyg_resolution res;
+
+ res = Cyg_Clock::real_time_clock->get_resolution ();
+
+ // RTC takes res.dividend/res.divisor ns/tick
+ ticks = ((cyg_uint64)TEST_DELAY * res.divisor) / res.dividend;
+
+ Cyg_Scheduler::start();
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ clock1_main();
+}
+
+#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( "Kernel real-time clock disabled");
+}
+
+#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
+
+// EOF clock1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/clockcnv.cxx b/cesar/ecos/packages/kernel/current/tests/clockcnv.cxx
new file mode 100644
index 0000000000..0b47482814
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/clockcnv.cxx
@@ -0,0 +1,287 @@
+//==========================================================================
+//
+// clockcnv.cxx
+//
+// Clock Converter test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 2000-01-24
+// Description: Tests the Kernel Real Time Clock Converter subsystem
+//
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/clock.hxx>
+#include <cyg/kernel/thread.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/clock.inl>
+#include <cyg/kernel/thread.inl>
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+
+#include <cyg/infra/diag.h>
+
+static void null_printf(const char *, ...)
+{ /* nothing */ }
+
+#define PRINTF0 diag_printf
+#define nPRINTF0 null_printf
+
+#define nPRINTF1 diag_printf
+#define PRINTF1 null_printf
+
+#define nPRINTF2 diag_printf
+#define PRINTF2 null_printf
+
+
+#define NTHREADS 1
+#include "testaux.hxx"
+
+static struct { cyg_uint32 ns; double scale; } ns_tickers[] = {
+ { 70000000, 7.0 }, // 7cS
+ { 50000000, 5.0 }, // 5cS
+ { 45000000, 4.5 }, // 4.5cS
+ { 30000000, 3.0 }, // 3cS
+ { 20000000, 2.0 }, // 2cS
+ { 10000000, 1.0 }, // 1cS - no change
+ { 5000000, 0.5 }, // 1/2 a cS
+ { 4900000, 0.49 }, // a bit below
+ { 3333333, 0.3333333 }, // 1/3 cS
+ { 1250000, 0.125 }, // 800Hz
+ { 1000000, 0.1 }, // 1000Hz
+ { 909090, 0.0909090 }, // 1100Hz
+ { 490000, 0.049 }, // 490uS
+ { 333333, 0.0333333 }, // 1/30 cS, 1/3mS
+ { 49000, 0.0049 }, // 49uS
+ { 33333, 0.0033333 }, // 1/30 mS
+ { 4900, 0.00049 }, // 4.9uS
+ // now some outlandish ones
+ { 170, 0.000017 }, // 170nS
+ { 11, 0.0000011 }, // 11nS
+ { 1000000000u, 100.0 }, // one second
+ { 1234567777u, 123.4567777 }, // 1.234... seconds
+ { 4294967291u, 429.4967291 }, // 4.3 seconds, nearly maxint.
+ // now some which are prime in the nS per tick field
+ { 909091, 0.0909091 }, // also 1100Hz - but 909091 is a prime!
+ // and some eye-pleasing primes from the www - if they're not actually
+ // prime, don't blame me. http://www.rsok.com/~jrm/printprimes.html
+ { 1000003, 0.1000003 },
+ { 1477771, 0.1477771 },
+ { 2000003, 0.2000003 },
+ { 2382001, 0.2382001 },
+ { 3333133, 0.3333133 },
+ { 3999971, 0.3999971 },
+ { 5555591, 0.5555591 },
+ { 6013919, 0.6013919 },
+ // That's enough
+};
+
+static void entry0( CYG_ADDRWORD data )
+{
+ // First just try it with the clock as default:
+ Cyg_Clock *rtc = Cyg_Clock::real_time_clock;
+
+ Cyg_Clock::converter cv, rcv;
+ Cyg_Clock::cyg_resolution res;
+
+ unsigned int counter = 0;
+ unsigned int skipped = 0;
+
+ unsigned int i;
+ for ( i = 0; i < sizeof( ns_tickers )/sizeof( ns_tickers[0] ); i++ ) {
+
+ unsigned int lcounter = 0;
+ unsigned int lskipped = 0;
+
+ rtc->get_other_to_clock_converter( ns_tickers[i].ns, &cv );
+ rtc->get_clock_to_other_converter( ns_tickers[i].ns, &rcv );
+
+ PRINTF1( "ns per tick: %d\n", ns_tickers[i].ns );
+ PRINTF1( " converter: * %d / %d * %d / %d\n",
+ (int)cv.mul1, (int)cv.div1, (int)cv.mul2,(int) cv.div2 );
+ PRINTF1( " reverser: * %d / %d * %d / %d\n",
+ (int)rcv.mul1, (int)rcv.div1, (int)rcv.mul2, (int)rcv.div2 );
+
+ double d = 1.0;
+ d *= (double)cv.mul1;
+ d /= (double)cv.div1;
+ d *= (double)cv.mul2;
+ d /= (double)cv.div2;
+ d *= (double)rcv.mul1;
+ d /= (double)rcv.div1;
+ d *= (double)rcv.mul2;
+ d /= (double)rcv.div2;
+ PRINTF1( " composite product %d.%d\n",
+ (int)d, ((int)(d * 1000000) % 1000000 ) );
+ d -= 1.0;
+ CYG_TEST_CHECK( d < +0.0001, "Overflow in composite product" );
+ CYG_TEST_CHECK( d > -0.0001, "Underflow in composite product" );
+
+ res = rtc->get_resolution();
+
+ double factor_other_to_clock;
+ double factor_clock_to_other;
+
+ // res.dividend/res.divisor is the number of nS in a system
+ // clock tick. So:
+ d = (double)res.dividend/(double)res.divisor;
+
+ factor_other_to_clock = ns_tickers[i].scale * 1.0e7 / d ;
+ factor_clock_to_other = d / (ns_tickers[i].scale * 1.0e7);
+
+ unsigned int j;
+ for ( j = 1; j < 100; j++ ) {
+ cyg_uint64 delay;
+ if (cyg_test_is_simulator)
+ j += 30; // test fewer values
+ /* tr.b..m..k.. */
+
+#ifdef CYGPKG_HAL_V85X_V850_CEB
+ j += 30; // test fewer values
+#endif
+
+ for ( delay = j; delay < 1000000000000ll; delay *= 10 ) {
+ // get the converted result
+ cyg_uint64 result = Cyg_Clock::convert( delay, &cv );
+
+ counter++; lcounter++;
+ if ( (double)delay * (double)cv.mul1 > 1.6e+19 ||
+ (double)delay * (double)rcv.mul1 > 1.6e+19 ) {
+ // in silly territory now, give up.
+ // (that's MAXINT squared, approx.)
+ skipped++; lskipped++;
+ continue; // so the counter is accurate
+ }
+
+ PRINTF2( "delay %x%08x to result %x%08x\n",
+ (int)(delay >> 32), (int)delay,
+ (int)(result >> 32), (int)result );
+
+ // get what it should be in double maths
+ double delta = factor_other_to_clock * (double)delay;
+ if ( delta > 1000.0 ) {
+ delta = (double)result - delta;
+ delta /= (double)result;
+ CYG_TEST_CHECK( delta <= +0.01,
+ "Proportional overflow in conversion to" );
+ CYG_TEST_CHECK( delta >= -0.01,
+ "Proportional underflow in conversion to" );
+ }
+ else {
+ cyg_uint64 lo = (cyg_uint64)(delta); // assume TRUNCATION
+ cyg_uint64 hi = lo + 1;
+ CYG_TEST_CHECK( hi >= result,
+ "Range overflow in conversion to" );
+ CYG_TEST_CHECK( lo <= result,
+ "Range underflow in conversion to" );
+ }
+
+ // get the converted result
+ result = Cyg_Clock::convert( delay, &rcv );
+
+ PRINTF2( "delay %x%08x from result %x%08x\n",
+ (int)(delay >> 32), (int)delay,
+ (int)(result >> 32), (int)result );
+
+ // get what it should be in double maths
+ delta = factor_clock_to_other * (double)delay;
+ if ( delta > 1000.0 ) {
+ delta = (double)result - delta;
+ delta /= (double)result;
+ CYG_TEST_CHECK( delta <= +0.01,
+ "Proportional overflow in conversion from" );
+ CYG_TEST_CHECK( delta >= -0.01,
+ "Proportional underflow in conversion from" );
+ }
+ else {
+ cyg_uint64 lo = (cyg_uint64)(delta); // assume TRUNCATION
+ cyg_uint64 hi = lo + 1;
+ CYG_TEST_CHECK( hi >= result,
+ "Range overflow in conversion from" );
+ CYG_TEST_CHECK( lo <= result,
+ "Range underflow in conversion from" );
+ }
+
+ if (cyg_test_is_simulator)
+ break;
+ }
+ }
+ PRINTF0( "INFO:<%d nS/tick: tested %d values, skipped %d because of overflow>\n",
+ ns_tickers[i].ns, lcounter, lskipped );
+ }
+
+ PRINTF0( "INFO:<tested %d values, total skipped %d because of overflow>\n",
+ counter, skipped );
+
+ CYG_TEST_PASS_FINISH("ClockCnv OK");
+}
+
+void clockcnv_main( void )
+{
+ CYG_TEST_INIT();
+ new_thread(entry0, (CYG_ADDRWORD)&thread_obj[0]);
+ Cyg_Scheduler::start();
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ clockcnv_main();
+}
+
+#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( "Kernel real-time clock disabled");
+}
+
+#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
+
+// EOF clockcnv.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/clocktruth.cxx b/cesar/ecos/packages/kernel/current/tests/clocktruth.cxx
new file mode 100644
index 0000000000..c8dbad1ffd
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/clocktruth.cxx
@@ -0,0 +1,155 @@
+//==========================================================================
+//
+// clocktruth.cxx
+//
+// Clock Converter test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 2001-06-05
+// Description: Tests the Kernel Real Time Clock for accuracy using a human
+//
+//####DESCRIPTIONEND####
+
+
+// This is for a human to watch to sanity check the clock rate.
+// It's easier to see what's happening if you enable this:
+#define nRUNFOREVER
+
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/clock.hxx>
+#include <cyg/kernel/sema.hxx>
+#include <cyg/kernel/thread.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/clock.inl>
+#include <cyg/kernel/thread.inl>
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+
+#include <cyg/infra/diag.h>
+
+#define NTHREADS 1
+#include "testaux.hxx"
+
+#ifdef RUNFOREVER
+#define ENDPOINT 8192
+#else
+#define ENDPOINT 20
+#endif
+
+static cyg_alarm_fn alarmfunc;
+static void alarmfunc( Cyg_Alarm *alarm, CYG_ADDRWORD data )
+{
+ Cyg_Binary_Semaphore *sp = (Cyg_Binary_Semaphore *)data;
+ sp->post();
+}
+
+
+static void entry0( CYG_ADDRWORD data )
+{
+ cyg_uint32 now, then;
+ int i;
+
+ Cyg_Clock *rtc = Cyg_Clock::real_time_clock;
+
+ Cyg_Binary_Semaphore sema;
+
+ Cyg_Alarm alarm( rtc, &alarmfunc, (CYG_ADDRWORD)&sema );
+
+ // First, print 100 lines as fast as you can, of distinct ticks.
+ for ( i = 0; i < 100; i++ ) {
+ now = rtc->current_value_lo();
+ then = now;
+ while ( then == now )
+ now = rtc->current_value_lo();
+
+ diag_printf( "INFO<time now %8d>\n", now );
+ }
+
+ diag_printf( "INFO<per-second times are: %8d>\n", rtc->current_value_lo() );
+ for ( i = 0; i < 20; i++ ) {
+ Cyg_Thread::counted_sleep( 100 );
+ diag_printf( "INFO<per-second time %2d is %8d>\n",
+ i, rtc->current_value_lo() );
+ }
+
+ alarm.initialize( rtc->current_value() + 100, 100 );
+ alarm.enable();
+ for ( i = 0; i < ENDPOINT; i++ ) {
+ sema.wait();
+ diag_printf( "INFO<alarm time %2d is %8d>\n",
+ i, rtc->current_value_lo() );
+ }
+
+ CYG_TEST_PASS_FINISH("Clock truth OK");
+}
+
+void clocktruth_main( void )
+{
+ CYG_TEST_INIT();
+ new_thread(entry0, (CYG_ADDRWORD)&thread_obj[0]);
+ Cyg_Scheduler::start();
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ clocktruth_main();
+}
+
+#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( "Kernel real-time clock disabled");
+}
+
+#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
+
+// EOF clocktruth.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/cnt_sem0.cxx b/cesar/ecos/packages/kernel/current/tests/cnt_sem0.cxx
new file mode 100644
index 0000000000..8ef0f1656c
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/cnt_sem0.cxx
@@ -0,0 +1,89 @@
+//==========================================================================
+//
+// cnt_sem0.cxx
+//
+// Counting semaphore test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-24
+// Description: Limited to checking constructors/destructors
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+static Cyg_Counting_Semaphore sema0, sema1(0), sema2(1);
+
+#include "testaux.hxx"
+
+static bool flash( void )
+{
+ Cyg_Counting_Semaphore s0;
+
+ Cyg_Counting_Semaphore s1(97);
+
+ Cyg_Counting_Semaphore s2(0);
+
+ return true;
+}
+
+void cnt_sem0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ CYG_TEST_PASS_FINISH("Counting Semaphore 0 OK");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ cnt_sem0_main();
+}
+
+// EOF cnt_sem0.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/cnt_sem1.cxx b/cesar/ecos/packages/kernel/current/tests/cnt_sem1.cxx
new file mode 100644
index 0000000000..f23b63f7d3
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/cnt_sem1.cxx
@@ -0,0 +1,135 @@
+//==========================================================================
+//
+// cnt_sem1.cxx
+//
+// Counting semaphore test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-24
+// Description: Tests basic counting semaphore functionality.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+
+#define NTHREADS 2
+#include "testaux.hxx"
+
+static Cyg_Counting_Semaphore s0(0), s1(2), s2;
+
+static volatile cyg_ucount8 q = 0;
+
+static void entry0( CYG_ADDRWORD data )
+{
+ s0.wait();
+ CHECK( 1 == q++ );
+ s1.post();
+ s0.wait();
+ CHECK( 3 == q++ );
+ CHECK( 0 == s0.peek() );
+ CHECK( ! s0.trywait() );
+ s0.post();
+ CHECK( 4 == q++ );
+ CHECK( 1 == s0.peek() );
+ s0.post();
+ CHECK( 2 == s0.peek() );
+ s1.post();
+ CHECK( 0 == s2.peek() );
+ s2.wait();
+ CHECK( 6 == q++ );
+ CYG_TEST_PASS_FINISH("Counting Semaphore 1 OK");
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ CHECK( 2 == s1.peek() );
+ s1.wait();
+ CHECK( 1 == s1.peek() );
+ s1.wait();
+ CHECK( 0 == q++ );
+ CHECK( 0 == s0.peek() );
+ s0.post();
+ s1.wait();
+ CHECK( 2 == q++ );
+ s0.post();
+ s1.wait();
+ CHECK( 5 == q++ );
+ CHECK( 2 == s0.peek() );
+ CHECK( s0.trywait() );
+ CHECK( 1 == s0.peek() );
+ CHECK( s0.trywait() );
+ CHECK( 0 == s0.peek() );
+ s2.post();
+ s0.wait();
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+void cnt_sem1_main( void )
+{
+ CYG_TEST_INIT();
+
+ new_thread(entry0, 0);
+ new_thread(entry1, 1);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ cnt_sem1_main();
+}
+
+// EOF cnt_sem1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/dhrystone.c b/cesar/ecos/packages/kernel/current/tests/dhrystone.c
new file mode 100644
index 0000000000..6eb3d0a4ec
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/dhrystone.c
@@ -0,0 +1,1176 @@
+//=============================================================================
+//####UNSUPPORTEDBEGIN####
+//
+// -------------------------------------------
+// This source file has been contributed to eCos/Red Hat. It may have been
+// changed slightly to provide an interface consistent with those of other
+// files.
+//
+// The functionality and contents of this file is supplied "AS IS"
+// without any form of support and will not necessarily be kept up
+// to date by Red Hat.
+//
+// The style of programming used in this file may not comply with the
+// eCos programming guidelines. Please do not use as a base for other
+// files.
+//
+// All inquiries about this file, or the functionality provided by it,
+// should be directed to the 'ecos-discuss' mailing list (see
+// http://ecos.sourceware.org/ecos/intouch.html for details).
+//
+// -------------------------------------------
+//
+//####UNSUPPORTEDEND####
+//=============================================================================
+// Originally three different files, dhry.h, dhry21a.c and dhry21b.c
+// Merged into one file and changed a little to avoid compilation warnings.
+// The files were found at:
+// FTP ftp.nosc.mil/pub/aburto/dhrystone
+//=============================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/infra.h>
+#include <pkgconf/kernel.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h>
+
+#if !defined(CYGPKG_ISOINFRA)
+# define NA_MSG "Requires CYGPKG_ISOINFRA"
+#else
+# include <pkgconf/isoinfra.h>
+
+# if !defined(CYGFUN_KERNEL_API_C) \
+ || !defined(CYGINT_ISO_STDIO_FORMATTED_IO) \
+ || CYGINT_ISO_MALLOC == 0 \
+ || !defined(CYGINT_ISO_STRING_STRFUNCS)
+
+# define NA_MSG "Requires CYGFUN_KERNEL_API_C && CYGINT_ISO_STDIO_FORMATTED_IO && CYGINT_ISO_MALLOC && CYGINT_ISO_STRING_STRFUNCS"
+
+# elif !defined(__OPTIMIZE__) \
+ || defined(CYGPKG_INFRA_DEBUG) \
+ || defined(CYGPKG_KERNEL_INSTRUMENT)
+# define NA_MSG "Only runs with optimized code, no tracing and no asserts"
+# elif defined(CYGDBG_INFRA_DIAG_USE_DEVICE)
+# define NA_MSG "Must use HAL diag output to avoid background DSR activity"
+# endif
+#endif
+
+#ifndef NA_MSG
+
+#include <cyg/hal/hal_cache.h>
+#include <cyg/kernel/kapi.h>
+#include <stdlib.h>
+#include <string.h>
+
+// Time in seconds.
+double
+dtime(void)
+{
+ return (double) cyg_current_time() / 100;
+}
+
+// Number of loops to run.
+#if defined(CYGPRI_KERNEL_TESTS_DHRYSTONE_PASSES)
+# define PASSES CYGPRI_KERNEL_TESTS_DHRYSTONE_PASSES
+#else
+# define PASSES 400000
+#endif
+
+// Used in the code below to mark changes to the code.
+#define __ECOS__
+
+#undef true
+#undef false
+
+
+/*
+ *************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry.h (part 1 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ * Siemens Nixdorf Inf. Syst.
+ * STM OS 32
+ * Otto-Hahn-Ring 6
+ * W-8000 Muenchen 83
+ * Germany
+ * Phone: [+49]-89-636-42436
+ * (8-17 Central European Time)
+ * UUCP: weicker@ztivax.uucp@unido.uucp
+ * Internet: weicker@ztivax.siemens.com
+ *
+ * Original Version (in Ada) published in
+ * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ * pp. 1013 - 1030, together with the statistics
+ * on which the distribution of statements etc. is based.
+ *
+ * In this C version, the following C library functions are
+ * used:
+ * - strcpy, strcmp (inside the measurement loop)
+ * - printf, scanf (outside the measurement loop)
+ *
+ * Collection of Results:
+ * Reinhold Weicker (address see above) and
+ *
+ * Rick Richardson
+ * PC Research. Inc.
+ * 94 Apple Orchard Drive
+ * Tinton Falls, NJ 07724
+ * Phone: (201) 834-1378 (9-17 EST)
+ * UUCP: ...!uunet!pcrat!rick
+ *
+ * Please send results to Rick Richardson and/or Reinhold Weicker.
+ * Complete information should be given on hardware and software
+ * used. Hardware information includes: Machine type, CPU, type and
+ * size of caches; for microprocessors: clock frequency, memory speed
+ * (number of wait states). Software information includes: Compiler
+ * (and runtime library) manufacturer and version, compilation
+ * switches, OS version. The Operating System version may give an
+ * indication about the compiler; Dhrystone itself performs no OS
+ * calls in the measurement loop.
+ *
+ * The complete output generated by the program should be mailed
+ * such that at least some checks for correctness can be made.
+ *
+ *************************************************************************
+ *
+ * History: This version C/2.1 has been made for two reasons:
+ *
+ * 1) There is an obvious need for a common C version of
+ * Dhrystone, since C is at present the most popular system
+ * programming language for the class of processors
+ * (microcomputers, minicomputers) where Dhrystone is used
+ * most. There should be, as far as possible, only one C
+ * version of Dhrystone such that results can be compared
+ * without restrictions. In the past, the C versions
+ * distributed by Rick Richardson (Version 1.1) and by
+ * Reinhold Weicker had small (though not significant)
+ * differences.
+ *
+ * 2) As far as it is possible without changes to the
+ * Dhrystone statistics, optimizing compilers should be
+ * prevented from removing significant statements.
+ *
+ * This C version has been developed in cooperation with
+ * Rick Richardson (Tinton Falls, NJ), it incorporates many
+ * ideas from the "Version 1.1" distributed previously by
+ * him over the UNIX network Usenet.
+ * I also thank Chaim Benedelac (National Semiconductor),
+ * David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ * for their help with comments on earlier versions of the
+ * benchmark.
+ *
+ * Changes: In the initialization part, this version follows mostly
+ * Rick Richardson's version distributed via Usenet, not the
+ * version distributed earlier via floppy disk by Reinhold
+ * Weicker. As a concession to older compilers, names have
+ * been made unique within the first 8 characters. Inside the
+ * measurement loop, this version follows the version
+ * previously distributed by Reinhold Weicker.
+ *
+ * At several places in the benchmark, code has been added,
+ * but within the measurement loop only in branches that
+ * are not executed. The intention is that optimizing
+ * compilers should be prevented from moving code out of the
+ * measurement loop, or from removing code altogether. Since
+ * the statements that are executed within the measurement
+ * loop have NOT been changed, the numbers defining the
+ * "Dhrystone distribution" (distribution of statements,
+ * operand types and locality) still hold. Except for
+ * sophisticated optimizing compilers, execution times for
+ * this version should be the same as for previous versions.
+ *
+ * Since it has proven difficult to subtract the time for the
+ * measurement loop overhead in a correct way, the loop check
+ * has been made a part of the benchmark. This does have
+ * an impact - though a very minor one - on the distribution
+ * statistics which have been updated for this version.
+ *
+ * All changes within the measurement loop are described
+ * and discussed in the companion paper "Rationale for
+ * Dhrystone version 2".
+ *
+ * Because of the self-imposed limitation that the order and
+ * distribution of the executed statements should not be
+ * changed, there are still cases where optimizing compilers
+ * may not generate code for some statements. To a certain
+ * degree, this is unavoidable for small synthetic
+ * benchmarks. Users of the benchmark are advised to check
+ * code listings whether code is generated for all statements
+ * of Dhrystone.
+ *
+ * Version 2.1 is identical to version 2.0 distributed via
+ * the UNIX network Usenet in March 1988 except that it
+ * corrects some minor deficiencies that were found by users
+ * of version 2.0. The only change within the measurement
+ * loop is that a non-executed "else" part was added to the
+ * "if" statement in Func_3, and a non-executed "else" part
+ * removed from Proc_3.
+ *
+ *************************************************************************
+ *
+ * Defines: The following "Defines" are possible:
+ * -DROPT (default: Not defined)
+ * As an approximation to what an average C
+ * programmer might do, the "register" storage class
+ * is applied (if enabled by -DROPT)
+ * - for local variables, if they are used
+ * (dynamically) five or more times
+ * - for parameters if they are used (dynamically)
+ * six or more times
+ * Note that an optimal "register" strategy is
+ * compiler-dependent, and that "register"
+ * declarations do not necessarily lead to faster
+ * execution.
+ * -DNOSTRUCTASSIGN (default: Not defined)
+ * Define if the C compiler does not support
+ * assignment of structures.
+ * -DNOENUMS (default: Not defined)
+ * Define if the C compiler does not support
+ * enumeration types.
+ *
+ *************************************************************************
+ *
+ * Compilation model and measurement (IMPORTANT):
+ *
+ * This C version of Dhrystone consists of three files:
+ * - dhry.h (this file, containing global definitions and comments)
+ * - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ * - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ *
+ * The following "ground rules" apply for measurements:
+ * - Separate compilation
+ * - No procedure merging
+ * - Otherwise, compiler optimizations are allowed but should be
+ * indicated
+ * - Default results are those without register declarations
+ * See the companion paper "Rationale for Dhrystone Version 2" for a more
+ * detailed discussion of these ground rules.
+ *
+ * For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ * models ("small", "medium", "large" etc.) should be given if possible,
+ * together with a definition of these models for the compiler system
+ * used.
+ *
+ *************************************************************************
+ *
+ * Dhrystone (C version) statistics:
+ *
+ * [Comment from the first distribution, updated for version 2.
+ * Note that because of language differences, the numbers are slightly
+ * different from the Ada version.]
+ *
+ * The following program contains statements of a high level programming
+ * language (here: C) in a distribution considered representative:
+ *
+ * assignments 52 (51.0 %)
+ * control statements 33 (32.4 %)
+ * procedure, function calls 17 (16.7 %)
+ *
+ * 103 statements are dynamically executed. The program is balanced with
+ * respect to the three aspects:
+ *
+ * - statement type
+ * - operand type
+ * - operand locality
+ * operand global, local, parameter, or constant.
+ *
+ * The combination of these three aspects is balanced only approximately.
+ *
+ * 1. Statement Type:
+ * ----------------- number
+ *
+ * V1 = V2 9
+ * (incl. V1 = F(..)
+ * V = Constant 12
+ * Assignment, 7
+ * with array element
+ * Assignment, 6
+ * with record component
+ * --
+ * 34 34
+ *
+ * X = Y +|-|"&&"|"|" Z 5
+ * X = Y +|-|"==" Constant 6
+ * X = X +|- 1 3
+ * X = Y *|/ Z 2
+ * X = Expression, 1
+ * two operators
+ * X = Expression, 1
+ * three operators
+ * --
+ * 18 18
+ *
+ * if .... 14
+ * with "else" 7
+ * without "else" 7
+ * executed 3
+ * not executed 4
+ * for ... 7 | counted every time
+ * while ... 4 | the loop condition
+ * do ... while 1 | is evaluated
+ * switch ... 1
+ * break 1
+ * declaration with 1
+ * initialization
+ * --
+ * 34 34
+ *
+ * P (...) procedure call 11
+ * user procedure 10
+ * library procedure 1
+ * X = F (...)
+ * function call 6
+ * user function 5
+ * library function 1
+ * --
+ * 17 17
+ * ---
+ * 103
+ *
+ * The average number of parameters in procedure or function calls
+ * is 1.82 (not counting the function values as implicit parameters).
+ *
+ *
+ * 2. Operators
+ * ------------
+ * number approximate
+ * percentage
+ *
+ * Arithmetic 32 50.8
+ *
+ * + 21 33.3
+ * - 7 11.1
+ * * 3 4.8
+ * / (int div) 1 1.6
+ *
+ * Comparison 27 42.8
+ *
+ * == 9 14.3
+ * /= 4 6.3
+ * > 1 1.6
+ * < 3 4.8
+ * >= 1 1.6
+ * <= 9 14.3
+ *
+ * Logic 4 6.3
+ *
+ * && (AND-THEN) 1 1.6
+ * | (OR) 1 1.6
+ * ! (NOT) 2 3.2
+ *
+ * -- -----
+ * 63 100.1
+ *
+ *
+ * 3. Operand Type (counted once per operand reference):
+ * ---------------
+ * number approximate
+ * percentage
+ *
+ * Integer 175 72.3 %
+ * Character 45 18.6 %
+ * Pointer 12 5.0 %
+ * String30 6 2.5 %
+ * Array 2 0.8 %
+ * Record 2 0.8 %
+ * --- -------
+ * 242 100.0 %
+ *
+ * When there is an access path leading to the final operand (e.g. a
+ * record component), only the final data type on the access path is
+ * counted.
+ *
+ *
+ * 4. Operand Locality:
+ * -------------------
+ * number approximate
+ * percentage
+ *
+ * local variable 114 47.1 %
+ * global variable 22 9.1 %
+ * parameter 45 18.6 %
+ * value 23 9.5 %
+ * reference 22 9.1 %
+ * function result 6 2.5 %
+ * constant 55 22.7 %
+ * --- -------
+ * 242 100.0 %
+ *
+ *
+ * The program does not compute anything meaningful, but it is
+ * syntactically and semantically correct. All variables have a value
+ * assigned to them before they are used as a source operand.
+ *
+ * There has been no explicit effort to account for the effects of a
+ * cache, or to balance the use of long or short displacements for code
+ * or data.
+ *
+ *************************************************************************
+ */
+
+/* Compiler and system dependent definitions: */
+
+#define Mic_secs_Per_Second 1000000.0
+ /* Berkeley UNIX C returns process times in seconds/HZ */
+
+#ifdef NOSTRUCTASSIGN
+#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s) d = s
+#endif
+
+#ifdef NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+ typedef int Enumeration;
+#else
+ typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+ Enumeration;
+#endif
+ /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+#include <stdio.h>
+ /* for strcpy, strcmp */
+
+#define Null 0
+ /* Value of a Null pointer */
+#define true 1
+#define false 0
+
+typedef int One_Thirty;
+typedef int One_Fifty;
+typedef char Capital_Letter;
+typedef int Boolean;
+typedef char Str_30 [31];
+typedef int Arr_1_Dim [50];
+typedef int Arr_2_Dim [50] [50];
+
+typedef struct record
+ {
+ struct record *Ptr_Comp;
+ Enumeration Discr;
+ union {
+ struct {
+ Enumeration Enum_Comp;
+ int Int_Comp;
+ char Str_Comp [31];
+ } var_1;
+ struct {
+ Enumeration E_Comp_2;
+ char Str_2_Comp [31];
+ } var_2;
+ struct {
+ char Ch_1_Comp;
+ char Ch_2_Comp;
+ } var_3;
+ } variant;
+ } Rec_Type, *Rec_Pointer;
+
+#ifdef __ECOS__
+
+#ifndef ROPT
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#else
+#define REG register
+#endif
+
+Boolean Func_2 (Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref);
+Boolean Func_3 (Enumeration Enum_Par_Val);
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
+void Proc_2 (One_Fifty* Int_Par_Ref);
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
+void Proc_4 (void);
+void Proc_5 (void);
+void Proc_6 (Enumeration Enum_Val_Par, Enumeration* Enum_Ref_Par);
+void Proc_7 (One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val,
+ One_Fifty* Int_Par_Ref);
+void Proc_8 (Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref,
+ int Int_1_Par_Val, int Int_2_Par_Val);
+Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val);
+
+#endif // __ECOS__
+
+/*
+ *************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_1.c (part 2 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ *************************************************************************
+ */
+
+#include <stdio.h>
+#ifndef __ECOS__
+#include "dhry.h"
+#endif // __ECOS__
+
+/* Global Variables: */
+
+Rec_Pointer Ptr_Glob,
+ Next_Ptr_Glob;
+int Int_Glob;
+Boolean Bool_Glob;
+char Ch_1_Glob,
+ Ch_2_Glob;
+int Arr_1_Glob [50];
+int Arr_2_Glob [50] [50];
+
+char Reg_Define[] = "Register option selected.";
+
+#ifndef __ECOS__
+extern char *malloc ();
+Enumeration Func_1 ();
+#endif
+ /*
+ forward declaration necessary since Enumeration may not simply be int
+ */
+
+#ifndef __ECOS__
+#ifndef ROPT
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#else
+#define REG register
+#endif
+#endif
+
+/* variables for time measurement: */
+
+#define Too_Small_Time 2
+ /* Measurements should last at least 2 seconds */
+
+double Begin_Time,
+ End_Time,
+ User_Time;
+
+double Microseconds,
+ Dhrystones_Per_Second,
+ Vax_Mips;
+
+/* end of variables for time measurement */
+
+
+#ifndef __ECOS__
+void main ()
+#else // __ECOS__
+int main (void)
+#endif // __ECOS__
+/*****/
+
+ /* main program, corresponds to procedures */
+ /* Main and Proc_0 in the Ada version */
+{
+#ifndef __ECOS__
+ double dtime();
+#endif // __ECOS__
+
+ One_Fifty Int_1_Loc;
+ REG One_Fifty Int_2_Loc;
+ One_Fifty Int_3_Loc;
+ REG char Ch_Index;
+ Enumeration Enum_Loc;
+ Str_30 Str_1_Loc;
+ Str_30 Str_2_Loc;
+ REG int Run_Index;
+ REG int Number_Of_Runs;
+
+
+#ifdef __ECOS__
+
+ CYG_TEST_INIT();
+
+#ifdef CYG_HAL_I386_LINUX
+ CYG_TEST_NA("Only runs on hardware...");
+#else
+ if (cyg_test_is_simulator)
+ CYG_TEST_NA("Only runs on hardware...");
+#endif
+
+#else // __ECOS__
+ FILE *Ap;
+
+ /* Initializations */
+
+ if ((Ap = fopen("dhry.res","a+")) == NULL)
+ {
+ printf("Can not open dhry.res\n\n");
+ exit(1);
+ }
+#endif // __ECOS__
+
+ Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+ Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+
+ Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
+ Ptr_Glob->Discr = Ident_1;
+ Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
+ Ptr_Glob->variant.var_1.Int_Comp = 40;
+ strcpy (Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING");
+ strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+ Arr_2_Glob [8][7] = 10;
+ /* Was missing in published program. Without this statement, */
+ /* Arr_2_Glob [8][7] would have an undefined value. */
+ /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
+ /* overflow may occur for this array element. */
+
+ printf ("\n");
+ printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+ printf ("\n");
+/*
+ if (Reg)
+ {
+ printf ("Program compiled with 'register' attribute\n");
+ printf ("\n");
+ }
+ else
+ {
+ printf ("Program compiled without 'register' attribute\n");
+ printf ("\n");
+ }
+*/
+#ifdef __ECOS__
+ Number_Of_Runs = PASSES;
+#else // __ECOS__
+ printf ("Please give the number of runs through the benchmark: ");
+ {
+ int n;
+ scanf ("%d", &n);
+ Number_Of_Runs = n;
+ }
+ printf ("\n");
+#endif // __ECOS__
+
+ printf ("Execution starts, %d runs through Dhrystone\n",Number_Of_Runs);
+
+ /***************/
+ /* Start timer */
+ /***************/
+
+ Begin_Time = dtime();
+
+ for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
+ {
+
+ Proc_5();
+ Proc_4();
+ /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+ Int_1_Loc = 2;
+ Int_2_Loc = 3;
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+ Enum_Loc = Ident_2;
+ Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+ /* Bool_Glob == 1 */
+ while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
+ {
+ Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+ /* Int_3_Loc == 7 */
+ Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+ /* Int_3_Loc == 7 */
+ Int_1_Loc += 1;
+ } /* while */
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+ /* Int_Glob == 5 */
+ Proc_1 (Ptr_Glob);
+ for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+ /* loop body executed twice */
+ {
+ if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+ /* then, not executed */
+ {
+ Proc_6 (Ident_1, &Enum_Loc);
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+ Int_2_Loc = Run_Index;
+ Int_Glob = Run_Index;
+ }
+ }
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Int_2_Loc = Int_2_Loc * Int_1_Loc;
+ Int_1_Loc = Int_2_Loc / Int_3_Loc;
+ Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+ /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+ Proc_2 (&Int_1_Loc);
+ /* Int_1_Loc == 5 */
+
+ } /* loop "for Run_Index" */
+
+ /**************/
+ /* Stop timer */
+ /**************/
+
+ End_Time = dtime();
+
+ printf ("Execution ends\n");
+ printf ("\n");
+ printf ("Final values of the variables used in the benchmark:\n");
+ printf ("\n");
+ printf ("Int_Glob: %d\n", Int_Glob);
+ printf (" should be: %d\n", 5);
+ printf ("Bool_Glob: %d\n", Bool_Glob);
+ printf (" should be: %d\n", 1);
+ printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
+ printf (" should be: %c\n", 'A');
+ printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
+ printf (" should be: %c\n", 'B');
+ printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
+ printf (" should be: %d\n", 7);
+ printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
+ printf (" should be: Number_Of_Runs + 10\n");
+ printf ("Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent)\n");
+ printf (" Discr: %d\n", Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 2);
+ printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 17);
+ printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Next_Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent), same as above\n");
+ printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 1);
+ printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 18);
+ printf (" Str_Comp: %s\n", Next_Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Int_1_Loc: %d\n", Int_1_Loc);
+ printf (" should be: %d\n", 5);
+ printf ("Int_2_Loc: %d\n", Int_2_Loc);
+ printf (" should be: %d\n", 13);
+ printf ("Int_3_Loc: %d\n", Int_3_Loc);
+ printf (" should be: %d\n", 7);
+ printf ("Enum_Loc: %d\n", Enum_Loc);
+ printf (" should be: %d\n", 1);
+ printf ("Str_1_Loc: %s\n", Str_1_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
+ printf ("Str_2_Loc: %s\n", Str_2_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
+ printf ("\n");
+
+ User_Time = End_Time - Begin_Time;
+
+ if (User_Time < Too_Small_Time)
+ {
+ printf ("Measured time too small to obtain meaningful results\n");
+ printf ("Please increase number of runs\n");
+ printf ("\n");
+ }
+ else
+ {
+ Microseconds = User_Time * Mic_secs_Per_Second
+ / (double) Number_Of_Runs;
+ Dhrystones_Per_Second = (double) Number_Of_Runs / User_Time;
+ Vax_Mips = Dhrystones_Per_Second / 1757.0;
+
+#ifdef ROPT
+ printf ("Register option selected? YES\n");
+#else
+ printf ("Register option selected? NO\n");
+#ifndef __ECOS__
+ strcpy(Reg_Define, "Register option not selected.");
+#endif // __ECOS__
+#endif
+ printf ("Microseconds for one run through Dhrystone: ");
+#ifdef __ECOS__
+ printf ("%7.1f \n", Microseconds);
+ printf ("Dhrystones per Second: ");
+ printf ("%10.1f \n", Dhrystones_Per_Second);
+ printf ("VAX MIPS rating = %10.3f \n",Vax_Mips);
+ printf ("\n");
+#else // __ECOS__
+ printf ("%7.1lf \n", Microseconds);
+ printf ("Dhrystones per Second: ");
+ printf ("%10.1lf \n", Dhrystones_Per_Second);
+ printf ("VAX MIPS rating = %10.3lf \n",Vax_Mips);
+ printf ("\n");
+
+ fprintf(Ap,"\n");
+ fprintf(Ap,"Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+ fprintf(Ap,"%s\n",Reg_Define);
+ fprintf(Ap,"Microseconds for one loop: %7.1lf\n",Microseconds);
+ fprintf(Ap,"Dhrystones per second: %10.1lf\n",Dhrystones_Per_Second);
+ fprintf(Ap,"VAX MIPS rating: %10.3lf\n",Vax_Mips);
+ fclose(Ap);
+#endif // __ECOS__
+ }
+
+#ifdef __ECOS__
+ CYG_TEST_PASS_FINISH("Dhrystone test");
+#endif // __ECOS__
+}
+
+
+#ifdef __ECOS__
+void
+#endif // __ECOS__
+Proc_1 (Ptr_Val_Par)
+/******************/
+
+REG Rec_Pointer Ptr_Val_Par;
+ /* executed once */
+{
+ REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
+ /* == Ptr_Glob_Next */
+ /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
+ /* corresponds to "rename" in Ada, "with" in Pascal */
+
+ structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
+ Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+ Next_Record->variant.var_1.Int_Comp
+ = Ptr_Val_Par->variant.var_1.Int_Comp;
+ Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+ Proc_3 (&Next_Record->Ptr_Comp);
+ /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
+ == Ptr_Glob->Ptr_Comp */
+ if (Next_Record->Discr == Ident_1)
+ /* then, executed */
+ {
+ Next_Record->variant.var_1.Int_Comp = 6;
+ Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
+ &Next_Record->variant.var_1.Enum_Comp);
+ Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+ Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
+ &Next_Record->variant.var_1.Int_Comp);
+ }
+ else /* not executed */
+ structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+} /* Proc_1 */
+
+
+#ifdef __ECOS__
+void
+#endif // __ECOS__
+Proc_2 (Int_Par_Ref)
+/******************/
+ /* executed once */
+ /* *Int_Par_Ref == 1, becomes 4 */
+
+One_Fifty *Int_Par_Ref;
+{
+ One_Fifty Int_Loc;
+#ifdef __ECOS__
+ Enumeration Enum_Loc = Ident_1;
+#else // __ECOS__
+ Enumeration Enum_Loc;
+#endif // __ECOS__
+
+ Int_Loc = *Int_Par_Ref + 10;
+ do /* executed once */
+ if (Ch_1_Glob == 'A')
+ /* then, executed */
+ {
+ Int_Loc -= 1;
+ *Int_Par_Ref = Int_Loc - Int_Glob;
+ Enum_Loc = Ident_1;
+ } /* if */
+ while (Enum_Loc != Ident_1); /* true */
+} /* Proc_2 */
+
+
+#ifdef __ECOS__
+void
+#endif // __ECOS__
+Proc_3 (Ptr_Ref_Par)
+/******************/
+ /* executed once */
+ /* Ptr_Ref_Par becomes Ptr_Glob */
+
+Rec_Pointer *Ptr_Ref_Par;
+
+{
+ if (Ptr_Glob != Null)
+ /* then, executed */
+ *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+ Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+} /* Proc_3 */
+
+
+#ifdef __ECOS__
+void
+#endif // __ECOS__
+Proc_4 () /* without parameters */
+/*******/
+ /* executed once */
+{
+ Boolean Bool_Loc;
+
+ Bool_Loc = Ch_1_Glob == 'A';
+ Bool_Glob = Bool_Loc | Bool_Glob;
+ Ch_2_Glob = 'B';
+} /* Proc_4 */
+
+
+#ifdef __ECOS__
+void
+#endif // __ECOS__
+Proc_5 () /* without parameters */
+/*******/
+ /* executed once */
+{
+ Ch_1_Glob = 'A';
+ Bool_Glob = false;
+} /* Proc_5 */
+
+
+ /* Procedure for the assignment of structures, */
+ /* if the C compiler doesn't support this feature */
+#ifdef NOSTRUCTASSIGN
+memcpy (d, s, l)
+register char *d;
+register char *s;
+register int l;
+{
+ while (l--) *d++ = *s++;
+}
+#endif
+
+/*
+ *************************************************************************
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_2.c (part 3 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ *************************************************************************
+ */
+
+#ifndef __ECOS__
+#include "dhry.h"
+
+#ifndef REG
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#else
+#define REG register
+#endif
+#endif // __ECOS__
+
+extern int Int_Glob;
+extern char Ch_1_Glob;
+
+#ifdef __ECOS__
+void
+#endif // __ECOS__
+Proc_6 (Enum_Val_Par, Enum_Ref_Par)
+/*********************************/
+ /* executed once */
+ /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+
+Enumeration Enum_Val_Par;
+Enumeration *Enum_Ref_Par;
+{
+ *Enum_Ref_Par = Enum_Val_Par;
+ if (! Func_3 (Enum_Val_Par))
+ /* then, not executed */
+ *Enum_Ref_Par = Ident_4;
+ switch (Enum_Val_Par)
+ {
+ case Ident_1:
+ *Enum_Ref_Par = Ident_1;
+ break;
+ case Ident_2:
+ if (Int_Glob > 100)
+ /* then */
+ *Enum_Ref_Par = Ident_1;
+ else *Enum_Ref_Par = Ident_4;
+ break;
+ case Ident_3: /* executed */
+ *Enum_Ref_Par = Ident_2;
+ break;
+ case Ident_4: break;
+ case Ident_5:
+ *Enum_Ref_Par = Ident_3;
+ break;
+ } /* switch */
+} /* Proc_6 */
+
+
+#ifdef __ECOS__
+void
+#endif // __ECOS__
+Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
+/**********************************************/
+ /* executed three times */
+ /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
+ /* Int_Par_Ref becomes 7 */
+ /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+ /* Int_Par_Ref becomes 17 */
+ /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+ /* Int_Par_Ref becomes 18 */
+One_Fifty Int_1_Par_Val;
+One_Fifty Int_2_Par_Val;
+One_Fifty *Int_Par_Ref;
+{
+ One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 2;
+ *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+} /* Proc_7 */
+
+
+#ifdef __ECOS__
+void
+#endif // __ECOS__
+Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
+/*********************************************************************/
+ /* executed once */
+ /* Int_Par_Val_1 == 3 */
+ /* Int_Par_Val_2 == 7 */
+Arr_1_Dim Arr_1_Par_Ref;
+Arr_2_Dim Arr_2_Par_Ref;
+int Int_1_Par_Val;
+int Int_2_Par_Val;
+{
+ REG One_Fifty Int_Index;
+ REG One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 5;
+ Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+ Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+ Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+ for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+ Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+ Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+ Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+ Int_Glob = 5;
+} /* Proc_8 */
+
+
+Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
+/*************************************************/
+ /* executed three times */
+ /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
+ /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
+ /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
+
+Capital_Letter Ch_1_Par_Val;
+Capital_Letter Ch_2_Par_Val;
+{
+ Capital_Letter Ch_1_Loc;
+ Capital_Letter Ch_2_Loc;
+
+ Ch_1_Loc = Ch_1_Par_Val;
+ Ch_2_Loc = Ch_1_Loc;
+ if (Ch_2_Loc != Ch_2_Par_Val)
+ /* then, executed */
+ return (Ident_1);
+ else /* not executed */
+ {
+ Ch_1_Glob = Ch_1_Loc;
+ return (Ident_2);
+ }
+} /* Func_1 */
+
+
+Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
+/*************************************************/
+ /* executed once */
+ /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+ /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+
+Str_30 Str_1_Par_Ref;
+Str_30 Str_2_Par_Ref;
+{
+ REG One_Thirty Int_Loc;
+#ifdef __ECOS__
+ Capital_Letter Ch_Loc = 'A';
+#else // __ECOS__
+ Capital_Letter Ch_Loc;
+#endif // __ECOS__
+
+ Int_Loc = 2;
+ while (Int_Loc <= 2) /* loop body executed once */
+ if (Func_1 (Str_1_Par_Ref[Int_Loc],
+ Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+ /* then, executed */
+ {
+ Ch_Loc = 'A';
+ Int_Loc += 1;
+ } /* if, while */
+ if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+ /* then, not executed */
+ Int_Loc = 7;
+ if (Ch_Loc == 'R')
+ /* then, not executed */
+ return (true);
+ else /* executed */
+ {
+ if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+ /* then, not executed */
+ {
+ Int_Loc += 7;
+ Int_Glob = Int_Loc;
+ return (true);
+ }
+ else /* executed */
+ return (false);
+ } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean Func_3 (Enum_Par_Val)
+/***************************/
+ /* executed once */
+ /* Enum_Par_Val == Ident_3 */
+Enumeration Enum_Par_Val;
+{
+ Enumeration Enum_Loc;
+
+ Enum_Loc = Enum_Par_Val;
+ if (Enum_Loc == Ident_3)
+ /* then, executed */
+ return (true);
+ else /* not executed */
+ return (false);
+} /* Func_3 */
+
+#else /* ifndef NA_MSG */
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(NA_MSG);
+}
+#endif
diff --git a/cesar/ecos/packages/kernel/current/tests/except1.cxx b/cesar/ecos/packages/kernel/current/tests/except1.cxx
new file mode 100644
index 0000000000..4736bd3286
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/except1.cxx
@@ -0,0 +1,271 @@
+//=================================================================
+//
+// except1.cxx
+//
+// Exception test 1
+//
+//=================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//=================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm, jlarmour
+// Date: 1999-02-16
+// Description: Test basic exception functionality
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGPKG_KERNEL_EXCEPTIONS
+
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+#include <cyg/kernel/intr.hxx> // cyg_VSR
+
+#include <cyg/hal/hal_intr.h> // exception ranges
+
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/thread.inl>
+
+#define NTHREADS 1
+#include "testaux.hxx"
+
+#ifndef CYGPKG_HAL_ARM_PID
+#define EXCEPTION_DATA_ACCESS
+#endif
+
+static int d0;
+#ifdef EXCEPTION_DATA_ACCESS
+static cyg_exception_handler handler0;
+
+static void handler0(CYG_ADDRWORD data, cyg_code number, CYG_ADDRWORD info)
+{
+ CYG_TEST_INFO("handler 0 called");
+
+ CYG_TEST_CHECK((CYG_ADDRWORD)123 == data, "handler given wrong data");
+
+ // ignore machine specific stuff
+ CYG_UNUSED_PARAM(cyg_code, number);
+ CYG_UNUSED_PARAM(CYG_ADDRWORD, info);
+
+ CYG_TEST_PASS_FINISH("Except 1 OK");
+}
+#endif
+
+static void handler1(CYG_ADDRWORD data, cyg_code number, CYG_ADDRWORD info)
+{
+ CYG_TEST_INFO("handler 1 called");
+
+ CYG_TEST_CHECK((CYG_ADDRWORD)&d0 == data, "handler given wrong data");
+
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
+ CYG_TEST_CHECK(number == CYGNUM_HAL_EXCEPTION_MAX, "handler given wrong number");
+#else
+ CYG_UNUSED_PARAM(cyg_code, number);
+#endif
+
+ CYG_TEST_CHECK((CYG_ADDRWORD)99 == info, "handler given wrong info");
+}
+
+#ifdef EXCEPTION_DATA_ACCESS
+// The following function attempts to cause an exception in various
+// hacky ways. It is machine dependent what exception is generated.
+// It does reads rather than writes hoping not to corrupt anything
+// important.
+static int
+cause_fpe(int num)
+{
+ double a;
+
+ a = 1.0/num; // Depending on FPU emulation and/or
+ // the FPU architecture, this may
+ // cause an exception.
+ // (float division by zero)
+
+ return ((int)a)/num; // This may cause an exception if
+ // the architecture supports it.
+ // (integer division by zero).
+} // cause_fpe()
+
+void cause_exception(void)
+{
+ int x;
+ unsigned int p=0;
+
+ // First try for an address exception (unaligned access exception
+ // or SEGV/BUS exceptions)
+ do {
+ x=*(volatile int *)(p-1);
+ p+=0x100000;
+ } while(p != 0);
+
+ // Next try an integer or floating point divide-by-zero exception.
+ cause_fpe(0);
+}
+#endif
+
+static void entry0( CYG_ADDRWORD data )
+{
+#ifdef EXCEPTION_DATA_ACCESS
+ cyg_code n;
+#endif
+ cyg_exception_handler *old_handler, *old_handler1;
+ CYG_ADDRWORD old_data, old_data1;
+ Cyg_Thread *p=Cyg_Thread::self();
+
+ CYG_UNUSED_PARAM(CYG_ADDRESS, data);
+
+ p->register_exception(
+ CYGNUM_HAL_EXCEPTION_MAX,
+ &handler1,
+ (CYG_ADDRWORD)&d0,
+ &old_handler,
+ &old_data);
+
+ p->register_exception(
+ CYGNUM_HAL_EXCEPTION_MAX,
+ &handler1,
+ (CYG_ADDRWORD)&d0,
+ &old_handler1,
+ &old_data1);
+
+ CYG_TEST_CHECK(old_handler1 == &handler1,
+ "register exception: old_handler not the one previously registered");
+ CYG_TEST_CHECK(old_data1 == (CYG_ADDRWORD)&d0,
+ "register exception: old_data not those previously registered");
+
+ p->deliver_exception(CYGNUM_HAL_EXCEPTION_MAX, (CYG_ADDRWORD)99);
+
+ CYG_TEST_INFO("handler 1 returned");
+
+ p->deregister_exception(CYGNUM_HAL_EXCEPTION_MAX);
+ p->deregister_exception(CYGNUM_HAL_EXCEPTION_MAX);
+
+#ifdef EXCEPTION_DATA_ACCESS
+
+#if 0
+#elif defined(CYGPKG_HAL_POWERPC_SIM)
+ // The exception generated by the SIM is not recognized by GDB.
+ // PR 19945 workaround.
+ CYG_TEST_NA("Not applicable to PowerPC SIM");
+#endif
+
+ for(n = CYGNUM_HAL_EXCEPTION_MIN; n <= CYGNUM_HAL_EXCEPTION_MAX; n++) {
+ p->register_exception(
+ n,
+ handler0,
+ (CYG_ADDRWORD)123,
+ &old_handler1,
+ &old_data1);
+ }
+
+ CYG_TEST_PASS("Attempting to provoke exception");
+
+ cause_exception();
+
+ CYG_TEST_FAIL_FINISH("Couldn't cause exception");
+#else // EXCEPTION_DATA_ACCESS
+ CYG_TEST_NA("Platform does not support data exceptions");
+#endif
+
+}
+
+#ifdef CYG_HAL_MIPS_TX39_JMR3904
+
+externC cyg_VSR __default_exception_vsr;
+cyg_VSR *old_vsr;
+
+#endif
+
+void except0_main( void )
+{
+ // Use CYG_TEST_GDBCMD _before_ CYG_TEST_INIT()
+ CYG_TEST_GDBCMD("handle SIGBUS nostop");
+ CYG_TEST_GDBCMD("handle SIGSEGV nostop");
+ CYG_TEST_GDBCMD("handle SIGFPE nostop");
+
+ CYG_TEST_INIT();
+
+#ifdef HAL_VSR_SET_TO_ECOS_HANDLER
+ // Reclaim the VSR off CygMon possibly
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_ACCESS, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_FPU, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO, NULL );
+#endif
+#endif
+
+ new_thread(entry0, 0);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ except0_main();
+}
+#else // def CYGPKG_KERNEL_EXCEPTIONS
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Exceptions disabled");
+}
+#endif // def CYGPKG_KERNEL_EXCEPTIONS
+
+// EOF except1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/flag0.cxx b/cesar/ecos/packages/kernel/current/tests/flag0.cxx
new file mode 100644
index 0000000000..aeb4b3c3cc
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/flag0.cxx
@@ -0,0 +1,88 @@
+//==========================================================================
+//
+// flag0.cxx
+//
+// Flag test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-05-11
+// Description: Limited to checking constructors/destructors
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/flag.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include "testaux.hxx"
+
+static Cyg_Flag f0, f1;
+
+
+static bool flash( void )
+{
+ Cyg_Flag f0;
+
+ Cyg_Flag f1;
+
+ return true;
+}
+
+void flag0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ CYG_TEST_PASS_FINISH("Flag 0 OK");
+
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ flag0_main();
+}
+// EOF flag0.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/flag1.cxx b/cesar/ecos/packages/kernel/current/tests/flag1.cxx
new file mode 100644
index 0000000000..17274a197c
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/flag1.cxx
@@ -0,0 +1,219 @@
+//==========================================================================
+//
+// flag1.cxx
+//
+// Flag test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author: dsm
+// Contributors: dsm
+// Date: 1998-05-11
+// Description: Tests basic flag functionality.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+
+#include <cyg/kernel/flag.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+
+#define NTHREADS 3
+#include "testaux.hxx"
+
+static Cyg_Flag f0, f1;
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+static Cyg_Flag f2;
+#endif
+
+static volatile cyg_atomic q = 0;
+#define FIRST_THREAD_WAIT_TIME 5
+#define SECOND_THREAD_WAIT_TIME 10
+#define THIRD_THREAD_WAIT_TIME 20
+
+static void entry0( CYG_ADDRWORD data )
+{
+ CYG_TEST_INFO("Testing setbits() and maskbits()");
+ CYG_TEST_CHECK(0==f0.peek(), "flag not initialized properly");
+ f0.setbits(0x1);
+ CYG_TEST_CHECK(1==f0.peek(), "setbits");
+ f0.setbits(0x3);
+ CYG_TEST_CHECK(3==f0.peek(), "setbits");
+ f0.maskbits(~0x5);
+ CYG_TEST_CHECK(2==f0.peek(), "maskbits");
+ f0.setbits();
+ CYG_TEST_CHECK(~0u==f0.peek(), "setbits no arg");
+ f0.maskbits();
+ CYG_TEST_CHECK(0==f0.peek(), "maskbits no arg");
+ CYG_TEST_CHECK(0==q++, "bad synchronization");
+
+ CYG_TEST_INFO("Testing wait()");
+ f1.setbits(0x4);
+ CYG_TEST_CHECK(0x4==f1.peek(), "maskbits no arg");
+ CYG_TEST_CHECK(1==q++, "bad synchronization");
+ f1.setbits(0x18); // wake t1
+ f1.wait(0x11, Cyg_Flag::AND | Cyg_Flag::CLR);
+ CYG_TEST_CHECK(0==f1.peek(), "flag value wrong");
+ CYG_TEST_CHECK(3==q++, "bad synchronization");
+ f0.setbits(0x2); // wake t1
+ f1.wait(0x10, Cyg_Flag::AND );
+ f0.setbits(0x1); // wake t1
+
+ f1.wait(0x11, Cyg_Flag::AND | Cyg_Flag::CLR);
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ f2.wait(0x2, Cyg_Flag::OR);
+ CYG_TEST_CHECK(20==q,"bad synchronization");
+ f2.wait(0x10, Cyg_Flag::AND,
+ Cyg_Clock::real_time_clock->current_value()+THIRD_THREAD_WAIT_TIME);
+ CYG_TEST_CHECK(21==q++,"bad synchronization");
+#endif
+ f0.wait(1, Cyg_Flag::OR);
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ f1.wait(0xc, Cyg_Flag::AND);
+ CYG_TEST_CHECK(2==q++, "bad synchronization");
+ CYG_TEST_CHECK(0x1c==f1.peek(), "flag value wrong");
+ f1.setbits(0x1); // wake t0
+ f0.wait(0x3, Cyg_Flag::OR);
+ CYG_TEST_CHECK(4==q++, "bad synchronization");
+ CYG_TEST_CHECK(2==f0.peek(), "flag value wrong");
+
+ f1.setbits(0xf0); // wake t0,t2
+ f0.wait(0x5, Cyg_Flag::AND | Cyg_Flag::CLR); // wait for t0 & t2
+ CYG_TEST_CHECK(0==f0.peek(), "flag value wrong");
+ CYG_TEST_CHECK(0xf0==f1.peek(), "flag value wrong");
+ CYG_TEST_CHECK(5==q++, "bad synchronization");
+ f1.maskbits();
+ CYG_TEST_CHECK(0==f1.peek(), "flag value wrong");
+
+ CYG_TEST_INFO("Testing poll()");
+ f0.setbits(0x55);
+ CYG_TEST_CHECK(0x55==f0.peek(), "flag value wrong");
+ CYG_TEST_CHECK(0x55==f0.poll(0x3, Cyg_Flag::OR),"bad poll() return");
+ CYG_TEST_CHECK(0==f0.poll(0xf, Cyg_Flag::AND),"poll()");
+ CYG_TEST_CHECK(0==f0.poll(0xa, Cyg_Flag::OR),"poll()");
+ CYG_TEST_CHECK(0x55==f0.peek(), "flag value wrong");
+ CYG_TEST_CHECK(0x55==f0.poll(0xf, Cyg_Flag::OR | Cyg_Flag::CLR),"poll");
+ CYG_TEST_CHECK(0x0==f0.peek(), "flag value wrong");
+ f0.setbits(0x50);
+ CYG_TEST_CHECK(0x50==f0.poll(0x10, Cyg_Flag::AND | Cyg_Flag::CLR),"poll");
+ CYG_TEST_CHECK(0x0==f0.peek(), "flag value wrong");
+
+ CYG_TEST_INFO("Testing waiting()");
+ f0.maskbits();
+ CYG_TEST_CHECK(!f0.waiting(), "waiting()");
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ thread[1]->delay( 10 ); // allow other threads to reach wait on f1
+ CYG_TEST_CHECK(f1.waiting(), "waiting() not true");
+ f1.setbits(); // wake one of t0,t2
+ CYG_TEST_CHECK(f1.waiting(), "waiting() not true");
+#else
+ f1.setbits(0x11); // wake one of t0,t2
+#endif
+ f1.setbits(0x11); // wake other of t0,t2
+ CYG_TEST_CHECK(!f1.waiting(), "waiting not false");
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ CYG_TEST_INFO("Testing wait() with timeout");
+ q=20;
+ f2.setbits(0x2); // synchronize with t0,t2
+ CYG_TEST_CHECK(20==q,"bad synchronization");
+ f2.wait(0x20, Cyg_Flag::AND,
+ Cyg_Clock::real_time_clock->current_value()+SECOND_THREAD_WAIT_TIME);
+ CYG_TEST_CHECK(22==q++,"bad synchronization");
+#endif
+
+ CYG_TEST_PASS_FINISH("Flag 1 OK");
+}
+
+static void entry2( CYG_ADDRWORD data )
+{
+ f1.wait(0x60, Cyg_Flag::OR);
+ f0.setbits(0x4);
+
+ f1.wait(0x11, Cyg_Flag::AND | Cyg_Flag::CLR);
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ f2.wait(0x2, Cyg_Flag::OR);
+ CYG_TEST_CHECK(20==q,"bad synchronization");
+ CYG_TEST_CHECK(0==f2.wait(0x40, Cyg_Flag::AND,
+ Cyg_Clock::real_time_clock->current_value()+FIRST_THREAD_WAIT_TIME),
+ "timed wait() wrong");
+ CYG_TEST_CHECK(20==q++,"bad synchronization");
+ // Now wake t0 before it times out
+ f2.setbits(0x10);
+#endif
+ f0.wait(1, Cyg_Flag::OR);
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+void flag1_main( void )
+{
+ CYG_TEST_INIT();
+
+ new_thread(entry0, 0);
+ new_thread(entry1, 1);
+ new_thread(entry2, 2);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ flag1_main();
+}
+
+// EOF flag1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/fptest.c b/cesar/ecos/packages/kernel/current/tests/fptest.c
new file mode 100644
index 0000000000..f455c8b3b3
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/fptest.c
@@ -0,0 +1,364 @@
+//==========================================================================
+//
+// fptest.cxx
+//
+// Basic FPU test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Nick Garnett
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg@calivar.com
+// Contributors: nickg@calivar.com
+// Date: 2003-01-27
+// Description: Simple FPU test. This is not very sophisticated as far
+// as checking FPU performance or accuracy. It is more
+// concerned with checking that several threads doing FP
+// operations do not interfere with eachother's use of the
+// FPU.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+//#include <cyg/kernel/test/stackmon.h>
+//#include CYGHWR_MEMORY_LAYOUT_H
+
+//==========================================================================
+
+#if defined(CYGFUN_KERNEL_API_C) && \
+ defined(CYGSEM_KERNEL_SCHED_MLQUEUE) && \
+ (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
+
+//==========================================================================
+// Base priority for all threads.
+
+#define BASE_PRI 5
+
+//==========================================================================
+// Runtime
+//
+// This is the number of ticks that the program will run for. 3000
+// ticks is equal to 30 seconds in the default configuration. For
+// simulators we reduce the run time to 3 simulated seconds.
+
+#define RUN_TICKS 3000
+#define RUN_TICKS_SIM 300
+
+//==========================================================================
+// Thread parameters
+
+#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_MINIMUM)
+
+static cyg_uint8 stacks[3][STACK_SIZE];
+static cyg_handle_t thread[3];
+static cyg_thread thread_struct[3];
+
+//==========================================================================
+// Alarm parameters.
+
+static cyg_alarm alarm_struct;
+static cyg_handle_t alarm;
+
+static cyg_count8 cur_thread = 0;
+static cyg_count32 alarm_ticks = 0;
+static cyg_count32 run_ticks = RUN_TICKS;
+
+//==========================================================================
+
+static int errors = 0;
+
+//==========================================================================
+// Random number generator. Ripped out of the C library.
+
+static int rand( unsigned int *seed )
+{
+// This is the code supplied in Knuth Vol 2 section 3.6 p.185 bottom
+
+#define RAND_MAX 0x7fffffff
+#define MM 2147483647 // a Mersenne prime
+#define AA 48271 // this does well in the spectral test
+#define QQ 44488 // (long)(MM/AA)
+#define RR 3399 // MM % AA; it is important that RR<QQ
+
+ *seed = AA*(*seed % QQ) - RR*(unsigned int)(*seed/QQ);
+ if (*seed < 0)
+ *seed += MM;
+
+ return (int)( *seed & RAND_MAX );
+}
+
+//==========================================================================
+// Test calculation.
+//
+// Generates an array of random FP values and then repeatedly applies
+// a calculation to them and checks that the same result is reached
+// each time. The calculation, in the macro CALC, is intended to make
+// maximum use of the FPU registers. However, the i386 compiler
+// doesn't let this expression get very complex before it starts
+// spilling values out to memory.
+
+static void do_test( double *values,
+ int count,
+ int loops,
+ int test,
+ const char *name)
+{
+ unsigned int i, j;
+ // volatiles necessary to force
+ // values to 64 bits for comparison
+ volatile double sum = 1.0;
+ volatile double last_sum;
+ unsigned int seed;
+
+#define V(__i) (values[(__i)%count])
+#define CALC ((V(i-1)*V(i+1))*(V(i-2)*V(i+2))*(V(i-3)*sum))
+
+ seed = ((unsigned int)&i)*count;
+
+ // Set up an array of values...
+ for( i = 0; i < count; i++ )
+ values[i] = (double)rand( &seed )/(double)0x7fffffff;
+
+ // Now calculate something from them...
+ for( i = 0; i < count; i++ )
+ sum += CALC;
+ last_sum = sum;
+
+ // Now recalculate the sum in a loop and look for errors
+ for( j = 0; j < loops ; j++ )
+ {
+ sum = 1.0;
+ for( i = 0; i < count; i++ )
+ sum += CALC;
+
+ if( sum != last_sum )
+ {
+ union double_int_union {
+ double d;
+ cyg_uint32 i[2];
+ } diu_sum, diu_lastsum;
+
+ diu_sum.d = sum;
+ diu_lastsum.d = last_sum;
+
+ errors++;
+ if (sizeof(double) != 2*sizeof(cyg_uint32)) {
+ diag_printf("Warning: sizeof(double) != 2*sizeof(cyg_uint32), therefore next line may\n"
+ "have invalid sum/last_sum values\n");
+ }
+ diag_printf("%s: Sum mismatch! %d sum=[%08x:%08x] last_sum=[%08x:%08x]\n",
+ name,j, diu_sum.i[0], diu_sum.i[1], diu_lastsum.i[0], diu_lastsum.i[1] );
+ }
+
+#if 0
+ if( ((j*count)%1000000) == 0 )
+ diag_printf("INFO:<%s: %2d calculations done>\n",name,j*count);
+#endif
+ }
+
+}
+
+//==========================================================================
+// Alarm handler
+//
+// This is called every tick. It lowers the priority of the currently
+// running thread and raises the priority of the next. Thus we
+// implement a form of timelslicing between the threads at one tick
+// granularity.
+
+static void alarm_fn(cyg_handle_t alarm, cyg_addrword_t data)
+{
+ alarm_ticks++;
+
+ if( alarm_ticks >= run_ticks )
+ {
+ if( errors )
+ CYG_TEST_FAIL("Errors detected");
+ else
+ CYG_TEST_PASS("OK");
+
+ CYG_TEST_FINISH("FP Test done");
+ }
+ else
+ {
+ cyg_thread_set_priority( thread[cur_thread], BASE_PRI );
+
+ cur_thread = (cur_thread+1)%3;
+
+ cyg_thread_set_priority( thread[cur_thread], BASE_PRI-1 );
+ }
+}
+
+
+//==========================================================================
+
+#define FP1_COUNT 1000
+
+static double fpt1_values[FP1_COUNT];
+
+void fptest1( CYG_ADDRWORD id )
+{
+ while(1)
+ do_test( fpt1_values, FP1_COUNT, 2000000000, id, "fptest1" );
+}
+
+//==========================================================================
+
+#define FP2_COUNT 10000
+
+static double fpt2_values[FP2_COUNT];
+
+void fptest2( CYG_ADDRWORD id )
+{
+ while(1)
+ do_test( fpt2_values, FP2_COUNT, 2000000000, id, "fptest2" );
+}
+
+//==========================================================================
+
+#define FP3_COUNT 100
+
+static double fpt3_values[FP3_COUNT];
+
+void fptest3( CYG_ADDRWORD id )
+{
+ while(1)
+ do_test( fpt3_values, FP3_COUNT, 2000000000, id, "fptest3" );
+}
+
+//==========================================================================
+
+void fptest_main( void )
+{
+
+ CYG_TEST_INIT();
+
+ if( cyg_test_is_simulator )
+ {
+ run_ticks = RUN_TICKS_SIM;
+ }
+
+ CYG_TEST_INFO("Run fptest in cyg_start");
+ do_test( fpt3_values, FP3_COUNT, 1000, 0, "start" );
+ CYG_TEST_INFO( "cyg_start run done");
+
+ cyg_thread_create( BASE_PRI-1,
+ fptest1,
+ 0,
+ "fptest1",
+ &stacks[0][0],
+ STACK_SIZE,
+ &thread[0],
+ &thread_struct[0]);
+
+ cyg_thread_resume( thread[0] );
+
+ cyg_thread_create( BASE_PRI,
+ fptest2,
+ 1,
+ "fptest2",
+ &stacks[1][0],
+ STACK_SIZE,
+ &thread[1],
+ &thread_struct[1]);
+
+ cyg_thread_resume( thread[1] );
+
+ cyg_thread_create( BASE_PRI,
+ fptest3,
+ 2,
+ "fptest3",
+ &stacks[2][0],
+ STACK_SIZE,
+ &thread[2],
+ &thread_struct[2]);
+
+ cyg_thread_resume( thread[2] );
+
+ cyg_alarm_create( cyg_real_time_clock(),
+ alarm_fn,
+ 0,
+ &alarm,
+ &alarm_struct );
+
+ cyg_alarm_initialize( alarm, cyg_current_time()+1, 1 );
+
+ cyg_scheduler_start();
+
+}
+
+//==========================================================================
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ fptest_main();
+}
+
+//==========================================================================
+
+#else // CYGFUN_KERNEL_API_C...
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("FP test requires:\n"
+ "CYGFUN_KERNEL_API_C && \n"
+ "CYGSEM_KERNEL_SCHED_MLQUEUE && \n"
+ "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n");
+ CYG_TEST_NA("FP test requirements");
+}
+
+#endif // CYGFUN_KERNEL_API_C, etc.
+
+//==========================================================================
+// EOF fptest.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/intr0.cxx b/cesar/ecos/packages/kernel/current/tests/intr0.cxx
new file mode 100644
index 0000000000..f2be469e3b
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/intr0.cxx
@@ -0,0 +1,209 @@
+//=================================================================
+//
+// intr0.cxx
+//
+// Interrupt test 0
+//
+//=================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//=================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm, jlarmour
+// Date: 1999-02-16
+// Description: Very basic test of interrupt objects
+// Options:
+// CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE
+// CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE
+// CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/intr.hxx>
+#include <cyg/hal/hal_intr.h>
+
+#include <cyg/infra/testcase.h>
+
+#include "testaux.hxx"
+
+static cyg_ISR isr0, isr1;
+static cyg_DSR dsr0, dsr1;
+
+static char intr0_obj[sizeof(Cyg_Interrupt)];
+static char intr1_obj[sizeof(Cyg_Interrupt)];
+
+static cyg_uint32 isr0(cyg_vector vector, CYG_ADDRWORD data)
+{
+ CYG_UNUSED_PARAM(CYG_ADDRWORD, data);
+
+ Cyg_Interrupt::acknowledge_interrupt(vector);
+ return 0;
+}
+
+static void dsr0(cyg_vector vector, cyg_ucount32 count, CYG_ADDRWORD data)
+{
+ CYG_UNUSED_PARAM(cyg_vector, vector);
+ CYG_UNUSED_PARAM(cyg_ucount32, count);
+ CYG_UNUSED_PARAM(CYG_ADDRWORD, data);
+}
+
+static cyg_uint32 isr1(cyg_vector vector, CYG_ADDRWORD data)
+{
+ CYG_UNUSED_PARAM(cyg_vector, vector);
+ CYG_UNUSED_PARAM(CYG_ADDRWORD, data);
+ return 0;
+}
+
+static void dsr1(cyg_vector vector, cyg_ucount32 count, CYG_ADDRWORD data)
+{
+ CYG_UNUSED_PARAM(cyg_vector, vector);
+ CYG_UNUSED_PARAM(cyg_ucount32, count);
+ CYG_UNUSED_PARAM(CYG_ADDRWORD, data);
+}
+
+static bool flash( void )
+{
+ Cyg_Interrupt intr0 = Cyg_Interrupt(CYGNUM_HAL_ISR_MIN, 0, (CYG_ADDRWORD)333, isr0, dsr0 );
+
+ return true;
+}
+
+/* IMPORTANT: The calling convention for VSRs is target dependent. It is
+ * unlikely that a plain C or C++ routine would function correctly on any
+ * particular platform, even if it could correctly access the system
+ * resources necessary to handle the event that caused it to be called.
+ * VSRs usually must be written in assembly language.
+ *
+ * This is just a test program. The routine vsr0() below is defined simply
+ * to define an address that will be in executable memory. If an event
+ * causes this VSR to be called, all bets are off. If it is accidentally
+ * installed in the vector for the realtime clock, the system will likely
+ * freeze.
+ */
+
+static cyg_VSR vsr0;
+
+static void vsr0()
+{
+}
+
+void intr0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ // Make sure the chosen levels are not already in use.
+ int in_use;
+ cyg_vector lvl1 = CYGNUM_HAL_ISR_MIN + (1 % CYGNUM_HAL_ISR_COUNT);
+ HAL_INTERRUPT_IN_USE( lvl1, in_use );
+ Cyg_Interrupt* intr0 = NULL;
+ if (!in_use)
+ intr0 = new((void *)&intr0_obj[0]) Cyg_Interrupt( lvl1, 1, (CYG_ADDRWORD)777, isr0, dsr0 );
+
+ cyg_vector lvl2 = CYGNUM_HAL_ISR_MIN + ( 15 % CYGNUM_HAL_ISR_COUNT);
+ HAL_INTERRUPT_IN_USE( lvl2, in_use );
+ Cyg_Interrupt* intr1 = NULL;
+ if (!in_use && lvl1 != lvl2)
+ intr1 = new((void *)&intr1_obj[0]) Cyg_Interrupt( lvl2, 1, 888, isr1, dsr1 );
+
+ // Check these functions at least exist
+ Cyg_Interrupt::disable_interrupts();
+ Cyg_Interrupt::enable_interrupts();
+
+ if (intr0)
+ intr0->attach();
+ if (intr1)
+ intr1->attach();
+ if (intr0)
+ intr0->detach();
+ if (intr1)
+ intr1->detach();
+
+ // If this attaching interrupt replaces the previous interrupt
+ // instead of adding to it we could be in a big mess if the
+ // vector is being used by something important.
+
+ cyg_vector v = (CYGNUM_HAL_VSR_MIN + 11) % CYGNUM_HAL_VSR_COUNT;
+ cyg_VSR *old_vsr, *new_vsr;
+ Cyg_Interrupt::set_vsr( v, vsr0, &old_vsr );
+ Cyg_Interrupt::get_vsr( v, &new_vsr );
+ CHECK( vsr0 == new_vsr );
+
+ new_vsr = NULL;
+ Cyg_Interrupt::set_vsr( v, old_vsr, &new_vsr );
+ CHECK( new_vsr == vsr0 );
+
+ Cyg_Interrupt::set_vsr( v, new_vsr );
+ new_vsr = NULL;
+ Cyg_Interrupt::get_vsr( v, &new_vsr );
+ CHECK( vsr0 == new_vsr );
+
+ Cyg_Interrupt::set_vsr( v, old_vsr );
+ CHECK( vsr0 == new_vsr );
+ new_vsr = NULL;
+ Cyg_Interrupt::get_vsr( v, &new_vsr );
+ CHECK( old_vsr == new_vsr );
+
+ CHECK( NULL != vsr0 );
+
+ cyg_vector v1;
+#ifdef CYGPKG_HAL_MIPS_TX39
+ // This can be removed when PR 17831 is fixed
+ if ( cyg_test_is_simulator )
+ v1 = 12 % CYGNUM_HAL_ISR_COUNT;
+ else /* NOTE TRAILING ELSE... */
+#endif
+ v1 = CYGNUM_HAL_ISR_MIN + (6 % CYGNUM_HAL_ISR_COUNT);
+
+ Cyg_Interrupt::mask_interrupt(v1);
+ Cyg_Interrupt::unmask_interrupt(v1);
+
+ Cyg_Interrupt::configure_interrupt(v1, true, true);
+
+ CYG_TEST_PASS_FINISH("Intr 0 OK");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ intr0_main();
+}
+// EOF intr0.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/kalarm0.c b/cesar/ecos/packages/kernel/current/tests/kalarm0.c
new file mode 100644
index 0000000000..d3d27e3097
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kalarm0.c
@@ -0,0 +1,191 @@
+//==========================================================================
+//
+// kalarm0
+//
+// Alarm functionality test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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 the
+// copyright holders.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2003-06-25
+// Description: Tests the ability of alarms to be added and removed by the
+// alarm functions of other alarms.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+//==========================================================================
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \
+ defined(CYGFUN_KERNEL_API_C)
+
+#include "testaux.h"
+
+//==========================================================================
+
+//#define db_printf diag_printf
+#define db_printf( fmt, ... )
+
+//==========================================================================
+
+static cyg_counter counter_obj;
+static cyg_handle_t counter;
+static cyg_alarm alarm_obj[3];
+static cyg_handle_t alarm[3];
+
+static cyg_uint32 alarmfn_called[3];
+
+//==========================================================================
+
+void alarmfn0(cyg_handle_t alarmh, cyg_addrword_t data)
+{
+ db_printf("%s: %d\n",__PRETTY_FUNCTION__,cyg_counter_current_value( counter ));
+
+ // alarmfn0 just counts how many times it has been called
+
+ alarmfn_called[0]++;
+}
+
+//==========================================================================
+
+void alarmfn1(cyg_handle_t alarmh, cyg_addrword_t data)
+{
+ db_printf("%s: %d\n",__PRETTY_FUNCTION__,cyg_counter_current_value( counter ));
+
+ alarmfn_called[1]++;
+
+ // Reschedule alarm[0] to run every tick until alarm[2] next runs.
+
+ cyg_alarm_initialize( alarm[0], cyg_counter_current_value( counter )+1, 1 );
+
+}
+
+//==========================================================================
+
+void alarmfn2(cyg_handle_t alarmh, cyg_addrword_t data)
+{
+ db_printf("%s: %d\n",__PRETTY_FUNCTION__,cyg_counter_current_value( counter ));
+
+ alarmfn_called[2]++;
+
+ // Reschedule alarm[0] to run every 2 ticks until alarm[1] next runs.
+
+ cyg_alarm_initialize( alarm[0], cyg_counter_current_value( counter )+1, 2 );
+
+ // Reschedule alarm[1] to run every 3 ticks starting in 6 ticks time.
+
+ cyg_alarm_initialize( alarm[1], cyg_counter_current_value( counter )+6, 3 );
+}
+
+//==========================================================================
+
+void alarm0_main(void)
+{
+ int i;
+
+ CYG_TEST_INIT();
+
+ // Create the counter
+ cyg_counter_create( &counter, &counter_obj );
+
+ // Create the alarms
+ cyg_alarm_create( counter,
+ alarmfn0,
+ 0,
+ &alarm[0],
+ &alarm_obj[0]);
+
+
+ cyg_alarm_create( counter,
+ alarmfn1,
+ 1,
+ &alarm[1],
+ &alarm_obj[1]);
+
+ cyg_alarm_create( counter,
+ alarmfn2,
+ 2,
+ &alarm[2],
+ &alarm_obj[2]);
+
+
+ // Kick it all off by starting alarm[2]
+ cyg_alarm_initialize( alarm[2], 0, 10 );
+
+ // Run the whole thing for 10000 ticks
+ for( i = 0; i < 10000; i++ )
+ cyg_counter_tick( counter );
+
+ db_printf("alarmfn_called: %d %d %d\n",
+ alarmfn_called[0],alarmfn_called[1],alarmfn_called[2]);
+
+ CYG_TEST_CHECK( alarmfn_called[0]==5000, "alarmfn0 not called 5000 times\n");
+ CYG_TEST_CHECK( alarmfn_called[1]==2000, "alarmfn1 not called 2000 times\n");
+ CYG_TEST_CHECK( alarmfn_called[2]==1001, "alarmfn2 not called 1001 times\n");
+
+ CYG_TEST_PASS_FINISH("KAlarm0");
+}
+
+//==========================================================================
+
+externC void
+cyg_start( void )
+{
+ alarm0_main();
+}
+
+//==========================================================================
+
+#else
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( "This test needs CYGVAR_KERNEL_COUNTERS_CLOCK "
+ "and CYGFUN_KERNEL_API_C" );
+}
+
+#endif
+
+//==========================================================================
+// End of kalarm0.c
diff --git a/cesar/ecos/packages/kernel/current/tests/kcache1.c b/cesar/ecos/packages/kernel/current/tests/kcache1.c
new file mode 100644
index 0000000000..dbb82a0c76
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kcache1.c
@@ -0,0 +1,422 @@
+/*=================================================================
+//
+// kcache1.c
+//
+// Cache timing test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm, nickg
+// Date: 1998-06-18
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/hal/hal_cache.h>
+
+#if defined(HAL_DCACHE_SIZE) || defined(HAL_UCACHE_SIZE)
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+#ifdef CYGFUN_KERNEL_API_C
+
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_intr.h>
+
+// -------------------------------------------------------------------------
+// If the HAL does not supply this, we supply our own version
+
+#ifndef HAL_DCACHE_PURGE_ALL
+# ifdef HAL_DCACHE_SYNC
+
+#define HAL_DCACHE_PURGE_ALL() HAL_DCACHE_SYNC()
+
+# else
+
+static cyg_uint8 dca[HAL_DCACHE_SIZE + HAL_DCACHE_LINE_SIZE*2];
+
+#define HAL_DCACHE_PURGE_ALL() \
+CYG_MACRO_START \
+ volatile cyg_uint8 *addr = &dca[HAL_DCACHE_LINE_SIZE]; \
+ volatile cyg_uint8 tmp = 0; \
+ int i; \
+ for( i = 0; i < HAL_DCACHE_SIZE; i += HAL_DCACHE_LINE_SIZE ) \
+ { \
+ tmp = addr[i]; \
+ } \
+CYG_MACRO_END
+
+# endif
+#endif
+
+// -------------------------------------------------------------------------
+
+#define NTHREADS 1
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+#ifndef MAX_STRIDE
+#define MAX_STRIDE 64
+#endif
+
+volatile char m[(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE)*MAX_STRIDE];
+
+// -------------------------------------------------------------------------
+
+static void time0(register cyg_uint32 stride)
+{
+ register cyg_uint32 j,k;
+ cyg_tick_count_t count0, count1;
+ cyg_ucount32 t;
+ register char c;
+
+ count0 = cyg_current_time();
+
+ k = 0;
+ if ( cyg_test_is_simulator )
+ k = 3960;
+
+ for(; k<4000;k++) {
+ for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) {
+ c=m[stride*j];
+ }
+ }
+
+ count1 = cyg_current_time();
+ t = count1 - count0;
+ diag_printf("stride=%d, time=%d\n", stride, t);
+}
+
+// -------------------------------------------------------------------------
+
+void time1(void)
+{
+ cyg_uint32 i;
+
+ for(i=1; i<=MAX_STRIDE; i+=i) {
+ time0(i);
+ }
+}
+
+// -------------------------------------------------------------------------
+// With an ICache invalidate in the middle:
+#ifdef HAL_ICACHE_INVALIDATE_ALL
+static void time0II(register cyg_uint32 stride)
+{
+ register cyg_uint32 j,k;
+ cyg_tick_count_t count0, count1;
+ cyg_ucount32 t;
+ register char c;
+
+ count0 = cyg_current_time();
+
+ k = 0;
+ if ( cyg_test_is_simulator )
+ k = 3960;
+
+ for(; k<4000;k++) {
+ for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) {
+ HAL_ICACHE_INVALIDATE_ALL();
+ c=m[stride*j];
+ }
+ }
+
+ count1 = cyg_current_time();
+ t = count1 - count0;
+ diag_printf("stride=%d, time=%d\n", stride, t);
+}
+
+// -------------------------------------------------------------------------
+
+void time1II(void)
+{
+ cyg_uint32 i;
+
+ for(i=1; i<=MAX_STRIDE; i+=i) {
+ time0II(i);
+ }
+}
+#endif
+// -------------------------------------------------------------------------
+// With a DCache invalidate in the middle:
+// This is guaranteed to produce bogus timing results since interrupts
+// have to be disabled to prevent accidental loss of state.
+#ifdef HAL_DCACHE_INVALIDATE_ALL
+static void time0DI(register cyg_uint32 stride)
+{
+ register cyg_uint32 j,k;
+ volatile cyg_tick_count_t count0;
+ cyg_tick_count_t count1;
+ cyg_ucount32 t;
+ register char c;
+ register CYG_INTERRUPT_STATE oldints;
+
+ count0 = cyg_current_time();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+
+ k = 0;
+ if ( cyg_test_is_simulator )
+ k = 3960;
+
+ for(; k<4000;k++) {
+ for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) {
+ HAL_DCACHE_INVALIDATE_ALL();
+ c=m[stride*j];
+ }
+ }
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ count1 = cyg_current_time();
+ t = count1 - count0;
+ diag_printf("stride=%d, time=%d\n", stride, t);
+}
+
+// -------------------------------------------------------------------------
+
+void time1DI(void)
+{
+ cyg_uint32 i;
+
+ for(i=1; i<=MAX_STRIDE; i+=i) {
+ time0DI(i);
+ }
+}
+#endif
+// -------------------------------------------------------------------------
+// This test could be improved by counting number of passes possible
+// in a given number of ticks.
+
+static void entry0( cyg_addrword_t data )
+{
+ register CYG_INTERRUPT_STATE oldints;
+
+#ifdef HAL_CACHE_UNIFIED
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL(); // rely on above definition
+ HAL_UCACHE_INVALIDATE_ALL();
+ HAL_UCACHE_DISABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Cache off");
+ time1();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL(); // rely on above definition
+ HAL_UCACHE_INVALIDATE_ALL();
+ HAL_UCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Cache on");
+ time1();
+
+#ifdef HAL_DCACHE_INVALIDATE_ALL
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_UCACHE_INVALIDATE_ALL();
+ HAL_UCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Cache on: invalidate Cache (expect bogus timing)");
+ time1DI();
+#endif
+
+#else // HAL_CACHE_UNIFIED
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_DISABLE();
+ HAL_DCACHE_DISABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache off Icache off");
+ time1();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_DISABLE();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache on Icache off");
+ time1();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_ENABLE();
+ HAL_DCACHE_DISABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache off Icache on");
+ time1();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_ENABLE();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache on Icache on");
+ time1();
+
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_DISABLE();
+ HAL_DCACHE_DISABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache off Icache off (again)");
+ time1();
+
+#if defined(HAL_DCACHE_INVALIDATE_ALL) || defined(HAL_ICACHE_INVALIDATE_ALL)
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_ENABLE();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache on Icache on (again)");
+ time1();
+
+#if defined(CYGPKG_HAL_MIPS)
+ // In some architectures, the time taken for the next two tests is
+ // very long, partly because HAL_XCACHE_INVALIDATE_ALL() is implemented
+ // with a loop over the cache. Hence these tests take longer than the
+ // testing infrastructure is prepared to wait. The simplest way to get
+ // these tests to run quickly is to make them think they are running
+ // under a simulator.
+ // If the target actually is a simulator, skip the below - it's very
+ // slow on the simulator, even with reduced loop counts.
+ if (cyg_test_is_simulator)
+ CYG_TEST_PASS_FINISH("End of test");
+
+#if defined(CYGPKG_HAL_MIPS_TX49)
+ // The TX49 has a large cache, and even with reduced loop count,
+ // 90+ seconds elapses between each INFO output.
+ CYG_TEST_PASS_FINISH("End of test");
+#endif
+
+ cyg_test_is_simulator = 1;
+#endif
+
+#ifdef HAL_ICACHE_INVALIDATE_ALL
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_ENABLE();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache on Icache on: invalidate ICache each time");
+ time1II();
+#endif
+#ifdef HAL_DCACHE_INVALIDATE_ALL
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_ENABLE();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache on Icache on: invalidate DCache (expect bogus times)");
+ time1DI();
+#endif
+#endif // either INVALIDATE_ALL macro
+
+#endif // HAL_CACHE_UNIFIED
+
+ CYG_TEST_PASS_FINISH("End of test");
+}
+
+// -------------------------------------------------------------------------
+
+void kcache2_main( void )
+{
+ CYG_TEST_INIT();
+
+ cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "kcache1",
+ (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
+ cyg_thread_resume(thread[0]);
+
+ cyg_scheduler_start();
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ kcache2_main();
+}
+
+// -------------------------------------------------------------------------
+
+#else // def CYGFUN_KERNEL_API_C
+#define N_A_MSG "Kernel C API layer disabled"
+#endif // def CYGFUN_KERNEL_API_C
+#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
+#define N_A_MSG "Kernel real-time clock disabled"
+#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
+#else // def HAL_DCACHE_SIZE
+#define N_A_MSG "No caches defined"
+#endif // def HAL_DCACHE_SIZE
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG
+
+// -------------------------------------------------------------------------
+/* EOF kcache1.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/kcache2.c b/cesar/ecos/packages/kernel/current/tests/kcache2.c
new file mode 100644
index 0000000000..da200d0fb9
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kcache2.c
@@ -0,0 +1,920 @@
+/*=================================================================
+//
+// kcache2.c
+//
+// Cache feature/timing tests
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, based on kcache1.c by dsm
+// Contributors: jskov, gthomas
+// Date: 1998-12-10
+// Description: Tests some of the more exotic cache macros.
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+#ifdef CYGFUN_KERNEL_API_C
+
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_cache.h>
+
+// -------------------------------------------------------------------------
+
+#define NTHREADS 1
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+// The following are defaults for loop variables. Note they will be overriden
+// on simulator targets, where detected - there is no point testing a cache
+// which doesn't exist :-).
+
+#define TEST_DZERO_LOOPS 5000 // default number of loops for test_dzero()
+#define TIME_ILOCK_LOOPS 10000 // default number of loops for time_ilock()
+#define TIME_DLOCK_LOOPS 10000 // default number of loops for time_dlock()
+
+// Define this to enable a simple, but hopefully useful, data cache
+// test. It may help discover if the cache support has been defined
+// properly (in terms of size and shape)
+#ifdef HAL_DCACHE_LINE_SIZE
+#define _TEST_DCACHE_OPERATION
+#endif
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+#define MAXSIZE 1<<18
+
+volatile char m[MAXSIZE];
+
+// -------------------------------------------------------------------------
+// Test of data cache zero.
+// o Timing comparison with instructions doing the same amount of work.
+// o Check that area cleared with the DCACHE_ZERO macro contains zeros.
+#ifdef HAL_DCACHE_ZERO
+static void test_dzero(void)
+{
+ register cyg_uint32 k, i;
+ cyg_tick_count_t count0, count1;
+ cyg_ucount32 t;
+ volatile cyg_uint32* aligned_p;
+ volatile cyg_uint32* p;
+ register CYG_INTERRUPT_STATE oldints;
+ cyg_ucount32 test_dzero_loops = TEST_DZERO_LOOPS;
+
+ CYG_TEST_INFO("Data cache zero");
+
+ if (cyg_test_is_simulator)
+ test_dzero_loops=10;
+
+ aligned_p = (volatile cyg_uint32*)
+ (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
+ & ~(HAL_DCACHE_LINE_SIZE-1));
+
+ // Time with conventional instructions.
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ count0 = cyg_current_time();
+ for (k = 0; k < test_dzero_loops; k++) {
+ p = aligned_p;
+ for (i = 0; i < HAL_DCACHE_SETS; i++) {
+#if (16 == HAL_DCACHE_LINE_SIZE)
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+#elif (32 == HAL_DCACHE_LINE_SIZE)
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 0;
+#else
+#error "Not defined for this cache line size."
+#endif
+ }
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ }
+ count1 = cyg_current_time();
+ t = count1 - count0;
+ diag_printf("time with instructions: %d\n", t);
+
+ // Initialize the area with non-zero so we can check whether
+ // the macro cleared the area properly.
+ p = aligned_p;
+ for (i = 0;
+ i < HAL_DCACHE_SETS*HAL_DCACHE_LINE_SIZE/sizeof(cyg_uint32);
+ i++) {
+ *p++ = 0xdeadbeef;
+ }
+
+ // Time with DCACHE_ZERO.
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ count0 = cyg_current_time();
+ for (k = 0; k < test_dzero_loops; k++) {
+ HAL_DCACHE_ZERO(aligned_p, HAL_DCACHE_SETS*HAL_DCACHE_LINE_SIZE);
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ }
+ count1 = cyg_current_time();
+ t = count1 - count0;
+ diag_printf("time with HAL_DCACHE_ZERO: %d\n", t);
+
+ // Verify that the area was actually cleared.
+ {
+ cyg_uint32 d;
+
+ d = 0;
+ p = aligned_p;
+ for (i = 0;
+ i < HAL_DCACHE_SETS*HAL_DCACHE_LINE_SIZE/sizeof(cyg_uint32);
+ i++) {
+ d |= *p++;
+ }
+
+ CYG_TEST_CHECK(0 == d, "region not properly cleared");
+ }
+
+}
+#endif
+
+// -------------------------------------------------------------------------
+// Test of data cache write hint.
+// Just check that the macro compiles.
+#ifdef HAL_DCACHE_WRITE_HINT
+static void test_dwrite_hint(void)
+{
+ register cyg_uint32 k;
+ register CYG_INTERRUPT_STATE oldints;
+
+ CYG_TEST_INFO("Data cache write hint");
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ HAL_DCACHE_WRITE_HINT(&m[HAL_DCACHE_LINE_SIZE*2], 2*HAL_DCACHE_LINE_SIZE);
+ for (k = 0; k < 20; k++);
+ m[HAL_DCACHE_LINE_SIZE*2] = 42;
+}
+#endif
+
+// -------------------------------------------------------------------------
+// Test of data cache read hint.
+// Just check that the macro compiles.
+#ifdef HAL_DCACHE_READ_HINT
+static void test_dread_hint(void)
+{
+ register char c;
+ register cyg_uint32 k;
+ register CYG_INTERRUPT_STATE oldints;
+
+ CYG_TEST_INFO("Data cache read hint");
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ HAL_DCACHE_READ_HINT(&m[HAL_DCACHE_LINE_SIZE*2], 2*HAL_DCACHE_LINE_SIZE);
+ for (k = 0; k < 20; k++);
+ c = m[HAL_DCACHE_LINE_SIZE*2];
+}
+#endif
+
+// -------------------------------------------------------------------------
+// Test of data cache line store
+// o No semantic requirement.
+// o Check that flushed data is written to memory.
+// o Simple invocation check of macro.
+#ifdef HAL_DCACHE_STORE
+static void test_dstore(void)
+{
+ volatile cyg_uint8* aligned_p;
+ cyg_int32 i;
+ register CYG_INTERRUPT_STATE oldints;
+
+ CYG_TEST_INFO("Data cache store region");
+
+ for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
+ m[i] = 0;
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+
+ aligned_p = (volatile cyg_uint8*)
+ (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
+ & ~(HAL_DCACHE_LINE_SIZE-1));
+
+ aligned_p[0] = 42 + aligned_p[1]; // Load causes cache to be used!
+
+ HAL_DCACHE_STORE(aligned_p, HAL_DCACHE_LINE_SIZE);
+
+ CYG_TEST_CHECK(42 == aligned_p[0],
+ "memory didn't contain flushed data");
+
+ HAL_DCACHE_INVALIDATE_ALL(); // Discard...
+
+ CYG_TEST_CHECK(42 == aligned_p[0],
+ "memory didn't contain flushed data after invalidate all");
+
+ HAL_RESTORE_INTERRUPTS(oldints);
+}
+#endif
+
+// -------------------------------------------------------------------------
+// Test of data cache total flush (sync).
+// o No semantic requirement.
+// o Check that flushed data is written to memory.
+// o Simple invocation check of macro.
+#ifdef HAL_DCACHE_LINE_SIZE // So we can find our way around memory
+
+#ifdef _TEST_DCACHE_OPERATION
+static void
+test_dcache_operation(void)
+{
+ long *lp = (long *)m;
+ int i, errs;
+ cyg_uint32 oldints;
+
+ CYG_TEST_INFO("Data cache basic");
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ // Fill test buffer
+ for (i = 0; i < sizeof(m)/sizeof(*lp); i++) {
+ lp[i] = i;
+ }
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ // Now push data through the cache
+ // Note: 256 seems like a reasonable offset. It may be useful to actually
+ // compute this (and the size of the test region) based on cache geometry
+ for (i = 256; i < 256+HAL_DCACHE_SIZE/sizeof(*lp); i++) {
+ lp[i] = 0xFF000000 + i;
+ }
+ // Now force cache clean and off
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ // Verify the data
+ diag_printf("Verify data with cache off\n");
+ errs = 0;
+ for (i = 0; i < sizeof(m)/sizeof(*lp); i++) {
+ if ((i >= 256) && (i < 256+HAL_DCACHE_SIZE/sizeof(*lp))) {
+ if (lp[i] != (0xFF000000 + i)) {
+ if (++errs < 16) {
+ diag_printf("Data inside test range changed - was: %x, is %lx, index: %x\n",
+ 0xFF000000+i, lp[i], i);
+ }
+ }
+ } else {
+ if (lp[i] != i) {
+ if (++errs < 16) {
+ diag_printf("Data outside test range changed - was: %x, is %lx, index: %x\n",
+ i, lp[i], i);
+ }
+ }
+ }
+ }
+ CYG_TEST_CHECK(0 == errs, "dcache basic failed");
+#if 0 // Additional information
+ diag_printf("%d total errors during compare\n", errs);
+ diag_dump_buf(&lp[240], 128);
+#endif
+ HAL_RESTORE_INTERRUPTS(oldints);
+}
+#endif
+
+static void test_dsync(void)
+{
+ volatile cyg_uint8* aligned_p;
+ cyg_int32 i;
+ register CYG_INTERRUPT_STATE oldints;
+
+ CYG_TEST_INFO("Data cache sync all");
+
+ for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
+ m[i] = 0;
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+
+ aligned_p = (volatile cyg_uint8*)
+ (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
+ & ~(HAL_DCACHE_LINE_SIZE-1));
+
+ aligned_p[0] = 42 + aligned_p[1]; // Load causes cache to be used!
+ aligned_p[HAL_DCACHE_LINE_SIZE] = 43 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
+
+ HAL_DCACHE_SYNC();
+
+ CYG_TEST_CHECK(42 == aligned_p[0],
+ "memory didn't contain flushed data");
+ CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE],
+ "memory didn't contain flushed data next block");
+
+ HAL_DCACHE_INVALIDATE_ALL();
+
+ CYG_TEST_CHECK(42 == aligned_p[0],
+ "memory didn't contain flushed data after invalidate");
+ CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE],
+ "memory didn't contain flushed data next block after invalidate");
+
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_DISABLE();
+
+ CYG_TEST_CHECK(42 == aligned_p[0],
+ "memory didn't contain flushed data after disable");
+ CYG_TEST_CHECK(43 == aligned_p[HAL_DCACHE_LINE_SIZE],
+ "memory didn't contain flushed data next block after disable");
+
+ HAL_DCACHE_ENABLE();
+}
+#endif // HAL_DCACHE_LINE_SIZE
+
+// -------------------------------------------------------------------------
+// Test of data cache line flush.
+// o Requires write-back cache.
+// o Check that flushed data is written to memory.
+// o Simple range check of macro.
+#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
+#ifdef HAL_DCACHE_FLUSH
+static void test_dflush(void)
+{
+ volatile cyg_uint8* aligned_p;
+ cyg_int32 i;
+ register CYG_INTERRUPT_STATE oldints;
+
+ CYG_TEST_INFO("Data cache flush region");
+
+ for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
+ m[i] = 0;
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ aligned_p = (volatile cyg_uint8*)
+ (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
+ & ~(HAL_DCACHE_LINE_SIZE-1));
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+
+ aligned_p[0] = 42 + aligned_p[1]; // Load causes cache to be used!
+ aligned_p[HAL_DCACHE_LINE_SIZE] = 43 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
+
+ HAL_DCACHE_FLUSH(aligned_p, HAL_DCACHE_LINE_SIZE);
+
+ HAL_DCACHE_DISABLE();
+
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ CYG_TEST_CHECK(42 == aligned_p[0],
+ "memory didn't contain flushed data");
+ CYG_TEST_CHECK(0 == aligned_p[HAL_DCACHE_LINE_SIZE],
+ "flushed beyond region");
+
+ HAL_DCACHE_ENABLE();
+}
+#endif
+#endif
+
+// -------------------------------------------------------------------------
+// Test of data cache disable (which does NOT force contents out to RAM)
+// o Requires write-back cache [so NOT invoked unconditionally]
+// o Check that dirty data is not written to memory and is invalidated
+// in the cache.
+// o Simple invocation check of macro.
+#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
+static void test_ddisable(void)
+{
+ volatile cyg_uint8* aligned_p;
+ cyg_int32 i;
+ register CYG_INTERRUPT_STATE oldints;
+
+ CYG_TEST_INFO("Data cache gross disable");
+
+ for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
+ m[i] = 0;
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ aligned_p = (volatile cyg_uint8*)
+ (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
+ & ~(HAL_DCACHE_LINE_SIZE-1));
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+
+ aligned_p[0] = 43 + aligned_p[1]; // Load causes cache to be used!
+ aligned_p[HAL_DCACHE_LINE_SIZE-1] = 43;
+
+ aligned_p[HAL_DCACHE_LINE_SIZE] = 42 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
+
+ HAL_DCACHE_DISABLE();
+
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ CYG_TEST_CHECK(0 == aligned_p[0] &&
+ 0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
+ "cache/memory contained invalidated data");
+ CYG_TEST_CHECK(0 == aligned_p[HAL_DCACHE_LINE_SIZE],
+ "next block contained invalidated data");
+
+ HAL_DCACHE_ENABLE();
+}
+#endif // def HAL_DCACHE_QUERY_WRITE_MODE
+
+// -------------------------------------------------------------------------
+// Test of data cache total invalidate.
+// o Requires write-back cache.
+// o Check that invalidated data is not written to memory and is invalidated
+// in the cache.
+// o Simple invocation check of macro.
+#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
+#ifdef HAL_DCACHE_INVALIDATE_ALL
+static void test_dinvalidate_all(void)
+{
+ volatile cyg_uint8* aligned_p;
+ cyg_int32 i;
+ register CYG_INTERRUPT_STATE oldints;
+
+ CYG_TEST_INFO("Data cache invalidate all");
+
+ for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
+ m[i] = 0;
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+
+ aligned_p = (volatile cyg_uint8*)
+ (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
+ & ~(HAL_DCACHE_LINE_SIZE-1));
+
+ aligned_p[0] = 43 + aligned_p[1]; // Load causes cache to be used!
+ aligned_p[HAL_DCACHE_LINE_SIZE-1] = 43;
+
+ aligned_p[HAL_DCACHE_LINE_SIZE] = 42 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
+
+ HAL_DCACHE_INVALIDATE_ALL();
+
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ CYG_TEST_CHECK(0 == aligned_p[0] &&
+ 0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
+ "cache/memory contained invalidated data");
+ CYG_TEST_CHECK(0 == aligned_p[HAL_DCACHE_LINE_SIZE],
+ "next block contained invalidated data");
+}
+#endif
+#endif // def HAL_DCACHE_QUERY_WRITE_MODE
+
+// -------------------------------------------------------------------------
+// Test of data cache line invalidate.
+// o Requires write-back cache.
+// o Check that invalidated data is not written to memory and is invalidated
+// in the cache.
+// o Simple range check of macro.
+#ifdef HAL_DCACHE_QUERY_WRITE_MODE // only if we know this, can we test:
+#ifdef HAL_DCACHE_INVALIDATE
+static void test_dinvalidate(void)
+{
+ volatile cyg_uint8* aligned_p;
+ cyg_int32 i;
+ register CYG_INTERRUPT_STATE oldints;
+
+ CYG_TEST_INFO("Data cache invalidate region");
+
+ for (i = 0; i < HAL_DCACHE_LINE_SIZE*16; i++)
+ m[i] = 0;
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ aligned_p = (volatile cyg_uint8*)
+ (((unsigned long) &m[HAL_DCACHE_LINE_SIZE*2])
+ & ~(HAL_DCACHE_LINE_SIZE-1));
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+
+ aligned_p[0] = 43 + aligned_p[1]; // Load causes cache to be used!
+ aligned_p[HAL_DCACHE_LINE_SIZE-1] = 43;
+
+ aligned_p[HAL_DCACHE_LINE_SIZE] = 42 + aligned_p[HAL_DCACHE_LINE_SIZE + 1];
+
+ HAL_DCACHE_INVALIDATE(aligned_p, HAL_DCACHE_LINE_SIZE);
+
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ CYG_TEST_CHECK(0 == aligned_p[0] &&
+ 0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
+ "cache/memory contained invalidated data");
+ CYG_TEST_CHECK(42 == aligned_p[HAL_DCACHE_LINE_SIZE],
+ "invalidated beyond range");
+
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+
+ CYG_TEST_CHECK(0 == aligned_p[0] &&
+ 0 == aligned_p[HAL_DCACHE_LINE_SIZE-1],
+ "cache/memory contained invalidated data after SYNC/DIS");
+ CYG_TEST_CHECK(42 == aligned_p[HAL_DCACHE_LINE_SIZE],
+ "invalidated beyond range after SYNC/DIS");
+
+ HAL_DCACHE_ENABLE();
+}
+#endif
+#endif // def HAL_DCACHE_QUERY_WRITE_MODE
+
+// -------------------------------------------------------------------------
+// Test of instruction cache locking.
+// o Time difference between repeatedly executing a bunch of instructions
+// with and without locking.
+#ifdef HAL_ICACHE_LOCK
+static void iloop(unsigned long* start, unsigned long* end, int dummy)
+{
+ // dummy is just used to fool the compiler to not move the labels
+ // around. All callers should call with dummy=0;
+
+ register char c;
+ register CYG_INTERRUPT_STATE oldints;
+
+ if (1 == dummy) goto label_end;
+
+ label_start:
+ // Invalidating shouldn't affect locked lines.
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_ICACHE_DISABLE();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_ICACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+
+ c = m[HAL_DCACHE_LINE_SIZE*0];
+ c = m[HAL_DCACHE_LINE_SIZE*1];
+ c = m[HAL_DCACHE_LINE_SIZE*2];
+ c = m[HAL_DCACHE_LINE_SIZE*3];
+ c = m[HAL_DCACHE_LINE_SIZE*4];
+ c = m[HAL_DCACHE_LINE_SIZE*5];
+ c = m[HAL_DCACHE_LINE_SIZE*6];
+ c = m[HAL_DCACHE_LINE_SIZE*7];
+ c = m[HAL_DCACHE_LINE_SIZE*8];
+ c = m[HAL_DCACHE_LINE_SIZE*9];
+ c = m[HAL_DCACHE_LINE_SIZE*10];
+ c = m[HAL_DCACHE_LINE_SIZE*11];
+ c = m[HAL_DCACHE_LINE_SIZE*12];
+ c = m[HAL_DCACHE_LINE_SIZE*13];
+ c = m[HAL_DCACHE_LINE_SIZE*14];
+ c = m[HAL_DCACHE_LINE_SIZE*15];
+ c = m[HAL_DCACHE_LINE_SIZE*16];
+ c = m[HAL_DCACHE_LINE_SIZE*17];
+ c = m[HAL_DCACHE_LINE_SIZE*18];
+ c = m[HAL_DCACHE_LINE_SIZE*19];
+ c = m[HAL_DCACHE_LINE_SIZE*20];
+ c = m[HAL_DCACHE_LINE_SIZE*21];
+ c = m[HAL_DCACHE_LINE_SIZE*22];
+ c = m[HAL_DCACHE_LINE_SIZE*23];
+ c = m[HAL_DCACHE_LINE_SIZE*24];
+ c = m[HAL_DCACHE_LINE_SIZE*25];
+ c = m[HAL_DCACHE_LINE_SIZE*26];
+ c = m[HAL_DCACHE_LINE_SIZE*27];
+ c = m[HAL_DCACHE_LINE_SIZE*28];
+ c = m[HAL_DCACHE_LINE_SIZE*29];
+ c = m[HAL_DCACHE_LINE_SIZE*30];
+ c = m[HAL_DCACHE_LINE_SIZE*31];
+ c = m[HAL_DCACHE_LINE_SIZE*32];
+ c = m[HAL_DCACHE_LINE_SIZE*33];
+ c = m[HAL_DCACHE_LINE_SIZE*34];
+ c = m[HAL_DCACHE_LINE_SIZE*35];
+ c = m[HAL_DCACHE_LINE_SIZE*36];
+ c = m[HAL_DCACHE_LINE_SIZE*37];
+ c = m[HAL_DCACHE_LINE_SIZE*38];
+ c = m[HAL_DCACHE_LINE_SIZE*39];
+ c = m[HAL_DCACHE_LINE_SIZE*40];
+ c = m[HAL_DCACHE_LINE_SIZE*41];
+ c = m[HAL_DCACHE_LINE_SIZE*42];
+ c = m[HAL_DCACHE_LINE_SIZE*43];
+ c = m[HAL_DCACHE_LINE_SIZE*44];
+ c = m[HAL_DCACHE_LINE_SIZE*45];
+ c = m[HAL_DCACHE_LINE_SIZE*46];
+ c = m[HAL_DCACHE_LINE_SIZE*47];
+ c = m[HAL_DCACHE_LINE_SIZE*48];
+ c = m[HAL_DCACHE_LINE_SIZE*49];
+ c = m[HAL_DCACHE_LINE_SIZE*50];
+ c = m[HAL_DCACHE_LINE_SIZE*51];
+ c = m[HAL_DCACHE_LINE_SIZE*52];
+ c = m[HAL_DCACHE_LINE_SIZE*53];
+ c = m[HAL_DCACHE_LINE_SIZE*54];
+ c = m[HAL_DCACHE_LINE_SIZE*55];
+ c = m[HAL_DCACHE_LINE_SIZE*56];
+ c = m[HAL_DCACHE_LINE_SIZE*57];
+ c = m[HAL_DCACHE_LINE_SIZE*58];
+ c = m[HAL_DCACHE_LINE_SIZE*59];
+ c = m[HAL_DCACHE_LINE_SIZE*60];
+ c = m[HAL_DCACHE_LINE_SIZE*61];
+ c = m[HAL_DCACHE_LINE_SIZE*62];
+ c = m[HAL_DCACHE_LINE_SIZE*63];
+
+ label_end:
+
+ *start = (unsigned long) &&label_start;
+ *end = (unsigned long) &&label_end;
+
+ if (1 == dummy) goto label_start;
+}
+
+static void time_ilock(void)
+{
+ register cyg_ucount32 k;
+ cyg_tick_count_t count0, count1;
+ cyg_ucount32 t;
+ unsigned long start, end;
+ register cyg_ucount32 time_ilock_loops = TIME_ILOCK_LOOPS;
+
+ CYG_TEST_INFO("Instruction cache lock");
+
+ if (cyg_test_is_simulator)
+ time_ilock_loops = 10;
+
+ count0 = cyg_current_time();
+ for (k = 0; k < time_ilock_loops; k++) {
+ iloop(&start, &end, 0);
+ }
+ count1 = cyg_current_time();
+ t = count1 - count0;
+ diag_printf("time without lock: %d\n", t);
+
+ HAL_ICACHE_LOCK(start, end-start);
+
+ count0 = cyg_current_time();
+ for (k = 0; k < time_ilock_loops; k++) {
+ iloop(&start, &end, 0);
+ }
+ count1 = cyg_current_time();
+ t = count1 - count0;
+ diag_printf("time with lock: %d\n", t);
+
+ HAL_ICACHE_UNLOCK(start, end-start);
+}
+#endif // ifdef HAL_ICACHE_LOCK
+
+// -------------------------------------------------------------------------
+// Test of data cache locking.
+// o Time difference between repeatedly accessing a memory region
+// with and without locking.
+#ifdef HAL_DCACHE_LOCK
+static void dloop(void)
+{
+ register cyg_uint32 j;
+ register char c;
+ register CYG_INTERRUPT_STATE oldints;
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ for (j = 0; j < HAL_DCACHE_SETS; j++) {
+ c = m[HAL_DCACHE_LINE_SIZE*j];
+ }
+}
+
+static void time_dlock(void)
+{
+ register cyg_ucount32 k;
+ cyg_tick_count_t count0, count1;
+ cyg_ucount32 t;
+ register cyg_ucount32 time_dlock_loops = TIME_DLOCK_LOOPS;
+
+ CYG_TEST_INFO("Data cache lock");
+
+ if (cyg_test_is_simulator)
+ time_dlock_loops = 10;
+
+ count0 = cyg_current_time();
+ for (k = 0; k < time_dlock_loops; k++) {
+ dloop();
+ }
+ count1 = cyg_current_time();
+ t = count1 - count0;
+ diag_printf("time without lock: %d\n", t);
+
+ HAL_DCACHE_LOCK(&m[0], HAL_DCACHE_SETS*HAL_DCACHE_LINE_SIZE);
+
+ count0 = cyg_current_time();
+ for (k = 0; k < time_dlock_loops; k++) {
+ dloop();
+ }
+ count1 = cyg_current_time();
+ t = count1 - count0;
+ diag_printf("time with lock: %d\n", t);
+
+ HAL_DCACHE_UNLOCK(&m[0], HAL_DCACHE_SETS*HAL_DCACHE_LINE_SIZE);
+}
+#endif // ifdef HAL_DCACHE_LOCK
+
+// -------------------------------------------------------------------------
+static void entry0( cyg_addrword_t data )
+{
+ int numtests = 0;
+#ifdef HAL_DCACHE_QUERY_WRITE_MODE
+ int wmode;
+#endif
+#ifdef HAL_DCACHE_LOCK
+ time_dlock(); numtests++;
+#endif
+#ifdef HAL_ICACHE_LOCK
+ time_ilock(); numtests++;
+#endif
+#ifdef HAL_DCACHE_LINE_SIZE // So we can find our way around memory
+ test_dsync(); numtests++;
+#endif
+#ifdef HAL_DCACHE_STORE
+ test_dstore(); numtests++;
+#endif
+#ifdef _TEST_DCACHE_OPERATION
+ test_dcache_operation(); numtests++;
+#endif
+#ifdef HAL_DCACHE_READ_HINT
+ test_dread_hint(); numtests++;
+#endif
+#ifdef HAL_DCACHE_WRITE_HINT
+ test_dwrite_hint(); numtests++;
+#endif
+#ifdef HAL_DCACHE_ZERO
+ test_dzero(); numtests++;
+#endif
+
+ // The below tests only work on a copy-back cache.
+#ifdef HAL_DCACHE_QUERY_WRITE_MODE
+ HAL_DCACHE_QUERY_WRITE_MODE( wmode );
+
+ if ( HAL_DCACHE_WRITEBACK_MODE == wmode ) {
+ test_ddisable(); numtests++;
+#ifdef HAL_DCACHE_INVALIDATE
+ test_dinvalidate_all(); numtests++;
+#endif
+#ifdef HAL_DCACHE_FLUSH
+ test_dflush(); numtests++;
+#endif
+#ifdef HAL_DCACHE_INVALIDATE
+ test_dinvalidate(); numtests++;
+#endif
+ }
+#endif // def HAL_DCACHE_QUERY_WRITE_MODE
+ if ( numtests ) {
+ CYG_TEST_PASS_FINISH("End of test");
+ }
+ else {
+ CYG_TEST_NA( "No applicable cache tests" );
+ }
+}
+
+// -------------------------------------------------------------------------
+
+void kcache2_main( void )
+{
+ CYG_TEST_INIT();
+
+ cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "kcache2",
+ (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
+ cyg_thread_resume(thread[0]);
+
+ cyg_scheduler_start();
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ kcache2_main();
+}
+
+// -------------------------------------------------------------------------
+
+#else // def CYGFUN_KERNEL_API_C
+#define N_A_MSG "Kernel C API layer disabled"
+#endif // def CYGFUN_KERNEL_API_C
+#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
+#define N_A_MSG "Kernel real-time clock disabled"
+#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG
+
+// -------------------------------------------------------------------------
+/* EOF kcache2.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/kclock0.c b/cesar/ecos/packages/kernel/current/tests/kclock0.c
new file mode 100644
index 0000000000..91c126700c
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kclock0.c
@@ -0,0 +1,274 @@
+/*=================================================================
+//
+// kclock0.c
+//
+// Kernel C API Clock test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-20
+// Description: Tests some basic clock functions.
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+cyg_alarm_t call_me;
+
+cyg_counter counter0o, counter1o;
+cyg_handle_t counter0, counter1;
+
+cyg_alarm alarmo[3];
+cyg_handle_t alarm0, alarm1, alarm2;
+
+cyg_resolution_t res, res0, res1;
+
+cyg_clock clock0o;
+cyg_handle_t clock0;
+
+const cyg_uint32 big_number = 3333222111u;
+
+cyg_bool_t flash( void )
+{
+ cyg_counter_create( &counter0, &counter0o );
+ cyg_counter_create( &counter1, &counter1o );
+
+ cyg_alarm_create( counter0,
+ call_me,
+ (cyg_addrword_t)12,
+ &alarm0,
+ &alarmo[0]);
+
+ res.dividend = 1;
+ res.divisor = 2;
+
+ cyg_clock_create( res, &clock0, &clock0o );
+ cyg_clock_delete( clock0 );
+
+ cyg_alarm_delete( alarm0 );
+
+ cyg_counter_delete( counter0 );
+ cyg_counter_delete( counter1 );
+
+ return true;
+}
+
+/* Testing alarms
+//
+// call_me is a function that will be called when an alarm is
+// triggered. It updates a global variable called which is CHECKed
+// explicitly to see if the approriate alarms have been called.
+*/
+
+cyg_uint16 called = 0x0;
+
+void call_me(cyg_handle_t alarm, cyg_addrword_t data)
+{
+ called ^= (int)data;
+}
+
+void call_me2(cyg_handle_t alarm, cyg_addrword_t data)
+{
+ call_me(alarm, (cyg_addrword_t)((int)data^0x10));
+}
+
+
+void kclock0_main(void)
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ cyg_counter_create( &counter0, &counter0o);
+
+ CHECK( 0 == cyg_counter_current_value( counter0 ) );
+
+ cyg_counter_tick(counter0);
+
+ CHECK( 1 == cyg_counter_current_value(counter0) );
+
+ cyg_counter_tick(counter0);
+
+ CHECK( 2 == cyg_counter_current_value(counter0) );
+
+ cyg_counter_set_value( counter0, 0xffffffff );
+
+ CHECK( 0xffffffff == cyg_counter_current_value(counter0) );
+
+ cyg_counter_tick(counter0); // Overflows 32 bits
+
+ CHECK( 0x100000000ULL == cyg_counter_current_value(counter0) );
+
+ cyg_counter_set_value(counter0, 11);
+ CHECK( 11 == cyg_counter_current_value(counter0) );
+
+ /* the call_me functions cause the "called" bits to toggle
+ // checking the value of called checks the parity of # of calls
+ // made by each alarm.
+ */
+
+ cyg_alarm_create(counter0,
+ call_me, (cyg_addrword_t)0x1, &alarm0, &alarmo[0]);
+ cyg_alarm_create(counter0,
+ call_me, (cyg_addrword_t)0x2, &alarm1, &alarmo[1]);
+ cyg_alarm_create(counter0,
+ call_me2, (cyg_addrword_t)0x4, &alarm2, &alarmo[2]);
+
+ CHECK( 0x00 == called );
+ cyg_alarm_initialize(alarm0, 12,3);
+ cyg_alarm_initialize(alarm2, 21,2);
+ CHECK( 0x00 == called );
+
+ cyg_counter_tick(counter0); /* 12 a0 */
+ CHECK( 0x01 == called );
+
+ cyg_alarm_initialize(alarm1, 13,0);
+ cyg_counter_tick(counter0); /* 13 a1 */
+ CHECK( 0x03 == called );
+
+ cyg_alarm_initialize(alarm1, 17,0);
+ cyg_counter_tick(counter0); /* 14 */
+ CHECK( 0x03 == called );
+
+ cyg_counter_tick(counter0); /* 15 a0 */
+ CHECK( 0x02 == called );
+
+ cyg_counter_tick(counter0); /* 16 */
+ cyg_counter_tick(counter0); /* 17 a1 */
+ CHECK( 0x00 == called );
+
+ cyg_counter_tick(counter0); /* 18 a0 */
+ CHECK( 0x01 == called );
+
+ cyg_counter_tick(counter0); /* 19 */
+ cyg_counter_tick(counter0); /* 20 */
+ cyg_counter_tick(counter0); /* 21 a0 a2 */
+ CHECK( 0x14 == called );
+
+ cyg_counter_tick(counter0); /* 22 */
+ cyg_counter_tick(counter0); /* 23 a2 */
+ CHECK( 0x00 == called );
+
+ cyg_alarm_disable(alarm2);
+
+ cyg_counter_tick(counter0); /* 24 a0 */
+ cyg_counter_tick(counter0); /* 25 */
+ CHECK( 0x01 == called );
+
+ cyg_alarm_enable(alarm2); /* a2 (enabled at 25) */
+ CHECK( 0x15 == called );
+
+ cyg_counter_tick(counter0); /* 26 */
+ CHECK( 0x15 == called );
+
+ cyg_counter_tick(counter0); /* 27 a0 a2 */
+ cyg_counter_tick(counter0); /* 28 */
+ CHECK( 0x00 == called );
+
+ cyg_counter_tick(counter0); /* 29 a2 */
+ cyg_counter_tick(counter0); /* 30 a0 */
+ cyg_counter_tick(counter0); /* 31 a2 */
+ CHECK( 0x01 == called );
+
+ res0.dividend = 100;
+ res0.divisor = 3;
+
+ cyg_clock_create( res0, &clock0, &clock0o );
+
+ res1 = cyg_clock_get_resolution(clock0);
+ CHECK( res0.dividend == res1.dividend );
+ CHECK( res0.divisor == res1.divisor );
+
+ res1.dividend = 12;
+ res1.divisor = 25;
+
+ cyg_clock_set_resolution(clock0, res1);
+ res0 = cyg_clock_get_resolution(clock0);
+ CHECK( res0.dividend == res1.dividend );
+ CHECK( res0.divisor == res1.divisor );
+
+ cyg_clock_to_counter(clock0, &counter1);
+
+ CHECK( 0 == cyg_counter_current_value( counter1 ) );
+ CHECK( 0 == cyg_current_time() );
+
+ cyg_counter_tick(counter1);
+
+ CHECK( 1 == cyg_counter_current_value(counter1) );
+
+ res0 = cyg_clock_get_resolution(cyg_real_time_clock());
+
+ /* Current time should be 0 as interrupts will still be disabled */
+ CHECK( 0 == cyg_current_time() );
+
+ CYG_TEST_PASS_FINISH("Kernel C API Clock 0 OK");
+}
+
+externC void
+cyg_start( void )
+{
+ kclock0_main();
+}
+
+#else // def CYGFUN_KERNEL_API_C
+#define N_A_MSG "Kernel C API layer disabled"
+#endif // def CYGFUN_KERNEL_API_C
+#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
+#define N_A_MSG "Kernel real-time clock disabled"
+#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG
+
+// EOF kclock0.c
diff --git a/cesar/ecos/packages/kernel/current/tests/kclock1.c b/cesar/ecos/packages/kernel/current/tests/kclock1.c
new file mode 100644
index 0000000000..9eaf502516
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kclock1.c
@@ -0,0 +1,153 @@
+/*=================================================================
+//
+// kclock1.c
+//
+// Kernel C API Clock test 1 - Real Time Clock
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-20
+// Description: Tests the Kernel Real Time Clock
+// This test creates a thread, starts the scheduler and
+// delays for a time of about 5 seconds. This test should
+// be expected to run for about this length of time.
+// Omissions:
+// Doesn't test alarms attached to RTC.
+// Assumptions:
+// CYGVAR_KERNEL_COUNTERS_CLOCK must be set.
+// Resolution of clock small compared with 5s.
+// Overhead small compared with 5s.
+// Options:
+// CYGIMP_KERNEL_COUNTERS_SINGLE_LIST
+// CYGIMP_KERNEL_COUNTERS_MULTI_LIST
+// CYGVAR_KERNEL_COUNTERS_CLOCK
+// CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+
+static cyg_uint64 TEST_DELAY;
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+#define NTHREADS 1
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+static void entry0( cyg_addrword_t data )
+{
+ cyg_resolution_t res;
+ cyg_uint32 ticks;
+ cyg_tick_count_t count0, count1;
+ cyg_handle_t rtclock, rtcounter;
+
+ rtclock = cyg_real_time_clock();
+ cyg_clock_to_counter(rtclock, &rtcounter);
+
+ res = cyg_clock_get_resolution (rtclock);
+
+ /* RTC takes res.dividend/res.divisor ns/tick */
+ ticks = ((cyg_uint64)TEST_DELAY * res.divisor) / res.dividend;
+
+ count0 = cyg_counter_current_value(rtcounter);
+ cyg_thread_delay(ticks);
+ count1 = cyg_counter_current_value(rtcounter);
+
+ CYG_TEST_CHECK(count0+ticks <= count1,
+ "real time clock's counter not counting");
+
+ CYG_TEST_CHECK(count1 <= cyg_current_time(),"cyg_current_time()");
+
+ CYG_TEST_PASS_FINISH("Kernel C API Clock 1 OK");
+}
+
+void kclock1_main( void )
+{
+ CYG_TEST_INIT();
+
+ if (cyg_test_is_simulator) {
+ TEST_DELAY = 100000000ll;
+ } else {
+ TEST_DELAY = 3000000000ll;
+ }
+
+ cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "kclock1",
+ (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
+ cyg_thread_resume(thread[0]);
+
+ cyg_scheduler_start();
+}
+
+externC void
+cyg_start( void )
+{
+ kclock1_main();
+}
+
+#else // def CYGFUN_KERNEL_API_C
+#define N_A_MSG "Kernel C API layer disabled"
+#endif // def CYGFUN_KERNEL_API_C
+#else // def CYGFUN_KERNEL_THREADS_TIMER
+#define N_A_MSG "Kernel threads timer disabled"
+#endif // def CYGFUN_KERNEL_THREADS_TIMER
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG
+
+// EOF kclock1.c
diff --git a/cesar/ecos/packages/kernel/current/tests/kexcept1.c b/cesar/ecos/packages/kernel/current/tests/kexcept1.c
new file mode 100644
index 0000000000..d85687f6a4
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kexcept1.c
@@ -0,0 +1,288 @@
+/*=================================================================
+//
+// kexcept1.cxx
+//
+// Kernel C API Exception test 1
+//
+//=================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//=================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm, jlarmour
+// Date: 1999-02-16
+// Description: Test basic exception functionality
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGPKG_KERNEL_EXCEPTIONS
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include <cyg/hal/hal_intr.h> // exception ranges
+
+#include "testaux.h"
+
+#ifndef CYGPKG_HAL_ARM_PID
+#define EXCEPTION_DATA_ACCESS
+#endif
+
+#define NTHREADS 1
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+
+
+#ifdef EXCEPTION_DATA_ACCESS
+static cyg_exception_handler_t handler0;
+
+static void handler0(cyg_addrword_t data, cyg_code_t number, cyg_addrword_t info)
+{
+ CYG_TEST_INFO("handler 0 called");
+
+ CYG_TEST_CHECK((cyg_addrword_t)123 == data, "handler given wrong data");
+
+ // ignore machine specific stuff
+ CYG_UNUSED_PARAM(cyg_code_t, number);
+ CYG_UNUSED_PARAM(cyg_addrword_t, info);
+
+ CYG_TEST_PASS_FINISH("Except 1 OK");
+}
+#endif
+
+static int d0;
+
+static void handler1(cyg_addrword_t data, cyg_code_t number, cyg_addrword_t info)
+{
+ CYG_TEST_INFO("handler 1 called");
+
+ CYG_TEST_CHECK((cyg_addrword_t)&d0 == data, "handler given wrong data");
+
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
+ CYG_TEST_CHECK(number == CYGNUM_HAL_EXCEPTION_MAX, "handler given wrong number");
+#else
+ CYG_UNUSED_PARAM(cyg_code_t, number);
+#endif
+
+ CYG_TEST_CHECK((cyg_addrword_t)99 == info, "handler given wrong info");
+}
+
+
+#ifdef EXCEPTION_DATA_ACCESS
+// The following function attempts to cause an exception in various
+// hacky ways. It is machine dependent what exception is generated.
+// It does reads rather than writes hoping not to corrupt anything
+// important.
+static int
+cause_fpe(int num)
+{
+ double a;
+
+ a = 1.0/num; // Depending on FPU emulation and/or
+ // the FPU architecture, this may
+ // cause an exception.
+ // (float division by zero)
+
+ return ((int)a)/num; // This may cause an exception if
+ // the architecture supports it.
+ // (integer division by zero).
+} // cause_fpe()
+
+void cause_exception(void)
+{
+ int x;
+ unsigned int p=0;
+
+ // First try for an address exception (unaligned access exception
+ // or SEGV/BUS exceptions)
+ do {
+ x=*(volatile int *)(p-1);
+ p+=0x100000;
+ } while(p != 0);
+
+ // Next try an integer or floating point divide-by-zero exception.
+ cause_fpe(0);
+}
+#endif
+
+static void entry0( CYG_ADDRWORD data )
+{
+#ifdef EXCEPTION_DATA_ACCESS
+ cyg_code_t n;
+#endif
+ cyg_exception_handler_t *old_handler, *old_handler1;
+ cyg_addrword_t old_data, old_data1;
+
+ CYG_UNUSED_PARAM(CYG_ADDRESS, data);
+
+ cyg_exception_set_handler(
+ CYGNUM_HAL_EXCEPTION_MAX,
+ &handler1,
+ (cyg_addrword_t)&d0,
+ &old_handler,
+ &old_data);
+
+ cyg_exception_set_handler(
+ CYGNUM_HAL_EXCEPTION_MAX,
+ &handler1,
+ (cyg_addrword_t)&d0,
+ &old_handler1,
+ &old_data1);
+
+ CYG_TEST_CHECK(old_handler1 == &handler1,
+ "register exception: old_handler not the one previously registered");
+ CYG_TEST_CHECK(old_data1 == (cyg_addrword_t)&d0,
+ "register exception: old_data not those previously registered");
+
+ cyg_exception_call_handler(
+ cyg_thread_self(),
+ CYGNUM_HAL_EXCEPTION_MAX,
+ (cyg_addrword_t)99);
+
+ CYG_TEST_INFO("handler 1 returned");
+
+ cyg_exception_clear_handler(CYGNUM_HAL_EXCEPTION_MAX);
+ cyg_exception_clear_handler(CYGNUM_HAL_EXCEPTION_MAX);
+
+#ifdef EXCEPTION_DATA_ACCESS
+
+#if 0
+#elif defined(CYGPKG_HAL_POWERPC_SIM)
+ // The exception generated by the SIM is not recognized by GDB.
+ // PR 19945 workaround.
+ CYG_TEST_NA("Not applicable to PowerPC SIM");
+#endif
+
+ for(n = CYGNUM_HAL_EXCEPTION_MIN; n <= CYGNUM_HAL_EXCEPTION_MAX; n++) {
+ cyg_exception_set_handler(
+ n,
+ handler0,
+ (cyg_addrword_t)123,
+ &old_handler1,
+ &old_data1);
+ }
+
+ CYG_TEST_PASS("Attempting to provoke exception");
+
+ cause_exception();
+
+ CYG_TEST_FAIL_FINISH("Couldn't cause exception");
+#else // EXCEPTION_DATA_ACCESS
+ CYG_TEST_NA("Platform does not support data exceptions");
+#endif
+}
+
+#ifdef CYG_HAL_MIPS_TX39_JMR3904
+
+extern void __default_exception_vsr(void);
+
+#endif
+
+void except0_main( void )
+{
+ // Use CYG_TEST_GDBCMD _before_ CYG_TEST_INIT()
+ CYG_TEST_GDBCMD("handle SIGBUS nostop");
+ CYG_TEST_GDBCMD("handle SIGSEGV nostop");
+ CYG_TEST_GDBCMD("handle SIGFPE nostop");
+
+ CYG_TEST_INIT();
+
+#ifdef HAL_VSR_SET_TO_ECOS_HANDLER
+ // Reclaim the VSR off CygMon possibly
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_ACCESS, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_FPU, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
+ HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO, NULL );
+#endif
+#endif
+
+ cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "kexcept1",
+ (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
+ cyg_thread_resume(thread[0]);
+
+ cyg_scheduler_start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+ except0_main();
+}
+
+#else // def CYGFUN_KERNEL_API_C
+#define N_A_MSG "Kernel C API layer disabled"
+#endif // def CYGFUN_KERNEL_API_C
+#else // def CYGPKG_KERNEL_EXCEPTIONS
+#define N_A_MSG "Exceptions disabled"
+#endif // def CYGPKG_KERNEL_EXCEPTIONS
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+/* EOF kexcept1.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/kflag0.c b/cesar/ecos/packages/kernel/current/tests/kflag0.c
new file mode 100644
index 0000000000..d5483db11b
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kflag0.c
@@ -0,0 +1,99 @@
+/*==========================================================================
+//
+// kflag0.cxx
+//
+// Kernel C API Flag test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: hmt
+// Date: 1998-10-19
+// Description: Limited to checking constructors/destructors
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+cyg_flag_t f0, f1, f2;
+
+static bool flash( void )
+{
+ cyg_flag_init( &f0 );
+ cyg_flag_init( &f1 );
+ cyg_flag_init( &f2 );
+
+ cyg_flag_destroy( &f0 );
+ cyg_flag_destroy( &f1 );
+ cyg_flag_destroy( &f2 );
+
+ return true;
+}
+
+void kflag0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ CYG_TEST_PASS_FINISH("Kernel C API Flag 0 OK");
+
+}
+
+externC void
+cyg_start( void )
+{
+ kflag0_main();
+}
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+// EOF kflag0.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/kflag1.c b/cesar/ecos/packages/kernel/current/tests/kflag1.c
new file mode 100644
index 0000000000..d09ddec1ba
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kflag1.c
@@ -0,0 +1,244 @@
+/*==========================================================================
+//
+// kflag1.cxx
+//
+// Kernel C API Flag test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author: dsm
+// Contributors: hmt
+// Date: 1998-10-19
+// Description: Tests basic flag functionality.
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+
+#define NTHREADS 3
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+static cyg_flag_t f0, f1;
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+static cyg_flag_t f2;
+#endif
+
+static volatile cyg_ucount8 q = 0;
+#define FIRST_THREAD_WAIT_TIME 5
+#define SECOND_THREAD_WAIT_TIME 10
+#define THIRD_THREAD_WAIT_TIME 20
+
+static void entry0( cyg_addrword_t data )
+{
+ CYG_TEST_INFO("Testing cyg_flag_setbits() and cyg_flag_maskbits()");
+ CYG_TEST_CHECK(0==cyg_flag_peek( &f0 ), "flag not initialized properly");
+ cyg_flag_setbits( &f0, 0x1);
+ CYG_TEST_CHECK(1==cyg_flag_peek( &f0 ), "setbits");
+ cyg_flag_setbits( &f0, 0x3);
+ CYG_TEST_CHECK(3==cyg_flag_peek( &f0 ), "setbits");
+ cyg_flag_maskbits( &f0, ~0x5);
+ CYG_TEST_CHECK(2==cyg_flag_peek( &f0 ), "maskbits");
+ cyg_flag_setbits( &f0, ~0 );
+ CYG_TEST_CHECK(~0u==cyg_flag_peek( &f0 ), "setbits all set");
+ cyg_flag_maskbits( &f0, 0 );
+ CYG_TEST_CHECK(0==cyg_flag_peek( &f0 ), "maskbits all clear");
+ CYG_TEST_CHECK(0==q++, "bad synchronization");
+
+ CYG_TEST_INFO("Testing cyg_flag_wait()");
+ cyg_flag_setbits( &f1, 0x4);
+ CYG_TEST_CHECK(0x4==cyg_flag_peek( &f1 ), "setbits");
+ CYG_TEST_CHECK(1==q++, "bad synchronization");
+ cyg_flag_setbits( &f1, 0x18); // wake t1
+ cyg_flag_wait( &f1, 0x11, CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);
+ CYG_TEST_CHECK(0==cyg_flag_peek( &f1 ), "flag value wrong");
+ CYG_TEST_CHECK(3==q++, "bad synchronization");
+ cyg_flag_setbits( &f0, 0x2); // wake t1
+ cyg_flag_wait( &f1, 0x10, CYG_FLAG_WAITMODE_AND );
+ cyg_flag_setbits( &f0, 0x1); // wake t1
+
+ cyg_flag_wait( &f1, 0x11, CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ cyg_flag_wait( &f2, 0x2, CYG_FLAG_WAITMODE_OR);
+ CYG_TEST_CHECK(20==q,"bad synchronization");
+ cyg_flag_timed_wait( &f2, 0x10, CYG_FLAG_WAITMODE_AND,
+ cyg_current_time()+THIRD_THREAD_WAIT_TIME);
+ CYG_TEST_CHECK(21==q++,"bad synchronization");
+#endif
+ cyg_flag_wait( &f0, 1, CYG_FLAG_WAITMODE_OR);
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+static void entry1( cyg_addrword_t data )
+{
+ cyg_flag_wait( &f1, 0xc, CYG_FLAG_WAITMODE_AND);
+ CYG_TEST_CHECK(2==q++, "bad synchronization");
+ CYG_TEST_CHECK(0x1c==cyg_flag_peek( &f1 ), "flag value wrong");
+ cyg_flag_setbits( &f1, 0x1); // wake t0
+ cyg_flag_wait( &f0, 0x3, CYG_FLAG_WAITMODE_OR);
+ CYG_TEST_CHECK(4==q++, "bad synchronization");
+ CYG_TEST_CHECK(2==cyg_flag_peek( &f0 ), "flag value wrong");
+
+ cyg_flag_setbits( &f1, 0xf0); // wake t0,t2
+ cyg_flag_wait( &f0, 0x5, CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);
+ CYG_TEST_CHECK(0==cyg_flag_peek( &f0 ), "flag value wrong");
+ CYG_TEST_CHECK(0xf0==cyg_flag_peek( &f1 ), "flag value wrong");
+ CYG_TEST_CHECK(5==q++, "bad synchronization");
+ cyg_flag_maskbits( &f1, 0 );
+ CYG_TEST_CHECK(0==cyg_flag_peek( &f1 ), "flag value wrong");
+
+ CYG_TEST_INFO("Testing cyg_flag_poll()");
+ cyg_flag_setbits( &f0, 0x55);
+ CYG_TEST_CHECK(0x55==cyg_flag_peek( &f0 ), "flag value wrong");
+ CYG_TEST_CHECK(0x55==cyg_flag_poll( &f0, 0x3, CYG_FLAG_WAITMODE_OR),"bad poll() return");
+ CYG_TEST_CHECK(0==cyg_flag_poll( &f0, 0xf, CYG_FLAG_WAITMODE_AND),"poll()");
+ CYG_TEST_CHECK(0==cyg_flag_poll( &f0, 0xa, CYG_FLAG_WAITMODE_OR),"poll()");
+ CYG_TEST_CHECK(0x55==cyg_flag_peek( &f0 ), "flag value wrong");
+ CYG_TEST_CHECK(0x55==cyg_flag_poll( &f0, 0xf, CYG_FLAG_WAITMODE_OR | CYG_FLAG_WAITMODE_CLR),"poll");
+ CYG_TEST_CHECK(0x0==cyg_flag_peek( &f0 ), "flag value wrong");
+ cyg_flag_setbits( &f0, 0x50);
+ CYG_TEST_CHECK(0x50==cyg_flag_poll( &f0, 0x10, CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR),"poll");
+ CYG_TEST_CHECK(0x0==cyg_flag_peek( &f0 ), "flag value wrong");
+
+ CYG_TEST_INFO("Testing cyg_flag_waiting()");
+ cyg_flag_maskbits( &f0, 0 );
+ CYG_TEST_CHECK(!cyg_flag_waiting( &f0 ), "waiting()");
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ cyg_thread_delay( 10 ); // allow other threads to reach wait on f1
+ CYG_TEST_CHECK(cyg_flag_waiting( &f1 ), "waiting() not true");
+ cyg_flag_setbits( &f1, ~0 ); // wake one of t0,t2
+ CYG_TEST_CHECK(cyg_flag_waiting( &f1 ),"waiting() not true");
+#else
+ cyg_flag_setbits( &f1, 0x11); // wake one of t0,t2
+#endif
+ cyg_flag_setbits( &f1, 0x11); // wake other of t0,t2
+ CYG_TEST_CHECK(!cyg_flag_waiting( &f1 ),"waiting not false");
+ CYG_TEST_CHECK(0x0==cyg_flag_peek( &f1 ), "flag value wrong");
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ CYG_TEST_INFO("Testing cyg_flag_timed_wait()");
+ q=20;
+ cyg_flag_setbits( &f2, 0x2); // synchronize with t0,t2
+ CYG_TEST_CHECK(20==q,"bad synchronization");
+ cyg_flag_timed_wait( &f2, 0x20, CYG_FLAG_WAITMODE_AND,
+ cyg_current_time()+SECOND_THREAD_WAIT_TIME);
+ CYG_TEST_CHECK(22==q++,"bad synchronization");
+#endif
+
+ CYG_TEST_PASS_FINISH("Kernel C API Flag 1 OK");
+}
+
+static void entry2( cyg_addrword_t data )
+{
+ cyg_flag_wait( &f1, 0x60, CYG_FLAG_WAITMODE_OR);
+ cyg_flag_setbits( &f0, 0x4);
+
+ cyg_flag_wait( &f1, 0x11, CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ cyg_flag_wait( &f2, 0x2, CYG_FLAG_WAITMODE_OR);
+ CYG_TEST_CHECK(20==q,"bad synchronization");
+ CYG_TEST_CHECK(0==cyg_flag_timed_wait( &f2, 0x40, CYG_FLAG_WAITMODE_AND,
+ cyg_current_time()+FIRST_THREAD_WAIT_TIME),
+ "timed wait() wrong");
+ CYG_TEST_CHECK(20==q++,"bad synchronization");
+ // Now wake t0 before it times out
+ cyg_flag_setbits( &f2, 0x10);
+#endif
+ cyg_flag_wait( &f0, 1, CYG_FLAG_WAITMODE_OR);
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+void kflag1_main( void )
+{
+ CYG_TEST_INIT();
+
+ cyg_flag_init( &f0 );
+ cyg_flag_init( &f1 );
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ cyg_flag_init( &f2 );
+#endif
+
+ cyg_thread_create( 1, entry0 , (cyg_addrword_t)0, "kflag1-0",
+ (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
+ cyg_thread_resume(thread[0]);
+
+ cyg_thread_create( 1, entry1 , (cyg_addrword_t)1, "kflag1-1",
+ (void *)stack[1], STACKSIZE, &thread[1], &thread_obj[1]);
+ cyg_thread_resume(thread[1]);
+
+ cyg_thread_create( 1, entry2 , (cyg_addrword_t)2, "kflag1-2",
+ (void *)stack[2], STACKSIZE, &thread[2], &thread_obj[2]);
+ cyg_thread_resume(thread[2]);
+
+ cyg_scheduler_start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+ kflag1_main();
+}
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+// EOF flag1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/kill.cxx b/cesar/ecos/packages/kernel/current/tests/kill.cxx
new file mode 100644
index 0000000000..032403b82e
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kill.cxx
@@ -0,0 +1,199 @@
+//==========================================================================
+//
+// kill.cxx
+//
+// Thread kill test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1998-04-24
+// Description: Tests the functionality of thread kill() and
+// reinitalize().
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/mutex.hxx>
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+#include <cyg/kernel/sched.inl>
+
+#define NTHREADS 3
+
+#include "testaux.hxx"
+
+// In general, this delay has to be long enough to account for slow targets
+// and potential problems on e.g. the linux synthetic target to avoid
+// potential problems due to timing inaccuracy and scheduling of Linux
+// tasks. It is decreased further below for simulators.
+int delay_ticks = 5;
+
+
+static Cyg_Binary_Semaphore s0, s1;
+
+volatile cyg_atomic thread0_state;
+volatile cyg_atomic thread1_state;
+volatile cyg_atomic thread2_state;
+
+static void entry0( CYG_ADDRWORD data )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ thread0_state = 1;
+
+ s0.wait();
+
+ thread0_state = 2;
+
+ CYG_TEST_FAIL_FINISH("Thread not killed");
+
+ self->exit();
+}
+
+
+static void entry1( CYG_ADDRWORD data )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ thread1_state = 1;
+
+ self->delay(delay_ticks);
+
+ if( thread2_state != 1 )
+ CYG_TEST_FAIL_FINISH("Thread2 in wrong state");
+
+ thread1_state = 2;
+
+ thread[0]->kill();
+
+ thread1_state = 3;
+
+ thread[2]->kill();
+
+ thread1_state = 4;
+
+ self->delay(delay_ticks);
+
+ thread1_state = 5;
+ thread2_state = 0;
+
+ thread[2]->reinitialize();
+ thread[2]->resume();
+
+ self->delay(delay_ticks);
+
+ if( thread2_state != 1 )
+ CYG_TEST_FAIL_FINISH("Thread2 in wrong state");
+
+ thread1_state = 6;
+
+ self->delay(delay_ticks);
+
+ if( thread2_state != 2 )
+ CYG_TEST_FAIL_FINISH("Thread2 in wrong state");
+
+ thread[2]->kill();
+
+ thread1_state = 7;
+
+ CYG_TEST_PASS_FINISH("Kill OK");
+
+ Cyg_Thread::self()->exit();
+}
+
+static void entry2( CYG_ADDRWORD data )
+{
+ thread2_state = 1;
+
+ while( thread1_state != 6 ) continue;
+
+ thread2_state = 2;
+
+ for(;;) continue;
+
+}
+
+void release_main(void)
+{
+ CYG_TEST_INIT();
+
+ if (cyg_test_is_simulator)
+ delay_ticks = 2;
+
+ new_thread( entry0, 0);
+ new_thread( entry1, 1);
+ new_thread( entry2, 2);
+
+ thread[0]->set_priority(5);
+ thread[1]->set_priority(6);
+ thread[2]->set_priority(7);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ release_main();
+}
+
+#else // ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel threads timer disabled");
+}
+
+#endif // ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+// EOF kill.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/kintr0.c b/cesar/ecos/packages/kernel/current/tests/kintr0.c
new file mode 100644
index 0000000000..6bc53f672b
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kintr0.c
@@ -0,0 +1,230 @@
+/*=================================================================
+//
+// kintr0.c
+//
+// Kernel C API Intr test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm, jlarmour
+// Date: 1999-02-16
+// Description: Very basic test of interrupt objects
+// Options:
+// CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE
+// CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE_MAX
+// CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_intr.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+static cyg_interrupt intr_obj[2];
+
+static cyg_handle_t intr0, intr1;
+
+
+static cyg_ISR_t isr0, isr1;
+static cyg_DSR_t dsr0, dsr1;
+
+static cyg_uint32 isr0(cyg_vector_t vector, cyg_addrword_t data)
+{
+ CYG_UNUSED_PARAM(cyg_addrword_t, data);
+
+ cyg_interrupt_acknowledge(vector);
+ return 0;
+}
+
+static void dsr0(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ CYG_UNUSED_PARAM(cyg_vector_t, vector);
+ CYG_UNUSED_PARAM(cyg_ucount32, count);
+ CYG_UNUSED_PARAM(cyg_addrword_t, data);
+}
+
+static cyg_uint32 isr1(cyg_vector_t vector, cyg_addrword_t data)
+{
+ CYG_UNUSED_PARAM(cyg_vector_t, vector);
+ CYG_UNUSED_PARAM(cyg_addrword_t, data);
+ return 0;
+}
+
+static void dsr1(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ CYG_UNUSED_PARAM(cyg_vector_t, vector);
+ CYG_UNUSED_PARAM(cyg_ucount32, count);
+ CYG_UNUSED_PARAM(cyg_addrword_t, data);
+}
+
+static bool flash( void )
+{
+ cyg_handle_t handle;
+ cyg_interrupt intr;
+
+ cyg_interrupt_create(CYGNUM_HAL_ISR_MIN, 0, (cyg_addrword_t)333,
+ isr0, dsr0, &handle, &intr );
+ cyg_interrupt_delete(handle);
+
+ return true;
+}
+
+/* IMPORTANT: The calling convention for VSRs is target dependent. It is
+ * unlikely that a plain C or C++ routine would function correctly on any
+ * particular platform, even if it could correctly access the system
+ * resources necessary to handle the event that caused it to be called.
+ * VSRs usually must be written in assembly language.
+ *
+ * This is just a test program. The routine vsr0() below is defined simply
+ * to define an address that will be in executable memory. If an event
+ * causes this VSR to be called, all bets are off. If it is accidentally
+ * installed in the vector for the realtime clock, the system will likely
+ * freeze.
+ */
+
+static cyg_VSR_t vsr0;
+
+static void vsr0()
+{
+}
+
+void kintr0_main( void )
+{
+ cyg_vector_t v = (CYGNUM_HAL_VSR_MIN + 11) % CYGNUM_HAL_VSR_COUNT;
+ cyg_vector_t v1;
+ cyg_vector_t lvl1 = CYGNUM_HAL_ISR_MIN + (1 % CYGNUM_HAL_ISR_COUNT);
+ cyg_vector_t lvl2 = CYGNUM_HAL_ISR_MIN + (15 % CYGNUM_HAL_ISR_COUNT);
+ int in_use;
+
+ cyg_VSR_t *old_vsr, *new_vsr;
+
+ CYG_TEST_INIT();
+
+#ifdef CYGPKG_HAL_MIPS_TX39
+ // This can be removed when PR 17831 is fixed
+ if ( cyg_test_is_simulator )
+ v1 = 12 % CYGNUM_HAL_ISR_COUNT;
+ else /* NOTE TRAILING ELSE... */
+#endif
+ v1 = CYGNUM_HAL_ISR_MIN + ( 6 % CYGNUM_HAL_ISR_COUNT);
+
+ CHECK(flash());
+ CHECK(flash());
+
+ // Make sure the chosen levels are not already in use.
+ HAL_INTERRUPT_IN_USE( lvl1, in_use );
+ intr0 = 0;
+ if (!in_use)
+ cyg_interrupt_create(lvl1, 1, (cyg_addrword_t)777, isr0, dsr0,
+ &intr0, &intr_obj[0]);
+
+ HAL_INTERRUPT_IN_USE( lvl2, in_use );
+ intr1 = 0;
+ if (!in_use && lvl1 != lvl2)
+ cyg_interrupt_create(lvl2, 1, 888, isr1, dsr1, &intr1, &intr_obj[1]);
+
+ // Check these functions at least exist
+
+ cyg_interrupt_disable();
+ cyg_interrupt_enable();
+
+ if (intr0)
+ cyg_interrupt_attach(intr0);
+ if (intr1)
+ cyg_interrupt_attach(intr1);
+ if (intr0)
+ cyg_interrupt_detach(intr0);
+ if (intr1)
+ cyg_interrupt_detach(intr1);
+
+ // If this attaching interrupt replaces the previous interrupt
+ // instead of adding to it we could be in a big mess if the
+ // vector is being used by something important.
+
+ cyg_interrupt_get_vsr( v, &old_vsr );
+ cyg_interrupt_set_vsr( v, vsr0 );
+ cyg_interrupt_get_vsr( v, &new_vsr );
+ CHECK( vsr0 == new_vsr );
+
+ new_vsr = NULL;
+ cyg_interrupt_get_vsr( v, &new_vsr );
+ cyg_interrupt_set_vsr( v, old_vsr );
+ CHECK( new_vsr == vsr0 );
+
+ cyg_interrupt_set_vsr( v, new_vsr );
+ new_vsr = NULL;
+ cyg_interrupt_get_vsr( v, &new_vsr );
+ CHECK( vsr0 == new_vsr );
+
+ cyg_interrupt_set_vsr( v, old_vsr );
+ CHECK( vsr0 == new_vsr );
+ new_vsr = NULL;
+ cyg_interrupt_get_vsr( v, &new_vsr );
+ CHECK( old_vsr == new_vsr );
+
+ CHECK( NULL != vsr0 );
+
+ cyg_interrupt_mask(v1);
+ cyg_interrupt_unmask(v1);
+
+ cyg_interrupt_configure(v1, true, true);
+
+ CYG_TEST_PASS_FINISH("Kernel C API Intr 0 OK");
+}
+
+externC void
+cyg_start( void )
+{
+ kintr0_main();
+}
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+/* EOF kintr0.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/klock.c b/cesar/ecos/packages/kernel/current/tests/klock.c
new file mode 100644
index 0000000000..fefc3cab11
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/klock.c
@@ -0,0 +1,318 @@
+/*=================================================================
+//
+// klock.c
+//
+// Kernel lock test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-18
+// Description: Tests some basic thread functions.
+//####DESCRIPTIONEND####
+*/
+//==========================================================================
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+//==========================================================================
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#if (CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES == 0)
+
+//==========================================================================
+
+#include "testaux.h"
+
+#include <cyg/hal/hal_arch.h> // for CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+//==========================================================================
+
+#ifdef CYGNUM_HAL_STACK_SIZE_TYPICAL
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+#else
+#define STACKSIZE 2000
+#endif
+
+//==========================================================================
+
+static char stack[2][STACKSIZE];
+
+static cyg_thread thread[2];
+
+static cyg_handle_t pt0,pt1;
+
+static cyg_mutex_t mx;
+static cyg_cond_t cv;
+static cyg_sem_t sem;
+static cyg_flag_t fl;
+static cyg_mbox mbox;
+static cyg_handle_t mbh;
+
+volatile static int thread0_state = 0;
+volatile static int thread1_state = 0;
+
+//==========================================================================
+
+static void entry0( cyg_addrword_t data )
+{
+ CHECK( 222 == (int)data );
+
+ // Do everything with the scheduler locked.
+ cyg_scheduler_lock();
+
+ // --------------------------------------------------
+ // Mutex test
+
+ cyg_mutex_lock( &mx );
+ thread0_state = 1;
+
+ // Get thread 2 running.
+ cyg_thread_resume(pt1);
+ thread0_state = 2;
+
+#ifdef CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT
+ cyg_cond_wait( &cv );
+ thread0_state = 3;
+
+ while( thread1_state < 2 ) cyg_thread_yield();
+
+ cyg_cond_broadcast( &cv );
+ thread0_state = 4;
+#endif
+
+ cyg_mutex_unlock( &mx );
+ thread0_state = 5;
+
+
+ // --------------------------------------------------
+ // Semaphore test
+
+ cyg_semaphore_wait( &sem );
+ thread0_state = 6;
+
+ cyg_semaphore_post( &sem );
+ thread0_state = 7;
+
+ while( thread1_state < 7 ) cyg_thread_yield();
+
+ // --------------------------------------------------
+ // Flags test
+
+ cyg_flag_wait( &fl, 1, CYG_FLAG_WAITMODE_OR|CYG_FLAG_WAITMODE_CLR);
+ thread0_state = 8;
+
+ cyg_flag_setbits( &fl, 2 );
+ thread0_state = 9;
+
+ // --------------------------------------------------
+ // Message box test
+
+#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+ {
+ void *mbret;
+
+ mbret = cyg_mbox_get( mbh );
+ CYG_TEST_CHECK( mbret == (void *)0xAAAAAAAA , "bad result from cyg_mbox_timed_get()");
+ thread0_state = 10;
+
+ cyg_mbox_put( mbh, (void *)0xBBBBBBBB );
+ thread0_state = 11;
+ }
+#endif
+ // --------------------------------------------------
+
+ thread0_state = 999;
+
+ cyg_thread_yield();
+ cyg_thread_yield();
+ cyg_thread_yield();
+
+ CYG_TEST_CHECK( thread0_state == 999, "thread 0 not in exit state");
+ CYG_TEST_CHECK( thread1_state == 999, "thread 1 not in exit state");
+ CYG_TEST_PASS_FINISH("Kernel lock test OK");
+}
+
+//==========================================================================
+
+static void entry1( cyg_addrword_t data )
+{
+ cyg_bool res;
+
+ CHECK( 333 == (int)data );
+
+ // Do everything with the scheduler locked.
+ cyg_scheduler_lock();
+
+ // --------------------------------------------------
+ // Mutex test
+#ifdef CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT
+ cyg_mutex_lock( &mx );
+ thread1_state = 1;
+
+ while( thread0_state < 2 ) cyg_thread_yield();
+
+ cyg_cond_signal( &cv );
+ thread1_state = 2;
+
+ res = cyg_cond_timed_wait( &cv, cyg_current_time()+10 );
+ CYG_TEST_CHECK( res , "FALSE result from cyg_cond_timed_wait()" );
+ thread1_state = 3;
+
+ cyg_mutex_unlock( &mx );
+ thread1_state = 4;
+#endif
+
+ // --------------------------------------------------
+ // Semaphore test
+
+ while( thread0_state < 5 ) cyg_thread_yield();
+
+ cyg_semaphore_post( &sem );
+ thread1_state = 5;
+
+ while( thread0_state < 6 ) cyg_thread_yield();
+ thread1_state = 6;
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ res = cyg_semaphore_timed_wait( &sem, cyg_current_time()+10 );
+#else
+ res = cyg_semaphore_wait( &sem );
+#endif
+ CYG_TEST_CHECK( res , "FALSE result from cyg_semaphore[_timed]_wait()" );
+ thread1_state = 7;
+
+ // --------------------------------------------------
+ // Flags test
+
+ cyg_flag_setbits( &fl, 1 );
+ thread1_state = 8;
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ cyg_flag_timed_wait( &fl, 2, CYG_FLAG_WAITMODE_OR|CYG_FLAG_WAITMODE_CLR,
+ cyg_current_time()+10 );
+#else
+ cyg_flag_wait( &fl, 2, CYG_FLAG_WAITMODE_OR|CYG_FLAG_WAITMODE_CLR );
+#endif
+ thread1_state = 9;
+
+ // --------------------------------------------------
+ // Message box test
+#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+ {
+ void *mbret;
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ cyg_mbox_timed_put( mbh, (void *)0xAAAAAAAA, cyg_current_time()+10 );
+#else
+ cyg_mbox_put( mbh, (void *)0xAAAAAAAA );
+#endif
+ thread1_state = 10;
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ mbret = cyg_mbox_timed_get( mbh, cyg_current_time()+10);
+#else
+ mbret = cyg_mbox_get( mbh );
+#endif
+ CYG_TEST_CHECK( mbret == (void *)0xBBBBBBBB , "bad result from cyg_mbox[_timed]_get()");
+ thread1_state = 9;
+ }
+#endif
+ // --------------------------------------------------
+
+ thread1_state = 999;
+ cyg_thread_exit();
+}
+
+//==========================================================================
+
+void kthread1_main( void )
+{
+ CYG_TEST_INIT();
+
+ cyg_thread_create(4, entry0, (cyg_addrword_t)222, "kthread1-0",
+ (void *)stack[0], STACKSIZE, &pt0, &thread[0] );
+ cyg_thread_create(4, entry1, (cyg_addrword_t)333, "kthread1-1",
+ (void *)stack[1], STACKSIZE, &pt1, &thread[1] );
+
+ // Init all the objects
+
+ cyg_mutex_init( &mx );
+ cyg_cond_init( &cv, &mx );
+ cyg_semaphore_init( &sem, 0 );
+ cyg_flag_init( &fl );
+ cyg_mbox_create( &mbh, &mbox );
+
+ cyg_thread_resume(pt0);
+
+ cyg_scheduler_start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+//==========================================================================
+
+externC void
+cyg_start( void )
+{
+ kthread1_main();
+}
+
+//==========================================================================
+
+#else /* CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES == 0 */
+# define NA_MSG "Schedule has unique priorities"
+#endif
+
+#else /* def CYGFUN_KERNEL_API_C */
+# define NA_MSG "Kernel C API layer disabled"
+#endif
+
+#ifdef NA_MSG
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(NA_MSG);
+}
+#endif
+
+//==========================================================================
+/* EOF klock.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/kmbox1.c b/cesar/ecos/packages/kernel/current/tests/kmbox1.c
new file mode 100644
index 0000000000..8b0983731a
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kmbox1.c
@@ -0,0 +1,217 @@
+/*==========================================================================
+//
+// kmbox1.cxx
+//
+// Kernel Mbox test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author: dsm
+// Contributors: dsm
+// Date: 1998-06-02
+// Description: Tests basic mbox functionality.
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+#define NTHREADS 2
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+static cyg_handle_t m0, m1, m2;
+static cyg_mbox mbox0, mbox1, mbox2;
+
+static cyg_atomic q = 0;
+
+#ifndef CYGMTH_MBOX_PUT_CAN_WAIT
+#define cyg_mbox_PUT cyg_mbox_tryput
+#endif
+
+static void entry0( cyg_addrword_t data )
+{
+ cyg_count8 u,i,j;
+
+ CYG_TEST_INFO("Testing put() and tryput() without wakeup");
+ CYG_TEST_CHECK(!cyg_mbox_waiting_to_get(m0), "mbox not initialized properly");
+ CYG_TEST_CHECK(0==cyg_mbox_peek(m0), "mbox not initialized properly");
+ CYG_TEST_CHECK(NULL==cyg_mbox_peek_item(m0), "mbox not initialized properly");
+ cyg_mbox_PUT(m0, (void *)55);
+ CYG_TEST_CHECK(1==cyg_mbox_peek(m0), "peek() wrong");
+ CYG_TEST_CHECK(55==(cyg_count8)cyg_mbox_peek_item(m0), "peek_item() wrong");
+ for(u=1; cyg_mbox_tryput(m0, (void*)u); u++) {
+ CYG_TEST_CHECK(55==(cyg_count8)cyg_mbox_peek_item(m0), "peek_item() wrong");
+ CYG_TEST_CHECK(u+1==cyg_mbox_peek(m0), "peek() wrong");
+ }
+ CYG_TEST_CHECK(u == CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE, "mbox not configured size");
+
+ // m0 now contains ( 55 1 2 .. u-1 )
+ CYG_TEST_CHECK(u==cyg_mbox_peek(m0), "peek() wrong");
+ CYG_TEST_CHECK(55==(cyg_count8)cyg_mbox_peek_item(m0), "peek_item() wrong");
+
+ CYG_TEST_INFO("Testing get(), tryget()");
+
+ i = (cyg_count8)cyg_mbox_tryget(m0);
+ CYG_TEST_CHECK( 55 == i, "Got wrong message" );
+ for(j=1; j<u;j++) {
+ CYG_TEST_CHECK( j == (cyg_count8)cyg_mbox_peek_item(m0), "peek_item()" );
+ CYG_TEST_CHECK( cyg_mbox_peek(m0) == u - j, "peek() wrong" );
+ i = (cyg_count8)cyg_mbox_get(m0);
+ CYG_TEST_CHECK( j == i, "Got wrong message" );
+ }
+
+ CYG_TEST_CHECK( NULL == cyg_mbox_peek_item(m0), "peek_item()" );
+ CYG_TEST_CHECK( 0 == cyg_mbox_peek(m0), "peek()");
+
+ // m0 now empty
+
+ CYG_TEST_CHECK(!cyg_mbox_waiting_to_put(m0), "waiting_to_put()");
+ CYG_TEST_CHECK(!cyg_mbox_waiting_to_get(m0), "waiting_to_get()");
+
+ CYG_TEST_INFO("Testing get(), blocking");
+
+ CYG_TEST_CHECK(0==q++, "bad synchronization");
+ cyg_mbox_PUT(m1, (void*)99); // wakes t1
+ i = (cyg_count8)cyg_mbox_get(m0); // sent by t1
+ CYG_TEST_CHECK(3==i, "Recieved wrong message");
+ CYG_TEST_CHECK(2==q++, "bad synchronization");
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ CYG_TEST_CHECK(NULL==cyg_mbox_timed_get(m0, cyg_current_time()+10),
+ "unexpectedly found message");
+ CYG_TEST_CHECK(3==q++, "bad synchronization");
+ // Allow t1 to run as this get times out
+ // t1 must not be waiting...
+ CYG_TEST_CHECK(cyg_mbox_waiting_to_get(m0), "waiting_to_get()");
+
+ cyg_mbox_PUT(m0, (void*)7); // wake t1 from timed get
+#ifdef CYGMTH_MBOX_PUT_CAN_WAIT
+ q=10;
+ while(cyg_mbox_tryput(m0, (void*)6)) // fill m0's queue
+ ;
+ // m0 now contains ( 6 ... 6 )
+ CYG_TEST_CHECK(10==q++, "bad synchronization");
+ cyg_mbox_put(m1, (void*)4); // wake t1
+ CYG_TEST_CHECK(!cyg_mbox_timed_put(m0, (void*)8, cyg_current_time()+10),
+ "timed put() unexpectedly worked");
+ CYG_TEST_CHECK(12==q++, "bad synchronization");
+ // m0 still contains ( 6 ... 6 )
+ cyg_mbox_put(m0, (void*)9);
+ CYG_TEST_CHECK(13==q++, "bad synchronization");
+#endif
+#endif
+ i=(cyg_count8)cyg_mbox_get(m2);
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+static void entry1( cyg_addrword_t data )
+{
+ cyg_count8 i;
+ i = (cyg_count8)cyg_mbox_get(m1);
+ CYG_TEST_CHECK(1==q++, "bad synchronization");
+ cyg_mbox_PUT(m0, (void *)3); // wake t0
+
+#if defined(CYGFUN_KERNEL_THREADS_TIMER)
+ CYG_TEST_INFO("Testing timed functions");
+ CYG_TEST_CHECK(7==(cyg_count8)cyg_mbox_timed_get(m0,cyg_current_time()+20),
+ "timed get()");
+ CYG_TEST_CHECK(4==q++, "bad synchronization");
+#ifdef CYGMTH_MBOX_PUT_CAN_WAIT
+ CYG_TEST_CHECK(4==(cyg_count8)cyg_mbox_get(m1));
+
+ CYG_TEST_CHECK(11==q++, "bad synchronization");
+ thread[0]->delay(20); // allow t0 to reach put on m1
+ CYG_TEST_CHECK(14==q++, "bad synchronization");
+ CYG_TEST_CHECK(cyg_mbox_waiting_to_put(m0), "waiting_to_put()");
+ do {
+ // after first get m0 contains ( 6 .. 6 9 )
+ i=(cyg_count8)cyg_mbox_tryget(m0);
+ } while(6==i);
+ CYG_TEST_CHECK(9==i,"put gone awry");
+#endif
+#endif
+ CYG_TEST_PASS_FINISH("Kernel C API Mbox 1 OK");
+}
+
+void kmbox1_main( void )
+{
+ CYG_TEST_INIT();
+
+ cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "kmbox1-0",
+ (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",
+ (void *)stack[1], STACKSIZE, &thread[1], &thread_obj[1]);
+ cyg_thread_resume(thread[1]);
+
+ cyg_mbox_create( &m0, &mbox0 );
+ cyg_mbox_create( &m1, &mbox1 );
+ cyg_mbox_create( &m2, &mbox2 );
+
+ cyg_scheduler_start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+ kmbox1_main();
+}
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+/* EOF kmbox1.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/kmutex0.c b/cesar/ecos/packages/kernel/current/tests/kmutex0.c
new file mode 100644
index 0000000000..465dfb811e
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kmutex0.c
@@ -0,0 +1,98 @@
+/*=================================================================
+//
+// kmutex0.c
+//
+// Kernel C API Mutex and condition variable test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-23
+// Description: Limited to checking constructors/destructors
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+static cyg_mutex_t mutex0;
+
+static cyg_cond_t cvar0;
+
+static bool flash( void )
+{
+ cyg_mutex_init( &mutex0 );
+ cyg_cond_init( &cvar0, &mutex0 );
+
+ cyg_cond_destroy( &cvar0 );
+ cyg_mutex_destroy( &mutex0 );
+
+ return true;
+}
+
+void kmutex0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ CYG_TEST_PASS_FINISH("Kernel C API Mutex 0 OK");
+}
+
+externC void
+cyg_start( void )
+{
+ kmutex0_main();
+}
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+/* EOF kmutex0.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/kmutex1.c b/cesar/ecos/packages/kernel/current/tests/kmutex1.c
new file mode 100644
index 0000000000..dda80d0219
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kmutex1.c
@@ -0,0 +1,188 @@
+/*=================================================================
+//
+// kmutex1.c
+//
+// Kernel C API Mutex test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-23
+// Description: Tests basic mutex functionality.
+// Omissions: Timed wait.
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+#define NTHREADS 3
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+
+static cyg_mutex_t m0, m1;
+static cyg_cond_t cvar0, cvar1, cvar2;
+
+static cyg_ucount8 m0d=0, m1d=0;
+
+static void finish( cyg_ucount8 t )
+{
+ cyg_mutex_lock( &m1 ); {
+ m1d |= 1<<t;
+ if( 0x7 == m1d )
+ CYG_TEST_PASS_FINISH("Kernel C API Mutex 1 OK");
+ cyg_cond_wait( &cvar2 );
+ } /* cyg_mutex_unlock( &m1 ); */
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+static void entry0( cyg_addrword_t data )
+{
+ cyg_mutex_lock( &m0 ); {
+ CHECK( ! cyg_mutex_trylock( &m0 ) );
+ cyg_mutex_lock( &m1 ); {
+ CHECK( ! cyg_mutex_trylock( &m0 ) );
+ } cyg_mutex_unlock( &m1 );
+ } cyg_mutex_unlock( &m0 );
+
+ cyg_mutex_lock( &m0 ); {
+ while ( 0 == m0d )
+ cyg_cond_wait( &cvar0 );
+ CHECK( 1 == m0d++ );
+ cyg_cond_signal( &cvar0 );
+ while ( 4 != m0d )
+ cyg_cond_wait( &cvar1 );
+ CHECK( 4 == m0d );
+ } cyg_mutex_unlock( &m0 );
+
+ finish( (cyg_ucount8)data );
+}
+
+static void entry1( cyg_addrword_t data )
+{
+ cyg_mutex_lock( &m0 ); {
+ CHECK( cyg_mutex_trylock( &m1 ) ); {
+ } cyg_mutex_unlock( &m1 );
+ } cyg_mutex_unlock( &m0 );
+
+ cyg_mutex_lock( &m0 ); {
+ CHECK( 0 == m0d++ );
+ cyg_cond_broadcast( &cvar0 );
+ } cyg_mutex_unlock( &m0 );
+
+ cyg_mutex_lock( &m0 ); {
+ while( 1 == m0d )
+ cyg_cond_wait( &cvar0 );
+ CHECK( 2 == m0d++ );
+ cyg_cond_signal( &cvar0 );
+ while( 3 == m0d )
+ cyg_cond_wait( &cvar1 );
+ } cyg_mutex_unlock( &m0 );
+
+ finish( (cyg_ucount8)data );
+}
+
+static void entry2( cyg_addrword_t data )
+{
+ cyg_mutex_lock( &m0 ); {
+ while( 3 != m0d ) {
+ cyg_cond_wait( &cvar0 );
+ }
+ CHECK( 3 == m0d++ );
+ cyg_cond_broadcast( &cvar1 );
+ } cyg_mutex_unlock( &m0 );
+
+ finish( (cyg_ucount8)data );
+}
+
+void kmutex1_main( void )
+{
+ CYG_TEST_INIT();
+
+ cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "kmutex1-0",
+ (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
+ cyg_thread_resume(thread[0]);
+
+ cyg_thread_create(4, entry1 , (cyg_addrword_t)1, "kmutex1-1",
+ (void *)stack[1], STACKSIZE, &thread[1], &thread_obj[1]);
+ cyg_thread_resume(thread[1]);
+
+ cyg_thread_create(4, entry2 , (cyg_addrword_t)2, "kmutex1-2",
+ (void *)stack[2], STACKSIZE, &thread[2], &thread_obj[2]);
+ cyg_thread_resume(thread[2]);
+
+ cyg_mutex_init( &m0 );
+ cyg_mutex_init( &m1 );
+
+ cyg_cond_init( &cvar0, &m0 );
+ cyg_cond_init( &cvar1, &m0 );
+ cyg_cond_init( &cvar2, &m1 );
+
+ cyg_scheduler_start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+ kmutex1_main();
+}
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+/* EOF kmutex1.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/kmutex3.c b/cesar/ecos/packages/kernel/current/tests/kmutex3.c
new file mode 100644
index 0000000000..5dba368b81
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kmutex3.c
@@ -0,0 +1,639 @@
+//==========================================================================
+//
+// kmutex3.c
+//
+// Mutex test 3 - priority inheritance
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 2000-01-06, 2001-08-10
+// Description: Tests mutex priority inheritance. This is simply a
+// translation of the similarly named kernel test to the
+// KAPI, with the intention of also testing the new
+// "set the protocol at run-time" extensions.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/infra/diag.h> // diag_printf
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+// ------------------------------------------------------------------------
+//
+// These checks should be enough; any other scheduler which has priorities
+// should manifest as having no priority inheritance, but otherwise fine,
+// so the test should work correctly.
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \
+ (CYGNUM_KERNEL_SCHED_PRIORITIES > 20) && \
+ defined(CYGFUN_KERNEL_API_C) && \
+ !defined(CYGPKG_KERNEL_SMP_SUPPORT)
+
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h> // diag_printf
+
+
+// ------------------------------------------------------------------------
+// manufacture a simpler feature test macro for priority inheritance than
+// the configuration gives us. We have priority inheritance if it is configured
+// as the only protocol, or if it is the default protocol for dynamic protocol
+// choice.
+
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_INHERIT
+# define PRIORITY_INHERITANCE "dynamic-default-inherit"
+# endif
+# else
+# define PRIORITY_INHERITANCE "static-inherit"
+# endif
+#endif
+
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_CEILING
+# if CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY <= 5
+# define PRIORITY_INHERITANCE "dynamic-default-ceiling-high"
+# elif CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY >= 15
+# define NO_PRIORITY_INHERITANCE "dynamic-default-ceiling-low"
+# else
+# define PRIORITY_UNKNOWN "dynamic-default-ceiling-mid"
+# endif
+# endif
+# else
+# if CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY <= 5
+# define PRIORITY_INHERITANCE "static-ceiling-high"
+# elif CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY >= 15
+# define NO_PRIORITY_INHERITANCE "static-ceiling-low"
+# else
+# define PRIORITY_UNKNOWN "static-ceiling-mid"
+# endif
+# endif
+#endif
+
+#ifndef PRIORITY_INHERITANCE
+# ifndef NO_PRIORITY_INHERITANCE
+# define NO_PRIORITY_INHERITANCE "no scheme selected"
+# endif
+#endif
+
+// ------------------------------------------------------------------------
+// Management functions
+//
+// Stolen from testaux.hxx and copied in here because I want to be able to
+// reset the world also.
+//
+// Translated into KAPI also.
+
+#define NTHREADS 7
+
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS] = { 0 };
+
+typedef cyg_uint64 CYG_ALIGNMENT_TYPE;
+
+static cyg_thread thread_obj[NTHREADS];
+
+static CYG_ALIGNMENT_TYPE stack[NTHREADS] [
+ (STACKSIZE+sizeof(CYG_ALIGNMENT_TYPE)-1)
+ / sizeof(CYG_ALIGNMENT_TYPE) ];
+
+static volatile int nthreads = 0;
+
+#undef NULL
+#define NULL (0)
+
+static cyg_handle_t new_thread( cyg_thread_entry_t *entry,
+ cyg_addrword_t data,
+ cyg_addrword_t priority,
+ int do_resume )
+{
+ int _nthreads = nthreads++;
+
+ CYG_ASSERT(_nthreads < NTHREADS,
+ "Attempt to create more than NTHREADS threads");
+
+ cyg_thread_create( priority,
+ entry,
+ data,
+ NULL, // no name
+ (void *)(stack[_nthreads]),
+ STACKSIZE,
+ &thread[_nthreads],
+ &thread_obj[_nthreads] );
+
+ if ( do_resume )
+ cyg_thread_resume( thread[_nthreads] );
+
+ return thread[_nthreads];
+}
+
+
+static void kill_threads( void )
+{
+ CYG_ASSERT(nthreads <= NTHREADS,
+ "More than NTHREADS threads");
+ CYG_ASSERT( cyg_thread_self() == thread[0],
+ "kill_threads() not called from thread 0");
+ while ( nthreads > 1 ) {
+ nthreads--;
+ if ( NULL != thread[nthreads] ) {
+ do
+ cyg_thread_kill( thread[nthreads] );
+ while ( ! cyg_thread_delete ( thread[nthreads] ) );
+ thread[nthreads] = NULL;
+ }
+ }
+ CYG_ASSERT(nthreads == 1,
+ "No threads left");
+}
+
+// ------------------------------------------------------------------------
+
+#define DELAYFACTOR 1 // for debugging
+
+// ------------------------------------------------------------------------
+
+static cyg_mutex_t mutex_obj;
+static cyg_mutex_t *mutex;
+
+// These are for reporting back to the master thread
+volatile int got_it = 0;
+volatile int t3ran = 0;
+volatile int t3ended = 0;
+volatile int extras[4] = {0,0,0,0};
+
+volatile int go_flag = 0; // but this one controls thread 3 from thread 2
+
+// ------------------------------------------------------------------------
+// 0 to 3 of these run generally to interfere with the other processing,
+// to cause multiple prio inheritances, and clashes in any orders.
+
+static void extra_thread( cyg_addrword_t data )
+{
+ cyg_handle_t self = cyg_thread_self();
+
+#define XINFO( z ) \
+ do { z[13] = '0' + data; CYG_TEST_INFO( z ); } while ( 0 )
+
+ static char running[] = "Extra thread Xa running";
+ static char exiting[] = "Extra thread Xa exiting";
+ static char resumed[] = "Extra thread Xa resumed";
+ static char locked[] = "Extra thread Xa locked";
+ static char unlocked[] = "Extra thread Xa unlocked";
+
+ XINFO( running );
+
+ cyg_thread_suspend( self );
+
+ XINFO( resumed );
+
+ cyg_mutex_lock( mutex );
+
+ XINFO( locked );
+
+ cyg_mutex_unlock( mutex );
+
+ XINFO( unlocked );
+
+ extras[ data ] ++;
+
+ XINFO( exiting );
+
+}
+
+// ------------------------------------------------------------------------
+
+static void t1( cyg_addrword_t data )
+{
+ cyg_handle_t self = cyg_thread_self();
+
+ CYG_TEST_INFO( "Thread 1 running" );
+
+ cyg_thread_suspend( self );
+
+ cyg_mutex_lock( mutex );
+
+ got_it++;
+
+ CYG_TEST_CHECK( 0 == t3ended, "T3 ended prematurely [T1,1]" );
+
+ cyg_mutex_unlock( mutex );
+
+ CYG_TEST_CHECK( 0 == t3ended, "T3 ended prematurely [T1,2]" );
+
+ // That's all.
+
+ CYG_TEST_INFO( "Thread 1 exit" );
+}
+
+// ------------------------------------------------------------------------
+
+static void t2( cyg_addrword_t data )
+{
+ cyg_handle_t self = cyg_thread_self();
+ int i;
+ cyg_tick_count_t then, now;
+
+ CYG_TEST_INFO( "Thread 2 running" );
+
+ CYG_TEST_CHECK( 0 == (data & ~0x77), "Bad T2 arg: extra bits" );
+ CYG_TEST_CHECK( 0 == (data & (data >> 4)), "Bad T2 arg: overlap" );
+
+ cyg_thread_suspend( self );
+
+ // depending on our config argument, optionally restart some of the
+ // extra threads to throw noise into the scheduler:
+ for ( i = 0; i < 3; i++ )
+ if ( (1 << i) & data ) // bits 0-2 control
+ cyg_thread_resume( thread[i+4] ); // extras are thread[4-6]
+
+ cyg_thread_delay( DELAYFACTOR * 10 ); // let those threads run
+
+ cyg_scheduler_lock(); // do this next lot atomically
+
+ go_flag = 1; // unleash thread 3
+ cyg_thread_resume( thread[1] ); // resume thread 1
+
+ // depending on our config argument, optionally restart some of the
+ // extra threads to throw noise into the scheduler at this later point:
+ for ( i = 4; i < 7; i++ )
+ if ( (1 << i) & data ) // bits 4-6 control
+ cyg_thread_resume( thread[i] ); // extras are thread[4-6]
+
+ cyg_scheduler_unlock(); // let scheduling proceed
+
+ // Need a delay (but not a CPU yield) to allow t3 to awaken and act on
+ // the go_flag, otherwise we check these details below too soon.
+ // Actually, waiting for the clock to tick a couple of times would be
+ // better, so that is what we will do. Must be a busy-wait.
+ then = cyg_current_time();
+ do {
+ now = cyg_current_time();
+ // Wait longer than the delay in t3 waiting on go_flag
+ } while ( now < (then + 3) );
+
+#ifdef PRIORITY_UNKNOWN
+ CYG_TEST_INFO( "Not checking: " PRIORITY_UNKNOWN );
+#else
+#ifdef PRIORITY_INHERITANCE
+ CYG_TEST_INFO( "Checking priority scheme: " PRIORITY_INHERITANCE );
+ CYG_TEST_CHECK( 1 == t3ran, "Thread 3 did not run" );
+ CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+#else
+ CYG_TEST_INFO( "Checking NO priority scheme: " NO_PRIORITY_INHERITANCE );
+ CYG_TEST_CHECK( 0 == t3ran, "Thread 3 DID run" );
+ CYG_TEST_CHECK( 0 == got_it, "Thread 1 DID get the mutex" );
+#endif
+#endif
+
+ CYG_TEST_CHECK( 0 == t3ended, "Thread 3 ended prematurely [T2,1]" );
+
+ cyg_thread_delay( DELAYFACTOR * 20 ); // let those threads run
+
+ CYG_TEST_CHECK( 1 == t3ran, "Thread 3 did not run" );
+ CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+ CYG_TEST_CHECK( 1 == t3ended, "Thread 3 has not ended" );
+
+ for ( i = 0; i < 3; i++ )
+ if ( (1 << i) & (data | data >> 4) ) // bits 0-2 and 4-6 control
+ CYG_TEST_CHECK( 1 == extras[i+1], "Extra thread did not run" );
+ else
+ CYG_TEST_CHECK( 0 == extras[i+1], "Extra thread ran" );
+
+ CYG_TEST_PASS( "Thread 2 exiting, AOK" );
+ // That's all: restart the control thread.
+ cyg_thread_resume( thread[0] );
+}
+
+// ------------------------------------------------------------------------
+
+static void t3( cyg_addrword_t data )
+{
+ CYG_TEST_INFO( "Thread 3 running" );
+
+ cyg_mutex_lock( mutex );
+
+ cyg_thread_delay( DELAYFACTOR * 5 ); // let thread 3a run
+
+ cyg_thread_resume( thread[2] ); // resume thread 2
+
+ while ( 0 == go_flag )
+ cyg_thread_delay(1); // wait until we are told to go
+
+ t3ran ++; // record the fact
+
+ CYG_TEST_CHECK( 0 == got_it, "Thread 1 claims to have got my mutex" );
+
+ cyg_mutex_unlock( mutex );
+
+ t3ended ++; // record that we came back
+
+ CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+
+ CYG_TEST_INFO( "Thread 3 exit" );
+}
+
+// ------------------------------------------------------------------------
+
+static void control_thread( cyg_addrword_t data )
+{
+ cyg_handle_t self = cyg_thread_self();
+ int i, z;
+
+ CYG_TEST_INIT();
+ CYG_TEST_INFO( "Control Thread running" );
+
+ // Go through the 27 possibilities of resuming the extra threads
+ // 0: not at all
+ // 1: early in the process
+ // 2: later on
+ // which are represented by bits 0-3 and 4-6 resp in the argument to
+ // thread 2 (none set means no resume at all).
+ for ( i = 0; i < 27; i++ ) {
+ static int xx[] = { 0, 1, 16 };
+ int j = i % 3;
+ int k = (i / 3) % 3;
+ int l = (i / 9) % 3;
+
+ int d = xx[j] | (xx[k]<<1) | (xx[l]<<2) ;
+
+ if ( cyg_test_is_simulator && (0 != i && 13 != i && 26 != i) )
+ continue; // 13 is 111 base 3, 26 is 222 base 3
+
+#ifdef PRIORITY_INHERITANCE
+ // If the simple scheme plus relay enhancement, or any other
+ // *complete* scheme, we can run all three ancillary threads no
+ // problem, so no special action here.
+
+#else
+ // If no priority inheritance at all, running threads 1a and 2a is
+ // OK, but not thread 3a; it blocks the world.
+ if ( l ) // Cannot run thread 3a if no
+ break; // priority inheritance at all.
+#endif
+
+ mutex = &mutex_obj;
+ cyg_mutex_init( mutex );
+
+ got_it = 0;
+ t3ran = 0;
+ t3ended = 0;
+ for ( z = 0; z < 4; z++ ) extras[z] = 0;
+ go_flag = 0;
+
+ new_thread( t1, 0, 5, 1 ); // Slot 1
+ new_thread( t2, d, 10, 1 ); // Slot 2
+ new_thread( t3, 0, 15, 1 ); // Slot 3
+
+ new_thread( extra_thread, 1, 8, j ); // Slot 4
+ new_thread( extra_thread, 2, 12, k ); // Slot 5
+ new_thread( extra_thread, 3, 17, l ); // Slot 6
+
+ {
+ static char *a[] = { "inactive", "run early", "run late" };
+ diag_printf( "\n----- [%2d] New Cycle: 0x%02x, Threads 1a %s, 2a %s, 3a %s -----\n",
+ i, d, a[j], a[k], a[l] );
+ }
+
+ cyg_thread_suspend( self );
+
+ kill_threads();
+ cyg_mutex_destroy( mutex );
+ }
+ CYG_TEST_EXIT( "Control Thread exit" );
+}
+
+// ------------------------------------------------------------------------
+
+externC void
+cyg_user_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ new_thread( control_thread, 0, 2, 1 );
+}
+
+#else // CYGVAR_KERNEL_COUNTERS_CLOCK &c
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("KMutex3 test requires:\n"
+ "CYGFUN_KERNEL_API_C &&\n"
+ "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
+ "(CYGNUM_KERNEL_SCHED_PRIORITIES > 20) &&\n"
+ "!defined(CYGPKG_KERNEL_SMP_SUPPORT)\n");
+ CYG_TEST_NA("KMutex3 test requirements");
+}
+#endif // CYGVAR_KERNEL_COUNTERS_CLOCK &c
+
+
+// ------------------------------------------------------------------------
+// Documentation: enclosed is the design of this test.
+//
+// It has been carefully constructed so that it does NOT use other kernel
+// facilities (aside from delay-task) to test that priority inheritance is
+// working, or not, as intended by the configuration.
+//
+// These notes describe the flow of control in one run of the test with the
+// ancillary tasks optionally interspersed. The details of how those extra
+// tasks are or are not allowed to run are not described.
+//
+//
+//
+// The only change in the test that depends on whether there is inheritance or
+// not is the check in thread 2 on "3-ran" and "got it" flags marked ****
+//
+//
+// volatile &c booleans:
+// "got it" = FALSE
+// "3-ran" = FALSE
+// "3-ended" = FALSE
+// "extras"[3] = FALSE
+//
+// thread 1. prio 5, self-suspend.
+//
+// thread 1a, prio 8, self-suspend.
+//
+// thread 2. prio 10, self-suspend.
+//
+// thread 2a, prio 12, self-suspend.
+//
+// thread 3. prio 15, runs, lock mutex, resume(2)
+//
+// thread 3a, prio 17, self-suspend.
+//
+// 2. runs,
+// 2. resume(3a) +++OPTIONAL
+// 2. resume(2a) +++OPTIONAL
+// 2. resume(1a) +++OPTIONAL
+// [1a lock-fail] thread 3->prio := 8
+//
+// [3. runs maybe, does the looping thing]
+//
+// 2. sleep a while...
+//
+// [2a lock-fail] thread 3->prio := 12
+//
+// [3. runs maybe, does the looping thing]
+//
+// [3a lock-fail] thread 3->prio unchanged
+//
+// [3. runs maybe, does the looping thing]
+//
+// 2. lock scheduler
+// 2. set "go-flag"
+// 2. resume(1)
+// 2. resume(1a) +++OPTIONAL
+// 2. resume(2a) +++OPTIONAL
+// 2. resume(3a) +++OPTIONAL
+// 2. unlock scheduler
+//
+// 1. runs, lock mutex - thread 3 has it locked
+//
+// 2. busy-waits a bit for thread 3 to come out of its delay() loop.
+// This must be a *busy*wait so that 3 can only run via the
+// inherited raised priority.
+//
+// [xa. all do the same: lock mutex, ]
+// [xa. unlock mutex ]
+// [xa. set a flag "extras"[x] to say we are done. ]
+// [xa. exit ]
+//
+//
+//
+// INHERIT
+// -------
+//
+// thread 3->prio := 5
+//
+// 3. runs,
+// 3. set a flag to say "3-ran",
+// 3. loop with a sleep(1) until "go-flag" is set.
+// 3. check "got it" is false,
+// 3. then unlock mutex,
+//
+// thread 3->prio := 15
+//
+// 1. runs, set a flag to say "got it",
+// 1. check "3-ended" flag is false
+// 1. unlock mutex,
+// 1. check "3-ended" flag is still false
+// 1. exit.
+//
+// [1a locks, unlocks, exits]
+//
+// 2. runs, check "3-ran" and "got it" flags are TRUE ****
+// 2. check "3-ended" flag is false
+// 2. sleeps for a while so that...
+//
+// [2a locks, unlocks, exits]
+//
+// 3. runs, set "3-ended" flag,
+// 3. check "3-ran" and "got it" flags
+// 3. exit
+//
+// [3a locks, unlocks, exits]
+//
+// 2. awakens, checks all flags true,
+// 2. check that all "extra" threads that we started have indeed run
+// 2. end of test.
+//
+//
+//
+//
+// NO-INHERIT
+// ----------
+// thread 1 is waiting on the mutex
+//
+// [1a lock-fail]
+//
+// 2. runs, checks that "3-ran" and "got it" flags are FALSE ****
+// 2. check "3-ended" flag is false
+// 2. sleeps for a while so that...
+//
+// [2a. lock-fail]
+//
+// 3. runs, set a flag to say "3-ran",
+// 3. check "got it" is false,
+// 3. then unlock mutex,
+//
+// 1. runs, set a flag to say "got it",
+// 1. check "3-ended" flag is false
+// 1. unlock mutex,
+// 1. check "3-ended" flag is still false
+// 1. exit.
+//
+// [1a locks, unlocks, exits]
+// [2a locks, unlocks, exits]
+//
+// 3. runs, set "3-ended" flag,
+// 3. check "3-ran" and "got it" flags
+// 3. exit
+//
+// [3a locks, unlocks, exits]
+//
+// 2. awakens, checks all flags true,
+// 2. check that all "extra" threads that we started have indeed run
+// 2. end of test.
+//
+//
+// (the end)
+//
+//
+// ------------------------------------------------------------------------
+
+// EOF mutex3.c
diff --git a/cesar/ecos/packages/kernel/current/tests/kmutex4.c b/cesar/ecos/packages/kernel/current/tests/kmutex4.c
new file mode 100644
index 0000000000..c7539176dd
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kmutex4.c
@@ -0,0 +1,526 @@
+//==========================================================================
+//
+// kmutex4.c
+//
+// Mutex test 4 - dynamic priority inheritance protocol
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 2000-01-06, 2001-08-10, 2001-08-21
+// Description: Tests mutex priority inheritance. This is an extension of
+// kmutex3.c, to test the new "set the protocol at run-time"
+// extensions.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/infra/diag.h> // diag_printf
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+// ------------------------------------------------------------------------
+//
+// These checks should be enough; any other scheduler which has priorities
+// should manifest as having no priority inheritance, but otherwise fine,
+// so the test should work correctly.
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \
+ (CYGNUM_KERNEL_SCHED_PRIORITIES > 20) && \
+ defined(CYGFUN_KERNEL_API_C) && \
+ !defined(CYGPKG_KERNEL_SMP_SUPPORT) && \
+ defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC) \
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h> // diag_printf
+
+// ------------------------------------------------------------------------
+
+#define nVERBOSE
+
+// ------------------------------------------------------------------------
+// We have dynamic protocol choice, so we can set the protocol to whatever
+// we want. We'll do these combinations:
+// NONE
+// INHERIT
+// CEILING = 4 = higher than any thread === INHERIT in behaviour
+// CEILING = 11 = mixed in with threads === cannot check anything
+// CEILING = 17 = lower than any threads === NONE in behaviour
+
+#define PROTO_NONE (0)
+#define PROTO_INHERIT (1)
+#define PROTO_CEILING_HIGH (2)
+#define PROTO_CEILING_MID (3)
+#define PROTO_CEILING_LOW (4)
+
+int proto;
+
+static char * protnames[] = {
+ "none",
+ "inherit",
+ "high ceiling",
+ "medium ceiling",
+ "low ceiling",
+};
+
+// ------------------------------------------------------------------------
+// Management functions
+//
+// Stolen from testaux.hxx and copied in here because I want to be able to
+// reset the world also.
+//
+// Translated into KAPI also.
+
+#define NTHREADS 7
+
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS] = { 0 };
+
+typedef cyg_uint64 CYG_ALIGNMENT_TYPE;
+
+static cyg_thread thread_obj[NTHREADS];
+
+static CYG_ALIGNMENT_TYPE stack[NTHREADS] [
+ (STACKSIZE+sizeof(CYG_ALIGNMENT_TYPE)-1)
+ / sizeof(CYG_ALIGNMENT_TYPE) ];
+
+static volatile int nthreads = 0;
+
+#undef NULL
+#define NULL (0)
+
+static cyg_handle_t new_thread( cyg_thread_entry_t *entry,
+ cyg_addrword_t data,
+ cyg_addrword_t priority,
+ int do_resume,
+ char *name )
+{
+ int _nthreads = nthreads++;
+
+ CYG_ASSERT(_nthreads < NTHREADS,
+ "Attempt to create more than NTHREADS threads");
+
+ cyg_thread_create( priority,
+ entry,
+ data,
+ name,
+ (void *)(stack[_nthreads]),
+ STACKSIZE,
+ &thread[_nthreads],
+ &thread_obj[_nthreads] );
+
+ if ( do_resume )
+ cyg_thread_resume( thread[_nthreads] );
+
+ return thread[_nthreads];
+}
+
+
+static void kill_threads( void )
+{
+ CYG_ASSERT(nthreads <= NTHREADS,
+ "More than NTHREADS threads");
+ CYG_ASSERT( cyg_thread_self() == thread[0],
+ "kill_threads() not called from thread 0");
+ while ( nthreads > 1 ) {
+ nthreads--;
+ if ( NULL != thread[nthreads] ) {
+ do
+ cyg_thread_kill( thread[nthreads] );
+ while ( ! cyg_thread_delete ( thread[nthreads] ) );
+ thread[nthreads] = NULL;
+ }
+ }
+ CYG_ASSERT(nthreads == 1,
+ "No threads left");
+}
+
+// ------------------------------------------------------------------------
+
+#define DELAYFACTOR 1 // for debugging
+
+// ------------------------------------------------------------------------
+
+static cyg_mutex_t mutex_obj;
+static cyg_mutex_t *mutex;
+
+// These are for reporting back to the master thread
+volatile int got_it = 0;
+volatile int t3ran = 0;
+volatile int t3ended = 0;
+volatile int extras[4] = {0,0,0,0};
+
+volatile int go_flag = 0; // but this one controls thread 3 from thread 2
+
+// ------------------------------------------------------------------------
+// 0 to 3 of these run generally to interfere with the other processing,
+// to cause multiple prio inheritances, and clashes in any orders.
+
+static void extra_thread( cyg_addrword_t data )
+{
+ cyg_handle_t self = cyg_thread_self();
+
+
+#ifdef VERBOSE
+#define xXINFO( z ) \
+ do { z[13] = '0' + data; CYG_TEST_INFO( z ); } while ( 0 )
+
+ static char running[] = "Extra thread Xa running";
+ static char exiting[] = "Extra thread Xa exiting";
+ static char resumed[] = "Extra thread Xa resumed";
+ static char locked[] = "Extra thread Xa locked";
+ static char unlocked[] = "Extra thread Xa unlocked";
+#else
+#define XINFO( z ) /* nothing */
+#endif
+
+ XINFO( running );
+
+ cyg_thread_suspend( self );
+
+ XINFO( resumed );
+
+ cyg_mutex_lock( mutex );
+
+ XINFO( locked );
+
+ cyg_mutex_unlock( mutex );
+
+ XINFO( unlocked );
+
+ extras[ data ] ++;
+
+ XINFO( exiting );
+
+}
+
+// ------------------------------------------------------------------------
+
+static void t1( cyg_addrword_t data )
+{
+ cyg_handle_t self = cyg_thread_self();
+#ifdef VERBOSE
+ CYG_TEST_INFO( "Thread 1 running" );
+#endif
+ cyg_thread_suspend( self );
+
+ cyg_mutex_lock( mutex );
+
+ got_it++;
+
+ CYG_TEST_CHECK( 0 == t3ended, "T3 ended prematurely [T1,1]" );
+
+ cyg_mutex_unlock( mutex );
+
+ CYG_TEST_CHECK( 0 == t3ended, "T3 ended prematurely [T1,2]" );
+
+ // That's all.
+#ifdef VERBOSE
+ CYG_TEST_INFO( "Thread 1 exit" );
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+static void t2( cyg_addrword_t data )
+{
+ cyg_handle_t self = cyg_thread_self();
+ int i;
+ cyg_tick_count_t then, now;
+#ifdef VERBOSE
+ CYG_TEST_INFO( "Thread 2 running" );
+#endif
+ CYG_TEST_CHECK( 0 == (data & ~0x77), "Bad T2 arg: extra bits" );
+ CYG_TEST_CHECK( 0 == (data & (data >> 4)), "Bad T2 arg: overlap" );
+
+ cyg_thread_suspend( self );
+
+ // depending on our config argument, optionally restart some of the
+ // extra threads to throw noise into the scheduler:
+ for ( i = 0; i < 3; i++ )
+ if ( (1 << i) & data ) // bits 0-2 control
+ cyg_thread_resume( thread[i+4] ); // extras are thread[4-6]
+
+ cyg_thread_delay( DELAYFACTOR * 10 ); // let those threads run
+
+ cyg_scheduler_lock(); // do this next lot atomically
+
+ go_flag = 1; // unleash thread 3
+ cyg_thread_resume( thread[1] ); // resume thread 1
+
+ // depending on our config argument, optionally restart some of the
+ // extra threads to throw noise into the scheduler at this later point:
+ for ( i = 4; i < 7; i++ )
+ if ( (1 << i) & data ) // bits 4-6 control
+ cyg_thread_resume( thread[i] ); // extras are thread[4-6]
+
+ cyg_scheduler_unlock(); // let scheduling proceed
+
+ // Need a delay (but not a CPU yield) to allow t3 to awaken and act on
+ // the go_flag, otherwise we check these details below too soon.
+ // Actually, waiting for the clock to tick a couple of times would be
+ // better, so that is what we will do. Must be a busy-wait.
+ then = cyg_current_time();
+ do {
+ now = cyg_current_time();
+ // Wait longer than the delay in t3 waiting on go_flag
+ } while ( now < (then + 3) );
+
+ // Check for whatever result we expect from the protocol selected:
+ // This mirrors what is done in configury in kmutex3.c and mutex3.cxx
+ if ( PROTO_CEILING_MID == proto ) {
+ CYG_TEST_INFO( "Not checking: ceiling mid value" );
+ }
+ else if ( PROTO_INHERIT == proto ||
+ PROTO_CEILING_HIGH == proto ) {
+ CYG_TEST_INFO( "Checking priority scheme operating" );
+ CYG_TEST_CHECK( 1 == t3ran, "Thread 3 did not run" );
+ CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+ }
+ else {
+ CYG_TEST_INFO( "Checking NO priority scheme operating" );
+ CYG_TEST_CHECK( 0 == t3ran, "Thread 3 DID run" );
+ CYG_TEST_CHECK( 0 == got_it, "Thread 1 DID get the mutex" );
+ }
+
+ CYG_TEST_CHECK( 0 == t3ended, "Thread 3 ended prematurely [T2,1]" );
+
+ cyg_thread_delay( DELAYFACTOR * 20 ); // let those threads run
+
+ CYG_TEST_CHECK( 1 == t3ran, "Thread 3 did not run" );
+ CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+ CYG_TEST_CHECK( 1 == t3ended, "Thread 3 has not ended" );
+
+ for ( i = 0; i < 3; i++ )
+ if ( (1 << i) & (data | data >> 4) ) // bits 0-2 and 4-6 control
+ CYG_TEST_CHECK( 1 == extras[i+1], "Extra thread did not run" );
+ else
+ CYG_TEST_CHECK( 0 == extras[i+1], "Extra thread ran" );
+
+ CYG_TEST_PASS( "Thread 2 exiting, AOK" );
+ // That's all: restart the control thread.
+ cyg_thread_resume( thread[0] );
+}
+
+// ------------------------------------------------------------------------
+
+static void t3( cyg_addrword_t data )
+{
+#ifdef VERBOSE
+ CYG_TEST_INFO( "Thread 3 running" );
+#endif
+ cyg_mutex_lock( mutex );
+
+ cyg_thread_delay( DELAYFACTOR * 5 ); // let thread 3a run
+
+ cyg_thread_resume( thread[2] ); // resume thread 2
+
+ while ( 0 == go_flag )
+ cyg_thread_delay(1); // wait until we are told to go
+
+ t3ran ++; // record the fact
+
+ CYG_TEST_CHECK( 0 == got_it, "Thread 1 claims to have got my mutex" );
+
+ cyg_mutex_unlock( mutex );
+
+ t3ended ++; // record that we came back
+
+ CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+#ifdef VERBOSE
+ CYG_TEST_INFO( "Thread 3 exit" );
+#endif
+}
+
+// ------------------------------------------------------------------------
+
+static void control_thread( cyg_addrword_t data )
+{
+ cyg_handle_t self = cyg_thread_self();
+ int i, z;
+
+ CYG_TEST_INIT();
+ CYG_TEST_INFO( "Control Thread running" );
+
+ // Go through the 27 possibilities of resuming the extra threads
+ // 0: not at all
+ // 1: early in the process
+ // 2: later on
+ // which are represented by bits 0-3 and 4-6 resp in the argument to
+ // thread 2 (none set means no resume at all).
+ for ( i = 0; i < 27; i++ ) {
+ static int xx[] = { 0, 1, 16 };
+ int j = i % 3;
+ int k = (i / 3) % 3;
+ int l = (i / 9) % 3;
+
+ int d = xx[j] | (xx[k]<<1) | (xx[l]<<2) ;
+
+ if ( cyg_test_is_simulator && (0 != i && 13 != i && 26 != i) )
+ continue; // 13 is 111 base 3, 26 is 222 base 3
+
+ // Go through all these priority inversion prevention protocols:
+ // (if supported in this configuration)
+ // PROTO_NONE (0)
+ // PROTO_INHERIT (1)
+ // PROTO_CEILING_HIGH (2)
+ // PROTO_CEILING_MID (3)
+ // PROTO_CEILING_LOW (4)
+ for ( proto = PROTO_NONE; proto <= PROTO_CEILING_LOW; proto++ ) {
+
+ // If no priority inheritance at all, running threads 1a and 2a is
+ // OK, but not thread 3a; it blocks the world.
+ if ( PROTO_NONE == proto ||
+ PROTO_CEILING_MID == proto ||
+ PROTO_CEILING_LOW == proto )
+ if ( l ) // Cannot run thread 3a if no
+ continue; // priority inheritance at all.
+
+ mutex = &mutex_obj;
+
+ switch ( proto ) {
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_NONE
+ case PROTO_NONE:
+ cyg_mutex_init( mutex );
+ cyg_mutex_set_protocol( mutex, CYG_MUTEX_NONE );
+ break;
+#endif
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT
+ case PROTO_INHERIT:
+ cyg_mutex_init( mutex );
+ cyg_mutex_set_protocol( mutex, CYG_MUTEX_INHERIT );
+ break;
+#endif
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING
+ case PROTO_CEILING_HIGH:
+ cyg_mutex_init( mutex );
+ cyg_mutex_set_protocol( mutex, CYG_MUTEX_CEILING );
+ cyg_mutex_set_ceiling( mutex, (cyg_priority_t) 4 );
+ break;
+ case PROTO_CEILING_MID:
+ cyg_mutex_init( mutex );
+ cyg_mutex_set_protocol( mutex, CYG_MUTEX_CEILING );
+ cyg_mutex_set_ceiling( mutex, (cyg_priority_t) 11 );
+ break;
+ case PROTO_CEILING_LOW:
+ cyg_mutex_init( mutex );
+ cyg_mutex_set_protocol( mutex, CYG_MUTEX_CEILING );
+ cyg_mutex_set_ceiling( mutex, (cyg_priority_t) 17 );
+ break;
+#endif
+ default:
+ continue; // Break out of the prio for loop - do nothing
+ }
+
+ got_it = 0;
+ t3ran = 0;
+ t3ended = 0;
+ for ( z = 0; z < 4; z++ ) extras[z] = 0;
+ go_flag = 0;
+
+ new_thread( t1, 0, 5, 1, "test 1" ); // Slot 1
+ new_thread( t2, d, 10, 1, "test 2" ); // Slot 2
+ new_thread( t3, 0, 15, 1, "test 3" ); // Slot 3
+
+ new_thread( extra_thread, 1, 8, j, "extra 1" ); // Slot 4
+ new_thread( extra_thread, 2, 12, k, "extra 2" ); // Slot 5
+ new_thread( extra_thread, 3, 17, l, "extra 3" ); // Slot 6
+
+ {
+ static char *a[] = { "inactive", "run early", "run late" };
+ diag_printf( "\n----- %s [%2d] New Cycle: 0x%02x, Threads 1a %s, 2a %s, 3a %s -----\n",
+ protnames[proto], i, d, a[j], a[k], a[l] );
+ }
+
+ cyg_thread_suspend( self );
+
+ kill_threads();
+ cyg_mutex_destroy( mutex );
+ }
+ }
+ CYG_TEST_EXIT( "Control Thread exit" );
+}
+
+// ------------------------------------------------------------------------
+
+externC void
+cyg_user_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ new_thread( control_thread, 0, 2, 1, "control thread" );
+}
+
+#else // CYGVAR_KERNEL_COUNTERS_CLOCK &c
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("KMutex4 test requires:\n"
+ "CYGFUN_KERNEL_API_C &&\n"
+ "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
+ "(CYGNUM_KERNEL_SCHED_PRIORITIES > 20) &&\n"
+ "!defined(CYGPKG_KERNEL_SMP_SUPPORT) &&\n"
+ "defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC)\n"
+ );
+ CYG_TEST_NA("KMutex4 test requirements");
+}
+#endif // CYGVAR_KERNEL_COUNTERS_CLOCK &c
+
+
+// ------------------------------------------------------------------------
+// Documentation: enclosed is the design of this test.
+//
+// See mutex3.cxx or kmutex3.c
+
+// ------------------------------------------------------------------------
+// EOF mutex4.c
diff --git a/cesar/ecos/packages/kernel/current/tests/kphilo.c b/cesar/ecos/packages/kernel/current/tests/kphilo.c
new file mode 100644
index 0000000000..b21207ce86
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kphilo.c
@@ -0,0 +1,236 @@
+//==========================================================================
+//
+// kphilo.c
+//
+// A test of the dining philosophers problem
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-24
+// Description: A test of the dining philosophers problem
+//####DESCRIPTIONEND####
+//
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/kernel/diag.h>
+
+// -------------------------------------------------------------------------
+// Data for the philosophers problem
+
+#define PHILOSOPHERS 15 // number of philosophers
+#define STACKSIZE (2*1024) // size of thread stack
+
+// array of stacks for philosopher threads
+char thread_stack[PHILOSOPHERS][STACKSIZE];
+
+// array of threads.
+cyg_thread thread[PHILOSOPHERS];
+
+cyg_handle_t thread_handle[PHILOSOPHERS];
+
+// array of chopsticks
+cyg_sem_t chopstick[PHILOSOPHERS];
+
+cyg_ucount32 data_index;
+
+// -------------------------------------------------------------------------
+// State recording and display
+
+static char pstate[PHILOSOPHERS+1]; // state vector showing what each
+ // philosopher is doing
+
+cyg_mutex_t state_mutex;
+
+#ifdef CYG_HAL_MN10300_MN103002
+static cyg_count8 eaters = 0;
+#endif
+
+void change_state(int id, char newstate)
+{
+ cyg_mutex_lock(&state_mutex);
+
+#ifdef CYG_HAL_MN10300_MN103002
+ if( pstate[id] == 'E' ) eaters--;
+ if( newstate == 'E' ) eaters++;
+// led(eaters);
+#endif
+
+ pstate[id] = newstate;
+
+ diag_write_string(pstate);
+#if 0
+ diag_write_char(' ');
+ diag_write_dec(Cyg_Scheduler::get_thread_switches());
+#endif
+ diag_write_char('\n');
+
+ cyg_mutex_unlock(&state_mutex);
+
+}
+
+char get_state( int id)
+{
+ char s;
+ cyg_mutex_lock(&state_mutex);
+
+ s = pstate[id];
+
+ cyg_mutex_unlock(&state_mutex);
+
+ return s;
+}
+
+// -------------------------------------------------------------------------
+// Thread to behave like a philosopher
+
+void Philosopher( cyg_addrword_t vid )
+{
+ cyg_uint32 id = (cyg_uint32)vid;
+ cyg_sem_t *first_stick = &chopstick[id];
+ cyg_sem_t *second_stick = &chopstick[(id+1)%PHILOSOPHERS];
+#ifdef CYGPKG_INFRA_DEBUG
+ int left_philo = ((id==0)?PHILOSOPHERS:id)-1;
+ int right_philo = (id==PHILOSOPHERS-1)?0:(id+1);
+#endif
+
+ CYG_ASSERT( id >= 0 && id < PHILOSOPHERS, "Bad id");
+
+ // Deadlock avoidance. The easiest way to make the philosophers
+ // behave is to make each pick up the lowest numbered stick
+ // first. This is how it works out anyway for all the philosophers
+ // except the last, who must have his sticks swapped.
+
+ if( id == PHILOSOPHERS-1 )
+ {
+ cyg_sem_t *t = first_stick;
+ first_stick = second_stick;
+ second_stick = t;
+ }
+
+ for(;;)
+ {
+ cyg_ucount32 val;
+
+ // The following variable is shared by all philosophers.
+ // It is incremented unprotected, but this does not matter
+ // since it is only present to introduce a little variability
+ // into the think and eat times.
+
+ static volatile int cycle = 0;
+
+ // Think for a bit
+
+ cyg_thread_delay((id+cycle++)%12); // Cogito ergo sum...
+
+ // I am now hungry, try to get the chopsticks
+
+ change_state(id,'H');
+
+ // Get the first stick
+ cyg_semaphore_wait(first_stick);
+
+ // Get the second stick
+ cyg_semaphore_wait(second_stick);
+
+ // Got them, now eat
+
+ change_state(id,'E');
+
+ // Check that the world is as I think it is...
+ cyg_semaphore_peek( first_stick, &val);
+ CYG_ASSERT( val == 0, "Not got first stick");
+ cyg_semaphore_peek( second_stick, &val);
+ CYG_ASSERT( val == 0, "Not got second stick");
+ CYG_ASSERT( get_state(left_philo) != 'E', "Left neighbour also eating!!");
+ CYG_ASSERT( get_state(right_philo) != 'E', "Right neighbour also eating!!");
+
+ cyg_thread_delay((id+cycle++)%6); // munch munch
+
+ // Finished eating, put down sticks.
+
+ change_state(id,'T');
+
+ cyg_semaphore_post( first_stick );
+ cyg_semaphore_post( second_stick );
+
+ }
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ int i;
+
+ diag_init();
+
+ diag_write_string("Philosophers\n");
+ diag_write_string("Started\n");
+
+ // Zero last element in state so it acts like
+ // a string.
+ pstate[PHILOSOPHERS] = 0;
+
+#if 1
+ for( i = 0; i < PHILOSOPHERS; i++ )
+ {
+ change_state(i,'T'); // starting state
+
+ cyg_thread_create(4, Philosopher, (cyg_addrword_t)i, "philosopher",
+ (void *)(&thread_stack[i]), STACKSIZE,
+ &thread_handle[i], &thread[i]);
+
+ // resume it
+ cyg_thread_resume(thread_handle[i]);
+
+ // and make the matching chopstick present
+ cyg_semaphore_init( &chopstick[i], 1);
+ }
+#endif
+
+ // Get the world going
+ cyg_scheduler_start();
+
+}
+
+// -------------------------------------------------------------------------
+// EOF kphilo.c
diff --git a/cesar/ecos/packages/kernel/current/tests/ksched1.c b/cesar/ecos/packages/kernel/current/tests/ksched1.c
new file mode 100644
index 0000000000..d1bf1c7d55
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/ksched1.c
@@ -0,0 +1,103 @@
+/*=================================================================
+//
+// ksched1.c
+//
+// Kernel C API Sched test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-23
+// Description: Simply checks the world starts
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+#define NTHREADS 2
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+
+static void entry0( cyg_addrword_t data )
+{
+ CHECK( 222 == (int)data );
+ CYG_TEST_PASS_FINISH( "Kernel C API Sched 1 OK");
+}
+
+void ksched1_main(void)
+{
+ CYG_TEST_INIT();
+
+ cyg_thread_create( 4, entry0 , (cyg_addrword_t)222, "ksched1",
+ (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
+ cyg_thread_resume(thread[0]);
+
+ cyg_scheduler_start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+ ksched1_main();
+}
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+/* EOF ksched1.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/ksem0.c b/cesar/ecos/packages/kernel/current/tests/ksem0.c
new file mode 100644
index 0000000000..4a7f359dc5
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/ksem0.c
@@ -0,0 +1,100 @@
+/*=================================================================
+//
+// ksem0.c
+//
+// Kernel C API Semaphore test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-20
+// Description: Limited to checking initialisation/destruction
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+cyg_sem_t s0, s1, s2;
+
+static bool flash( void )
+{
+ cyg_semaphore_init( &s0, 0 );
+ cyg_semaphore_init( &s1, 1 );
+ cyg_semaphore_init( &s2, 17 );
+
+ cyg_semaphore_destroy( &s0 );
+ cyg_semaphore_destroy( &s1 );
+ cyg_semaphore_destroy( &s2 );
+
+ return true;
+}
+
+void ksem0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ CYG_TEST_PASS_FINISH("Kernel C API Semaphore 0 OK");
+
+}
+
+externC void
+cyg_start( void )
+{
+ ksem0_main();
+}
+
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+/* EOF ksem0.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/ksem1.c b/cesar/ecos/packages/kernel/current/tests/ksem1.c
new file mode 100644
index 0000000000..89ed2cc431
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/ksem1.c
@@ -0,0 +1,169 @@
+/*=================================================================
+//
+// ksem1.c
+//
+// C API semaphore test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-20
+// Description: Tests basic semaphore functionality.
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+#define NTHREADS 2
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+
+static cyg_sem_t s0, s1, s2;
+
+static volatile cyg_ucount8 q = 0;
+
+static void entry0( cyg_addrword_t data )
+{
+ cyg_count32 val;
+
+ cyg_semaphore_wait(&s0);
+ CHECK( 1 == q++ );
+ cyg_semaphore_post(&s1);
+ cyg_semaphore_wait(&s0);
+ CHECK( 3 == q++ );
+ cyg_semaphore_peek(&s0, &val);
+ CHECK( 0 == val);
+ CHECK( ! cyg_semaphore_trywait(&s0) );
+ cyg_semaphore_post(&s0);
+ CHECK( 4 == q++ );
+ cyg_semaphore_peek(&s0, &val);
+ CHECK( 1 == val);
+ cyg_semaphore_post(&s0);
+ cyg_semaphore_peek(&s0, &val);
+ CHECK( 2 == val);
+ cyg_semaphore_post(&s1);
+ cyg_semaphore_peek(&s2, &val);
+ CHECK( 0 == val);
+ cyg_semaphore_wait(&s2);
+ CHECK( 6 == q++ );
+ CYG_TEST_PASS_FINISH("Kernel C API Semaphore 1 OK");
+}
+
+static void entry1( cyg_addrword_t data )
+{
+ cyg_count32 val;
+
+ cyg_semaphore_peek(&s1, &val);
+ CHECK( 2 == val);
+ cyg_semaphore_wait(&s1);
+ cyg_semaphore_peek(&s1, &val);
+ CHECK( 1 == val);
+ cyg_semaphore_wait(&s1);
+ CHECK( 0 == q++ );
+ cyg_semaphore_peek(&s0, &val);
+ CHECK( 0 == val);
+ cyg_semaphore_post(&s0);
+ cyg_semaphore_wait(&s1);
+ CHECK( 2 == q++ );
+ cyg_semaphore_post(&s0);
+ cyg_semaphore_wait(&s1);
+ CHECK( 5 == q++ );
+ cyg_semaphore_peek(&s0, &val);
+ CHECK( 2 == val);
+ CHECK( cyg_semaphore_trywait(&s0) );
+ cyg_semaphore_peek(&s0, &val);
+ CHECK( 1 == val);
+ CHECK( cyg_semaphore_trywait(&s0) );
+ cyg_semaphore_peek(&s0, &val);
+ CHECK( 0 == val);
+ cyg_semaphore_post(&s2);
+ cyg_semaphore_wait(&s0);
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+void ksem1_main( void )
+{
+ CYG_TEST_INIT();
+
+ cyg_semaphore_init( &s0, 0);
+ cyg_semaphore_init( &s1, 2);
+ cyg_semaphore_init( &s2, 0);
+
+ cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "ksem1-0",
+ (void *)stack[0], STACKSIZE,&thread[0], &thread_obj[0]);
+ cyg_thread_resume(thread[0]);
+
+ cyg_thread_create(4, entry1 , (cyg_addrword_t)1, "ksem1-1",
+ (void *)stack[1], STACKSIZE, &thread[1], &thread_obj[1]);
+ cyg_thread_resume(thread[1]);
+
+ cyg_scheduler_start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+ ksem1_main();
+}
+
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+/* EOF ksem1.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/kthread0.c b/cesar/ecos/packages/kernel/current/tests/kthread0.c
new file mode 100644
index 0000000000..eb1deaa4b7
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kthread0.c
@@ -0,0 +1,120 @@
+/*=================================================================
+//
+// kthread0.c
+//
+// Kernel C API Thread test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-18
+// Description: Limited to checking constructors/destructors
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static char stack[STACKSIZE];
+
+static cyg_thread_entry_t entry;
+
+static void entry( cyg_addrword_t data )
+{
+}
+
+static int *p;
+
+#if 0
+static cyg_handle_t t0,t1;
+static cyg_thread thread0, thread1;
+#endif
+
+static cyg_handle_t t2;
+static cyg_thread thread2;
+
+static bool flash( void )
+{
+#if 0 // no facility to allocate stack exists yet.
+ cyg_thread_create( entry, 0x111, NULL, 0, &t0, &thread0 );
+
+ cyg_thread_create( entry, (cyg_addrword_t)&t0, STACKSIZE, 0, &t1, &thread0 );
+#endif
+
+ cyg_thread_create(4, entry, (cyg_addrword_t)p, "kthread0",
+ (void *)stack, STACKSIZE, &t2, &thread2 );
+
+ return true;
+}
+
+void kthread0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ CYG_TEST_PASS_FINISH("Kernel C API Thread 0 OK");
+
+}
+
+externC void
+cyg_start( void )
+{
+ kthread0_main();
+}
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+/* EOF kthread0.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/kthread1.c b/cesar/ecos/packages/kernel/current/tests/kthread1.c
new file mode 100644
index 0000000000..3ceba97802
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/kthread1.c
@@ -0,0 +1,136 @@
+/*=================================================================
+//
+// kthread1.c
+//
+// Kernel C API Thread test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-18
+// Description: Tests some basic thread functions.
+//####DESCRIPTIONEND####
+*/
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_API_C
+
+#include "testaux.h"
+
+#include <cyg/hal/hal_arch.h> // for CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#ifdef CYGNUM_HAL_STACK_SIZE_TYPICAL
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+#else
+#define STACKSIZE 2000
+#endif
+
+static char stack[2][STACKSIZE];
+
+static cyg_thread thread[2];
+
+static cyg_handle_t pt0,pt1;
+
+
+static void entry0( cyg_addrword_t data )
+{
+ CHECK( 222 == (int)data );
+
+ cyg_thread_suspend(pt1);
+ cyg_thread_resume(pt1);
+
+ cyg_thread_delay(1);
+
+ cyg_thread_resume(pt1);
+
+ cyg_thread_delay(1);
+
+ CYG_TEST_PASS_FINISH("Kernel C API Thread 1 OK");
+}
+
+static void entry1( cyg_addrword_t data )
+{
+ cyg_handle_t self;
+ CHECK( 333 == (int)data );
+
+ self = cyg_thread_self();
+
+ CHECK( self == pt1 );
+
+ cyg_thread_suspend(pt1);
+
+ cyg_thread_exit(); // no guarantee this will be called
+}
+
+void kthread1_main( void )
+{
+ CYG_TEST_INIT();
+
+ cyg_thread_create(4, entry0, (cyg_addrword_t)222, "kthread1-0",
+ (void *)stack[0], STACKSIZE, &pt0, &thread[0] );
+ cyg_thread_create(4, entry1, (cyg_addrword_t)333, "kthread1-1",
+ (void *)stack[1], STACKSIZE, &pt1, &thread[1] );
+
+ cyg_thread_resume(pt0);
+ cyg_thread_resume(pt1);
+
+ cyg_scheduler_start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+ kthread1_main();
+}
+
+
+#else /* def CYGFUN_KERNEL_API_C */
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel C API layer disabled");
+}
+#endif /* def CYGFUN_KERNEL_API_C */
+
+/* EOF kthread1.c */
diff --git a/cesar/ecos/packages/kernel/current/tests/mbox1.cxx b/cesar/ecos/packages/kernel/current/tests/mbox1.cxx
new file mode 100644
index 0000000000..443b689bab
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/mbox1.cxx
@@ -0,0 +1,201 @@
+//==========================================================================
+//
+// mbox1.cxx
+//
+// Mbox test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author: dsm
+// Contributors: dsm
+// Date: 1998-05-19
+// Description: Tests basic mbox functionality.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+
+#include <cyg/kernel/mbox.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+#include <cyg/kernel/timer.hxx> // Cyg_Timer
+#include <cyg/kernel/clock.inl> // Cyg_Clock
+
+#define NTHREADS 2
+#include "testaux.hxx"
+
+static Cyg_Mbox m0, m1, m2;
+
+static volatile cyg_atomic q = 0;
+
+#ifndef CYGMTH_MBOX_PUT_CAN_WAIT
+#define PUT tryput
+#endif
+
+static void entry0( CYG_ADDRWORD data )
+{
+ cyg_count8 u,i;
+
+ 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");
+ CYG_TEST_CHECK(NULL==m0.peek_item(), "mbox not initialized properly");
+ m0.PUT((void *)55);
+ CYG_TEST_CHECK(1==m0.peek(), "peek() wrong");
+ CYG_TEST_CHECK(55==(cyg_count8)m0.peek_item(), "peek_item() wrong");
+ for(u=1; m0.tryput((void*)u); u++) {
+ CYG_TEST_CHECK(55==(cyg_count8)m0.peek_item(), "peek_item() wrong");
+ CYG_TEST_CHECK(u+1==m0.peek(), "peek() wrong");
+ }
+ CYG_TEST_CHECK(u == CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE, "mbox not configured size");
+
+ // m0 now contains ( 55 1 2 .. u-1 )
+ CYG_TEST_CHECK(u==m0.peek(), "peek() wrong");
+ CYG_TEST_CHECK(55==(cyg_count8)m0.peek_item(), "peek_item() wrong");
+
+ CYG_TEST_INFO("Testing get(), tryget()");
+
+ i = (cyg_count8)m0.tryget();
+ CYG_TEST_CHECK( 55 == i, "Got wrong message" );
+ for(cyg_count8 j=1; j<u;j++) {
+ CYG_TEST_CHECK( j == (cyg_count8)m0.peek_item(), "peek_item()" );
+ CYG_TEST_CHECK( m0.peek() == u - j, "peek() wrong" );
+ i = (cyg_count8)m0.get();
+ CYG_TEST_CHECK( j == i, "Got wrong message" );
+ }
+
+ CYG_TEST_CHECK( NULL == m0.peek_item(), "peek_item()" );
+ CYG_TEST_CHECK( 0 == m0.peek(), "peek()");
+
+ // m0 now empty
+
+ CYG_TEST_CHECK(!m0.waiting_to_put(), "waiting_to_put()");
+ CYG_TEST_CHECK(!m0.waiting_to_get(), "waiting_to_get()");
+
+ CYG_TEST_INFO("Testing get(), blocking");
+
+ CYG_TEST_CHECK(0==q++, "bad synchronization");
+ m1.PUT((void*)99); // wakes t1
+ i = (cyg_count8)m0.get(); // sent by t1
+ CYG_TEST_CHECK(3==i, "Recieved wrong message");
+ CYG_TEST_CHECK(2==q++, "bad synchronization");
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ CYG_TEST_CHECK(NULL==m0.get(
+ Cyg_Clock::real_time_clock->current_value() + 10),
+ "unexpectedly found message");
+ CYG_TEST_CHECK(3==q++, "bad synchronization");
+ // Allow t1 to run as this get times out
+ // t1 must not be waiting...
+ CYG_TEST_CHECK(m0.waiting_to_get(), "waiting_to_get()");
+
+ m0.PUT((void*)7); // wake t1 from timed get
+#ifdef CYGMTH_MBOX_PUT_CAN_WAIT
+ q=10;
+ while(m0.tryput((void*)6)) // fill m0's queue
+ ;
+ // m0 now contains ( 6 ... 6 )
+ CYG_TEST_CHECK(10==q++, "bad synchronization");
+ m1.put((void*)4); // wake t1
+ CYG_TEST_CHECK(!m0.put((void*)8, 2), "timed put() unexpectedly worked");
+ CYG_TEST_CHECK(12==q++, "bad synchronization");
+ // m0 still contains ( 6 ... 6 )
+ m0.put((void*)9);
+ CYG_TEST_CHECK(13==q++, "bad synchronization");
+#endif
+#endif
+ i=(cyg_count8)m2.get();
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ cyg_count8 i;
+ i = (cyg_count8)m1.get();
+ CYG_TEST_CHECK(1==q++, "bad synchronization");
+ m0.PUT((void *)3); // wake t0
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ CYG_TEST_INFO("Testing timed functions");
+ CYG_TEST_CHECK(7==(cyg_count8)m0.get(
+ Cyg_Clock::real_time_clock->current_value() + 20), "timed get()");
+ CYG_TEST_CHECK(4==q++, "bad synchronization");
+#ifdef CYGMTH_MBOX_PUT_CAN_WAIT
+ CYG_TEST_CHECK(4==(cyg_count8)m1.get());
+
+ CYG_TEST_CHECK(11==q++, "bad synchronization");
+ thread[0]->delay(20); // allow t0 to reach put on m1
+ CYG_TEST_CHECK(14==q++, "bad synchronization");
+ CYG_TEST_CHECK(m0.waiting_to_put(), "waiting_to_put()");
+ do {
+ // after first get m0 contains ( 6 .. 6 9 )
+ i=(cyg_count8)m0.tryget();
+ } while(6==i);
+ CYG_TEST_CHECK(9==i,"put gone awry");
+#endif
+#endif
+ CYG_TEST_PASS_FINISH("Mbox 1 OK");
+}
+
+void mbox1_main( void )
+{
+ CYG_TEST_INIT();
+
+ new_thread(entry0, 0);
+ new_thread(entry1, 1);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ mbox1_main();
+}
+
+// EOF mbox1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/mqueue1.cxx b/cesar/ecos/packages/kernel/current/tests/mqueue1.cxx
new file mode 100644
index 0000000000..3e392cc116
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/mqueue1.cxx
@@ -0,0 +1,411 @@
+/*========================================================================
+//
+// mqueue1.cxx
+//
+// Message queues tests
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2000-05-12
+// Purpose: This file provides tests for eCos mqueues
+// Description:
+// Usage:
+//
+//####DESCRIPTIONEND####
+//
+//======================================================================
+*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/kernel.h>
+
+/* INCLUDES */
+
+#include <cyg/infra/cyg_type.h> // common types and externC
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+#include <cyg/kernel/thread.inl>
+// Specially avoid inlining here due to the way we abuse the mqueue
+// implementation by making lots and lots of calls.
+#define CYGPRI_KERNEL_SYNCH_MQUEUE_INLINE
+#include <cyg/kernel/mqueue.hxx> // Mqueue Header
+#include <cyg/kernel/sema.hxx> // semaphores
+#include <cyg/infra/testcase.h> // test API
+
+// use the common kernel test magic to define 2 threads
+#define NTHREADS 2
+#include "testaux.hxx"
+
+/* GLOBALS */
+
+static char mempool[500];
+static size_t storedmempoollen;
+Cyg_Mqueue *mq;
+static Cyg_Binary_Semaphore t0sem, t1sem;
+static int calledback;
+
+
+/* FUNCTIONS */
+
+static int
+my_memcmp(const void *m1, const void *m2, size_t n)
+{
+ char *s1 = (char *)m1;
+ char *s2 = (char *)m2;
+
+ while (n--) {
+ if (*s1 != *s2)
+ return *s1 - *s2;
+ s1++;
+ s2++;
+ }
+ return 0;
+} // my_memcmp()
+
+static void *
+my_alloc( size_t len )
+{
+ if ( len > sizeof(mempool) )
+ return NULL;
+
+ storedmempoollen = len;
+ return &mempool[0];
+}
+
+static void
+my_free( void *ptr, size_t len )
+{
+ CYG_TEST_PASS_FAIL( (ptr == &mempool[0]) && (len == storedmempoollen),
+ "Freed pool correctly");
+ mq = NULL; // invalidate
+}
+
+static void
+callback(Cyg_Mqueue &mq, CYG_ADDRWORD data)
+{
+ calledback += (int)data;
+}
+
+//************************************************************************
+//************************************************************************
+
+static void
+t0( CYG_ADDRWORD data )
+{
+ Cyg_Mqueue::qerr_t err;
+ char buf[35];
+ size_t len;
+ unsigned int prio;
+ bool b;
+
+ Cyg_Mqueue the_mq(4, 32, &my_alloc, &my_free, &err );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
+ "Create queue" );
+ mq = &the_mq;
+
+//------------------------------------------------------------------------
+
+ err = mq->put( "Peter piper picked", sizeof("Peter piper picked"),
+ 5, true );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err, "Simple (put)");
+
+ t1sem.post();
+
+//------------------------------------------------------------------------
+
+ t0sem.wait();
+
+ err = mq->get( buf, &len, &prio, true );
+ b = (err == Cyg_Mqueue::OK);
+ if (b)
+ b = (len == sizeof("a peck of"));
+ if (b)
+ b = (prio == 100);
+ if (b)
+ b = (0 ==
+ my_memcmp(buf, "a peck of", sizeof("a peck of"))
+ );
+ CYG_TEST_PASS_FAIL( b, "Blocking get");
+
+//------------------------------------------------------------------------
+
+ t0sem.wait();
+
+ CYG_TEST_PASS_FAIL( 4 == mq->count(), "mq count" );
+ err = mq->get( buf, &len, &prio, false );
+ b = (err == Cyg_Mqueue::OK);
+ if (b)
+ b = (len == sizeof("pickled peppers"));
+ if (b)
+ b = (prio == 300);
+ if (b)
+ b = (0 ==
+ my_memcmp(buf, "pickled peppers", sizeof("pickled peppers"))
+ );
+ if (b)
+ b = (3 == mq->count());
+ CYG_TEST_PASS_FAIL( b, "Prioritized (get 1)");
+
+ err = mq->get( buf, &len, &prio, false );
+ b = (err == Cyg_Mqueue::OK);
+ if (b)
+ b = (len == sizeof("."));
+ if (b)
+ b = (prio == 250);
+ if (b)
+ b = (0 ==
+ my_memcmp(buf, ".", sizeof("."))
+ );
+ if (b)
+ b = (2 == mq->count());
+ CYG_TEST_PASS_FAIL( b, "Prioritized (get 2)");
+
+ err = mq->get( buf, &len, &prio, false );
+ b = (err == Cyg_Mqueue::OK);
+ if (b)
+ b = (len == 1);
+ if (b)
+ b = (prio == 225);
+ if (b)
+ b = (0 ==
+ my_memcmp(buf, "", 1)
+ );
+ if (b)
+ b = (1 == mq->count());
+ CYG_TEST_PASS_FAIL( b, "Prioritized (get 3)");
+
+ err = mq->get( buf, &len, &prio, false );
+ b = (err == Cyg_Mqueue::OK);
+ if (b)
+ b = (len == sizeof("If Peter"));
+ if (b)
+ b = (prio == 200);
+ if (b)
+ b = (0 ==
+ my_memcmp(buf, "If Peter", sizeof("If Peter"))
+ );
+ if (b)
+ b = (0 == mq->count());
+ CYG_TEST_PASS_FAIL( b, "Prioritized (get 4)");
+
+//------------------------------------------------------------------------
+
+ err = mq->get( buf, &len, &prio, false );
+
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::WOULDBLOCK == err,
+ "Non-blocking get of empty queue" );
+
+//------------------------------------------------------------------------
+
+ Cyg_Mqueue::callback_fn_t oldcallback;
+
+ oldcallback = mq->setnotify( &callback, (CYG_ADDRWORD) 42 );
+
+ err = mq->put( "If Peter", sizeof("If Peter"),
+ 200, false );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
+ "Prioritized (put in empty queue)");
+ CYG_TEST_PASS_FAIL( 42 == calledback, "callback" );
+ CYG_TEST_PASS_FAIL( NULL == oldcallback, "oldcallback" );
+
+ err = mq->get( buf, &len, &prio, false );
+ b = (err == Cyg_Mqueue::OK);
+ if (b)
+ b = (len == sizeof("If Peter"));
+ if (b)
+ b = (prio == 200);
+ if (b)
+ b = (0 ==
+ my_memcmp(buf, "If Peter", sizeof("If Peter"))
+ );
+ CYG_TEST_PASS_FAIL( b, "Prioritized (get 2)");
+
+ t1sem.post();
+
+ err = mq->get( buf, &len, &prio, true );
+ b = (err == Cyg_Mqueue::OK);
+ if (b)
+ b = (len == 32);
+ if (b)
+ b = (42 == calledback);
+ if (b)
+ b = (prio == 250);
+ if (b)
+ b = (0 ==
+ my_memcmp(buf, "12345678901234567890123456789012", 32)
+ );
+ CYG_TEST_PASS_FAIL( b, "callback (blocked wait)");
+
+//------------------------------------------------------------------------
+
+ t1sem.post();
+ t0sem.wait();
+
+} // t0()
+
+
+//************************************************************************
+//************************************************************************
+
+
+static void
+t1( CYG_ADDRWORD data )
+{
+ Cyg_Mqueue::qerr_t err;
+ char buf[35];
+ size_t len;
+ unsigned int prio;
+ bool b;
+
+//------------------------------------------------------------------------
+
+ // wait till t0 says we can go
+ t1sem.wait();
+
+ err = mq->get( buf, &len, &prio, true );
+ b = (err == Cyg_Mqueue::OK);
+ if (b)
+ b = (len == sizeof("Peter piper picked"));
+ if (b)
+ b = (prio == 5);
+ if (b)
+ b = (0 ==
+ my_memcmp(buf, "Peter piper picked", sizeof("Peter piper picked"))
+ );
+
+ CYG_TEST_PASS_FAIL( b, "Simple");
+
+//------------------------------------------------------------------------
+
+ t0sem.post(); // t0 should run straight away
+ Cyg_Thread::yield(); // but just in case we have a funny sched
+
+ // by now t0 is blocked in mq->get
+
+ err = mq->put( "a peck of", sizeof("a peck of"),
+ 100, false );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err, "Block (put in empty queue)");
+
+//------------------------------------------------------------------------
+
+ err = mq->put( "If Peter", sizeof("If Peter"),
+ 200, false );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
+ "Prioritized (put in empty queue)");
+
+ err = mq->put( "pickled peppers", sizeof("pickled peppers"),
+ 300, false );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
+ "Prioritized (put in queue w/1)");
+
+ err = mq->put( ".", sizeof("."), 250, false );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
+ "Prioritized (put in queue w/2)");
+
+ err = mq->put( "", 1, 225, false );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
+ "Prioritized (put in queue w/3)");
+
+ err = mq->put( "foobar", 6, 1, false );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::WOULDBLOCK == err,
+ "Prioritized (full queue)");
+
+ t0sem.post();
+
+//------------------------------------------------------------------------
+
+ t1sem.wait();
+ Cyg_Thread::yield(); // but just in case we have a funny sched
+
+ err = mq->put( "12345678901234567890123456789012xxxx", 32,
+ 250, false );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
+ "callback (put in queue)");
+
+//------------------------------------------------------------------------
+
+ t1sem.wait();
+
+ // Create an oversized queue
+ {
+ Cyg_Mqueue huge_mq(99999, 99999, &my_alloc, &my_free, &err );
+ CYG_TEST_PASS_FAIL( Cyg_Mqueue::NOMEM == err,
+ "Oversized queue rejected" );
+ // and it now gets destructed - but that shouldn't call free
+ // to be called
+ }
+
+//------------------------------------------------------------------------
+
+ t0sem.post(); // t0 should run straight away
+ Cyg_Thread::yield(); // but just in case we have a funny sched
+
+ // check that mq was destroyed when t0 dropped off the end
+ CYG_TEST_PASS_FAIL( NULL == mq, "queue destroyed correctly" );
+
+ CYG_TEST_EXIT("kernel mqueue test 1");
+
+} // t1()
+
+
+//************************************************************************
+//************************************************************************
+
+externC void
+cyg_user_start(void)
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ CYG_TEST_INIT();
+
+ CYG_TEST_INFO( "Starting kernel mqueue test 1" );
+ new_thread( t0, 0);
+ new_thread( t1, 1);
+
+#ifdef CYGIMP_THREAD_PRIORITY
+ thread[0]->set_priority( 4 );
+ thread[1]->set_priority( 5 ); // make sure the threads execute as intended
+#endif
+} // cyg_user_start()
+
+//------------------------------------------------------------------------
+
+
+/* EOF mqueue1.cxx */
diff --git a/cesar/ecos/packages/kernel/current/tests/mutex0.cxx b/cesar/ecos/packages/kernel/current/tests/mutex0.cxx
new file mode 100644
index 0000000000..e8a208f0d7
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/mutex0.cxx
@@ -0,0 +1,96 @@
+//==========================================================================
+//
+// mutex0.cxx
+//
+// Mutex and condition variable test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-24
+// Description: Limited to checking constructors/destructors
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/mutex.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include "testaux.hxx"
+
+static Cyg_Mutex mutex0;
+
+static Cyg_Condition_Variable cvar0( mutex0 );
+
+static bool flash( void )
+{
+ Cyg_Mutex m0;
+
+ CYG_ASSERTCLASSO(m0, "error");
+
+ Cyg_Condition_Variable cv0( m0 );
+
+ CYG_ASSERTCLASSO(cv0, "error");
+
+ return true;
+}
+
+void mutex0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ CYG_ASSERTCLASSO(mutex0, "error");
+ CYG_ASSERTCLASSO(cvar0, "error");
+
+ CYG_TEST_PASS_FINISH("Mutex 0 OK");
+
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ mutex0_main();
+}
+// EOF mutex0.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/mutex1.cxx b/cesar/ecos/packages/kernel/current/tests/mutex1.cxx
new file mode 100644
index 0000000000..5233a3e67d
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/mutex1.cxx
@@ -0,0 +1,162 @@
+//==========================================================================
+//
+// mutex1.cxx
+//
+// Mutex test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-24
+// Description: Tests basic mutex functionality.
+// Omissions: Timed wait.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+
+#include <cyg/kernel/mutex.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/thread.inl>
+
+
+#define NTHREADS 3
+#include "testaux.hxx"
+
+static Cyg_Mutex m0, m1;
+static Cyg_Condition_Variable cvar0( m0 ), cvar1( m0 ), cvar2( m1 );
+
+static cyg_ucount8 m0d=0, m1d=0;
+
+static void finish( cyg_ucount8 t )
+{
+ m1.lock(); {
+ m1d |= 1<<t;
+ if( 0x7 == m1d )
+ CYG_TEST_PASS_FINISH("Mutex 1 OK");
+ cvar2.wait();
+ }
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+static void entry0( CYG_ADDRWORD data )
+{
+ m0.lock(); {
+ CHECK( ! m0.trylock() );
+ m1.lock(); {
+ CHECK( ! m0.trylock() );
+ } m1.unlock();
+ } m0.unlock();
+
+ m0.lock(); {
+ while ( 0 == m0d )
+ cvar0.wait();
+ CHECK( 1 == m0d++ );
+ cvar0.signal();
+ while ( 4 != m0d )
+ cvar1.wait();
+ CHECK( 4 == m0d );
+ } m0.unlock();
+
+ finish( data );
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ m0.lock(); {
+ CHECK( m1.trylock() ); {
+ } m1.unlock();
+ } m0.unlock();
+
+ m0.lock(); {
+ CHECK( 0 == m0d++ );
+ cvar0.broadcast();
+ } m0.unlock();
+
+ m0.lock(); {
+ while( 1 == m0d )
+ cvar0.wait();
+ CHECK( 2 == m0d++ );
+ cvar0.signal();
+ while (3 == m0d )
+ cvar1.wait();
+ } m0.unlock();
+
+ finish( data ); // At most 1 finish inside m0 lock
+}
+
+static void entry2( CYG_ADDRWORD data )
+{
+ m0.lock(); {
+ while( 3 != m0d ) {
+ cvar0.wait();
+ }
+ CHECK( 3 == m0d++ );
+ cvar1.broadcast();
+ } m0.unlock();
+
+ finish( data );
+}
+
+void mutex1_main( void )
+{
+ CYG_TEST_INIT();
+
+ new_thread(entry0, 0);
+ new_thread(entry1, 1);
+ new_thread(entry2, 2);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ mutex1_main();
+}
+// EOF mutex1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/mutex2.cxx b/cesar/ecos/packages/kernel/current/tests/mutex2.cxx
new file mode 100644
index 0000000000..cc23bd29f8
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/mutex2.cxx
@@ -0,0 +1,272 @@
+//==========================================================================
+//
+// mutex1.cxx
+//
+// Mutex test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1999-02-19
+// Description: Tests mutex release functionality
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+
+#include <cyg/kernel/mutex.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/thread.inl>
+
+// ------------------------------------------------------------------------
+
+#if !defined(CYGPKG_KERNEL_SMP_SUPPORT)
+
+// ------------------------------------------------------------------------
+
+#define NTHREADS 4
+#include "testaux.hxx"
+#include "testaux.h"
+
+// ------------------------------------------------------------------------
+
+static Cyg_Mutex m0, m1;
+static Cyg_Condition_Variable cvar0( m0 ), cvar1( m0 ), cvar2( m1 );
+
+volatile int thread_state[NTHREADS];
+
+// ------------------------------------------------------------------------
+// This thread is meant to get hung up trying to re-acquire m0
+// after waiting on the cv.
+
+static void entry0( CYG_ADDRWORD data )
+{
+ CYG_TEST_INFO( "thread0: lock mutex 0");
+
+ m0.lock();
+
+ CYG_TEST_INFO( "thread0: wait cvar 0");
+
+ thread_state[data] = 1;
+
+ cvar0.wait();
+
+ thread_state[data] = 2;
+
+ CYG_TEST_INFO( "thread0: woke from cvar 0");
+
+ CYG_TEST_INFO( "thread0: unlock mutex 0");
+
+ m0.unlock();
+
+ thread_state[data] = 3;
+
+ CYG_TEST_INFO( "thread0: exit");
+
+ thread[data]->exit();
+}
+
+// ------------------------------------------------------------------------
+// This thread is meant to claim and keep m0.
+
+static void entry1( CYG_ADDRWORD data )
+{
+ CYG_TEST_INFO( "thread1: lock mutex 0");
+
+ m0.lock();
+
+ CYG_TEST_INFO( "thread1: lock mutex 1");
+
+ thread_state[data] = 1;
+
+ m1.lock();
+
+ thread_state[data] = 2;
+
+ CYG_TEST_INFO( "thread1: wait cvar 2");
+
+ cvar2.wait();
+
+ thread_state[data] = 3;
+
+ CYG_TEST_INFO( "thread1: woke from cvar 2");
+
+ CYG_TEST_INFO( "thread1: unlock mutex 1");
+
+ m1.unlock();
+
+ thread_state[data] = 4;
+
+ CYG_TEST_INFO( "thread1: unlock m0");
+
+ m0.unlock();
+
+ thread_state[data] = 5;
+
+ CYG_TEST_INFO( "thread1: exit");
+
+ thread[data]->exit();
+}
+
+// ------------------------------------------------------------------------
+// This thread is meant to get hung trying to acquire m0, and then get
+// released out of it by thread3.
+
+static void entry2( CYG_ADDRWORD data )
+{
+ CYG_TEST_INFO( "thread2: lock mutex 0");
+
+ thread_state[data] = 1;
+
+ if( m0.lock() )
+ {
+ thread_state[data] = 2;
+
+ CYG_TEST_INFO( "thread2: lock mutex 0 - returned TRUE");
+ CYG_TEST_FAIL_FINISH(" m0.lock() returned TRUE" );
+ }
+ else
+ {
+ thread_state[data] = 3;
+ CYG_TEST_INFO( "thread2: lock mutex 0 - returned FALSE");
+ }
+
+ CYG_TEST_INFO( "thread2: exit");
+
+ thread[data]->exit();
+}
+
+// ------------------------------------------------------------------------
+
+static void entry3( CYG_ADDRWORD data )
+{
+
+ CHECK( thread_state[0] == 1 );
+ CHECK( thread_state[1] == 2 );
+ CHECK( thread_state[2] == 1 );
+
+ CYG_TEST_INFO( "thread3: signal cvar 0");
+
+ cvar0.signal();
+
+ CHECK( thread_state[0] == 1 );
+ CHECK( thread_state[1] == 2 );
+ CHECK( thread_state[2] == 1 );
+
+ CYG_TEST_INFO( "thread3: release mutex 0");
+
+ m0.release();
+
+ CHECK( thread_state[0] == 1 );
+ CHECK( thread_state[1] == 2 );
+ CHECK( thread_state[2] == 3 );
+
+ CYG_TEST_INFO( "thread3: signal cvar 2");
+
+ cvar2.signal();
+
+ CHECK( thread_state[0] == 3 );
+ CHECK( thread_state[1] == 5 );
+ CHECK( thread_state[2] == 3 );
+
+ CYG_TEST_PASS_FINISH( "mutex2 finished OK");
+
+ CYG_TEST_INFO( "thread3: exit");
+
+ thread[data]->exit();
+}
+
+// ------------------------------------------------------------------------
+
+void mutex2_main( void )
+{
+ CYG_TEST_INIT();
+
+ new_thread(entry0, 0);
+ new_thread(entry1, 1);
+ new_thread(entry2, 2);
+ new_thread(entry3, 3);
+
+ // Set priorities from the top to prevent two threads getting
+ // the same priority: this causes an ASSERT on some configurations.
+ thread[3]->set_priority( 5 );
+ thread[2]->set_priority( 4 );
+ thread[1]->set_priority( 3 );
+ thread[0]->set_priority( 2 );
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+// ------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ mutex2_main();
+}
+
+// ------------------------------------------------------------------------
+
+#else // CYGPKG_KERNEL_SMP_SUPPORT
+
+// ------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Mutex2 test requires: !defined(CYGPKG_KERNEL_SMP_SUPPORT)");
+
+}
+
+// ------------------------------------------------------------------------
+
+#endif // CYGPKG_KERNEL_SMP_SUPPORT
+
+// ------------------------------------------------------------------------
+// EOF mutex2.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/mutex3.cxx b/cesar/ecos/packages/kernel/current/tests/mutex3.cxx
new file mode 100644
index 0000000000..7abeec8af3
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/mutex3.cxx
@@ -0,0 +1,631 @@
+//==========================================================================
+//
+// mutex3.cxx
+//
+// Mutex test 3 - priority inheritance
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 2000-01-06
+// Description: Tests mutex priority inheritance
+//####DESCRIPTIONEND####
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+
+#include <cyg/kernel/mutex.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/thread.inl>
+
+#include <cyg/infra/diag.h> // diag_printf
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+// ------------------------------------------------------------------------
+//
+// These checks should be enough; any other scheduler which has priorities
+// should manifest as having no priority inheritance, but otherwise fine,
+// so the test should work correctly.
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \
+ (CYGNUM_KERNEL_SCHED_PRIORITIES > 20) && \
+ !defined(CYGPKG_KERNEL_SMP_SUPPORT)
+
+// ------------------------------------------------------------------------
+// Manufacture a simpler feature test macro for priority inheritance than
+// the configuration gives us. We have priority inheritance if it is configured
+// as the only protocol, or if it is the default protocol for dynamic protocol
+// choice.
+// FIXME: If we have dynamic protocol choice, we can also set priority inheritance
+// as the protocol to be used on the mutexes we are interested in. At present we
+// do not do this.
+
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_INHERIT
+# define PRIORITY_INHERITANCE "dynamic-default-inherit"
+# endif
+# else
+# define PRIORITY_INHERITANCE "static-inherit"
+# endif
+#endif
+
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_CEILING
+# if CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY <= 5
+# define PRIORITY_INHERITANCE "dynamic-default-ceiling-high"
+# elif CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY >= 15
+# define NO_PRIORITY_INHERITANCE "dynamic-default-ceiling-low"
+# else
+# define PRIORITY_UNKNOWN "dynamic-default-ceiling-mid"
+# endif
+# endif
+# else
+# if CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY <= 5
+# define PRIORITY_INHERITANCE "static-ceiling-high"
+# elif CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY >= 15
+# define NO_PRIORITY_INHERITANCE "static-ceiling-low"
+# else
+# define PRIORITY_UNKNOWN "static-ceiling-mid"
+# endif
+# endif
+#endif
+
+#ifndef PRIORITY_INHERITANCE
+# ifndef NO_PRIORITY_INHERITANCE
+# define NO_PRIORITY_INHERITANCE "no scheme selected"
+# endif
+#endif
+
+// ------------------------------------------------------------------------
+// Management functions
+//
+// Stolen from testaux.hxx and copied in here because I want to be able to
+// reset the world also.
+
+#define NTHREADS 7
+
+inline void *operator new(size_t size, void *ptr) { return ptr; };
+
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static Cyg_Thread *thread[NTHREADS] = { 0 };
+
+typedef CYG_WORD64 CYG_ALIGNMENT_TYPE;
+
+static CYG_ALIGNMENT_TYPE thread_obj[NTHREADS] [
+ (sizeof(Cyg_Thread)+sizeof(CYG_ALIGNMENT_TYPE)-1)
+ / sizeof(CYG_ALIGNMENT_TYPE) ];
+
+static CYG_ALIGNMENT_TYPE stack[NTHREADS] [
+ (STACKSIZE+sizeof(CYG_ALIGNMENT_TYPE)-1)
+ / sizeof(CYG_ALIGNMENT_TYPE) ];
+
+static volatile int nthreads = 0;
+
+static Cyg_Thread *new_thread( cyg_thread_entry *entry,
+ CYG_ADDRWORD data,
+ CYG_ADDRWORD priority,
+ int do_resume )
+{
+ int _nthreads = nthreads++;
+
+ CYG_ASSERT(_nthreads < NTHREADS,
+ "Attempt to create more than NTHREADS threads");
+
+ thread[_nthreads] = new( (void *)&thread_obj[_nthreads] )
+ Cyg_Thread(priority,
+ entry, data,
+ NULL, // no name
+ (CYG_ADDRESS)stack[_nthreads], STACKSIZE );
+
+ if ( do_resume )
+ thread[_nthreads]->resume();
+
+ return thread[_nthreads];
+}
+
+
+static void kill_threads( void )
+{
+ CYG_ASSERT(nthreads <= NTHREADS,
+ "More than NTHREADS threads");
+ CYG_ASSERT( Cyg_Thread::self() == thread[0],
+ "kill_threads() not called from thread 0");
+ while ( nthreads > 1 ) {
+ nthreads--;
+ if ( NULL != thread[nthreads] ) {
+ thread[nthreads]->kill();
+ thread[nthreads]->~Cyg_Thread();
+ thread[nthreads] = NULL;
+ }
+ }
+ CYG_ASSERT(nthreads == 1,
+ "No threads left");
+}
+
+// ------------------------------------------------------------------------
+
+#define DELAYFACTOR 1 // for debugging
+
+// ------------------------------------------------------------------------
+
+static Cyg_Mutex mutex;
+
+// These are for reporting back to the master thread
+volatile int got_it = 0;
+volatile int t3ran = 0;
+volatile int t3ended = 0;
+volatile int extras[4] = {0,0,0,0};
+
+volatile int go_flag = 0; // but this one controls thread 3 from thread 2
+
+// ------------------------------------------------------------------------
+// 0 to 3 of these run generally to interfere with the other processing,
+// to cause multiple prio inheritances, and clashes in any orders.
+
+static void extra_thread( CYG_ADDRWORD data )
+{
+#define XINFO( z ) \
+ do { z[13] = '0' + data; CYG_TEST_INFO( z ); } while ( 0 )
+
+ static char running[] = "Extra thread Xa running";
+ static char exiting[] = "Extra thread Xa exiting";
+ static char resumed[] = "Extra thread Xa resumed";
+ static char locked[] = "Extra thread Xa locked";
+ static char unlocked[] = "Extra thread Xa unlocked";
+
+ XINFO( running );
+
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ self->suspend();
+
+ XINFO( resumed );
+
+ mutex.lock();
+
+ XINFO( locked );
+
+ mutex.unlock();
+
+ XINFO( unlocked );
+
+ extras[ data ] ++;
+
+ XINFO( exiting );
+
+}
+
+// ------------------------------------------------------------------------
+
+static void t1( CYG_ADDRWORD data )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ CYG_TEST_INFO( "Thread 1 running" );
+
+ self->suspend();
+
+ mutex.lock();
+
+ got_it++;
+
+ CYG_TEST_CHECK( 0 == t3ended, "T3 ended prematurely [T1,1]" );
+
+ mutex.unlock();
+
+ CYG_TEST_CHECK( 0 == t3ended, "T3 ended prematurely [T1,2]" );
+
+ // That's all.
+
+ CYG_TEST_INFO( "Thread 1 exit" );
+}
+
+// ------------------------------------------------------------------------
+
+static void t2( CYG_ADDRWORD data )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+ int i;
+ cyg_tick_count then, now;
+
+
+ CYG_TEST_INFO( "Thread 2 running" );
+
+ CYG_TEST_CHECK( 0 == (data & ~0x77), "Bad T2 arg: extra bits" );
+ CYG_TEST_CHECK( 0 == (data & (data >> 4)), "Bad T2 arg: overlap" );
+
+ self->suspend();
+
+ // depending on our config argument, optionally restart some of the
+ // extra threads to throw noise into the scheduler:
+ for ( i = 0; i < 3; i++ )
+ if ( (1 << i) & data ) // bits 0-2 control
+ thread[i+4]->resume(); // made sure extras are thread[4-6]
+
+ self->delay( DELAYFACTOR * 10 ); // let those threads run
+
+ Cyg_Scheduler::lock(); // do this next lot atomically
+
+ go_flag = 1; // unleash thread 3
+ thread[1]->resume(); // resume thread 1
+
+ // depending on our config argument, optionally restart some of the
+ // extra threads to throw noise into the scheduler at this later point:
+ for ( i = 4; i < 7; i++ )
+ if ( (1 << i) & data ) // bits 4-6 control
+ thread[i]->resume(); // made sure extras are thread[4-6]
+
+ Cyg_Scheduler::unlock(); // let scheduling proceed
+
+ // Need a delay (but not a CPU yield) to allow t3 to awaken and act on
+ // the go_flag, otherwise we check these details below too soon.
+ // Actually, waiting for the clock to tick a couple of times would be
+ // better, so that is what we will do. Must be a busy-wait.
+ then = Cyg_Clock::real_time_clock->current_value();
+ do {
+ now = Cyg_Clock::real_time_clock->current_value();
+ // Wait longer than the delay in t3 waiting on go_flag
+ } while ( now < (then + 3) );
+
+#ifdef PRIORITY_UNKNOWN
+ CYG_TEST_INFO( "Not checking: " PRIORITY_UNKNOWN );
+#else
+#ifdef PRIORITY_INHERITANCE
+ CYG_TEST_INFO( "Checking priority scheme: " PRIORITY_INHERITANCE );
+ CYG_TEST_CHECK( 1 == t3ran, "Thread 3 did not run" );
+ CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+#else
+ CYG_TEST_INFO( "Checking NO priority scheme: " NO_PRIORITY_INHERITANCE );
+ CYG_TEST_CHECK( 0 == t3ran, "Thread 3 DID run" );
+ CYG_TEST_CHECK( 0 == got_it, "Thread 1 DID get the mutex" );
+#endif
+#endif
+
+ CYG_TEST_CHECK( 0 == t3ended, "Thread 3 ended prematurely [T2,1]" );
+
+ self->delay( DELAYFACTOR * 20 ); // let those threads run
+
+ CYG_TEST_CHECK( 1 == t3ran, "Thread 3 did not run" );
+ CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+ CYG_TEST_CHECK( 1 == t3ended, "Thread 3 has not ended" );
+
+ for ( i = 0; i < 3; i++ )
+ if ( (1 << i) & (data | data >> 4) ) // bits 0-2 and 4-6 control
+ CYG_TEST_CHECK( 1 == extras[i+1], "Extra thread did not run" );
+ else
+ CYG_TEST_CHECK( 0 == extras[i+1], "Extra thread ran" );
+
+ CYG_TEST_PASS( "Thread 2 exiting, AOK" );
+ // That's all: restart the control thread.
+ thread[0]->resume();
+}
+
+// ------------------------------------------------------------------------
+
+static void t3( CYG_ADDRWORD data )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ CYG_TEST_INFO( "Thread 3 running" );
+
+ mutex.lock();
+
+ self->delay( DELAYFACTOR * 5 ); // let thread 3a run
+
+ thread[2]->resume(); // resume thread 2
+
+ while ( 0 == go_flag )
+ self->delay(1); // wait until we are told to go
+
+ t3ran ++; // record the fact
+
+ CYG_TEST_CHECK( 0 == got_it, "Thread 1 claims to have got my mutex" );
+
+ mutex.unlock();
+
+ t3ended ++; // record that we came back
+
+ CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+
+ CYG_TEST_INFO( "Thread 3 exit" );
+}
+
+// ------------------------------------------------------------------------
+
+static void control_thread( CYG_ADDRWORD data )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+ int i;
+
+ CYG_TEST_INIT();
+ CYG_TEST_INFO( "Control Thread running" );
+
+ // Go through the 27 possibilitied of resuming the extra threads
+ // 0: not at all
+ // 1: early in the process
+ // 2: later on
+ // which are represented by bits 0-3 and 4-6 resp in the argument to
+ // thread 2 (none set means no resume at all).
+ for ( i = 0; i < 27; i++ ) {
+ static int xx[] = { 0, 1, 16 };
+ int j = i % 3;
+ int k = (i / 3) % 3;
+ int l = (i / 9) % 3;
+
+ int d = xx[j] | (xx[k]<<1) | (xx[l]<<2) ;
+
+ if ( cyg_test_is_simulator && (0 != i && 13 != i && 26 != i) )
+ continue; // 13 is 111 base 3, 26 is 222 base 3
+
+#ifdef PRIORITY_INHERITANCE
+ // If the simple scheme plus relay enhancement, or any other
+ // *complete* scheme, we can run all three ancillary threads no
+ // problem, so no special action here.
+
+#else
+ // If no priority inheritance at all, running threads 1a and 2a is
+ // OK, but not thread 3a; it blocks the world.
+ if ( l ) // Cannot run thread 3a if no
+ break; // priority inheritance at all.
+#endif
+
+ mutex = Cyg_Mutex(); // Reinitialize this
+
+ got_it = 0;
+ t3ran = 0;
+ t3ended = 0;
+ for ( int z = 0; z < 4; z++ ) extras[z] = 0;
+ go_flag = 0;
+
+ new_thread( t1, 0, 5, 1 ); // Slot 1
+ new_thread( t2, d, 10, 1 ); // Slot 2
+ new_thread( t3, 0, 15, 1 ); // Slot 3
+
+ new_thread( extra_thread, 1, 8, j ); // Slot 4
+ new_thread( extra_thread, 2, 12, k ); // Slot 5
+ new_thread( extra_thread, 3, 17, l ); // Slot 6
+
+ {
+ static char *a[] = { "inactive", "run early", "run late" };
+ diag_printf( "\n----- [%2d] New Cycle: 0x%02x, Threads 1a %s, 2a %s, 3a %s -----\n",
+ i, d, a[j], a[k], a[l] );
+ }
+
+ self->suspend();
+
+ kill_threads();
+ mutex.~Cyg_Mutex();
+ }
+ CYG_TEST_EXIT( "Control Thread exit" );
+}
+
+// ------------------------------------------------------------------------
+
+externC void
+cyg_user_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ new_thread( control_thread, 0, 2, 1 );
+}
+
+#else // CYGVAR_KERNEL_COUNTERS_CLOCK &c
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("Mutex3 test requires:\n"
+ "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
+ "(CYGNUM_KERNEL_SCHED_PRIORITIES > 20) &&\n"
+ "!defined(CYGPKG_KERNEL_SMP_SUPPORT)\n");
+ CYG_TEST_NA("Mutex3 test requirements");
+}
+#endif // CYGVAR_KERNEL_COUNTERS_CLOCK &c
+
+
+// ------------------------------------------------------------------------
+// Documentation: enclosed is the design of this test.
+//
+// It has been carefully constructed so that it does NOT use other kernel
+// facilities (aside from delay-task) to test that priority inheritance is
+// working, or not, as intended by the configuration.
+//
+// These notes describe the flow of control in one run of the test with the
+// ancillary tasks optionally interspersed. The details of how those extra
+// tasks are or are not allowed to run are not described.
+//
+//
+//
+// The only change in the test that depends on whether there is inheritance or
+// not is the check in thread 2 on "3-ran" and "got it" flags marked ****
+//
+//
+// volatile &c booleans:
+// "got it" = FALSE
+// "3-ran" = FALSE
+// "3-ended" = FALSE
+// "extras"[3] = FALSE
+//
+// thread 1. prio 5, self-suspend.
+//
+// thread 1a, prio 8, self-suspend.
+//
+// thread 2. prio 10, self-suspend.
+//
+// thread 2a, prio 12, self-suspend.
+//
+// thread 3. prio 15, runs, lock mutex, resume(2)
+//
+// thread 3a, prio 17, self-suspend.
+//
+// 2. runs,
+// 2. resume(3a) +++OPTIONAL
+// 2. resume(2a) +++OPTIONAL
+// 2. resume(1a) +++OPTIONAL
+// [1a lock-fail] thread 3->prio := 8
+//
+// [3. runs maybe, does the looping thing]
+//
+// 2. sleep a while...
+//
+// [2a lock-fail] thread 3->prio := 12
+//
+// [3. runs maybe, does the looping thing]
+//
+// [3a lock-fail] thread 3->prio unchanged
+//
+// [3. runs maybe, does the looping thing]
+//
+// 2. lock scheduler
+// 2. set "go-flag"
+// 2. resume(1)
+// 2. resume(1a) +++OPTIONAL
+// 2. resume(2a) +++OPTIONAL
+// 2. resume(3a) +++OPTIONAL
+// 2. unlock scheduler
+//
+// 1. runs, lock mutex - thread 3 has it locked
+//
+// 2. busy-waits a bit for thread 3 to come out of its delay() loop.
+// This must be a *busy*wait so that 3 can only run via the
+// inherited raised priority.
+//
+// [xa. all do the same: lock mutex, ]
+// [xa. unlock mutex ]
+// [xa. set a flag "extras"[x] to say we are done. ]
+// [xa. exit ]
+//
+//
+//
+// INHERIT
+// -------
+//
+// thread 3->prio := 5
+//
+// 3. runs,
+// 3. set a flag to say "3-ran",
+// 3. loop with a sleep(1) until "go-flag" is set.
+// 3. check "got it" is false,
+// 3. then unlock mutex,
+//
+// thread 3->prio := 15
+//
+// 1. runs, set a flag to say "got it",
+// 1. check "3-ended" flag is false
+// 1. unlock mutex,
+// 1. check "3-ended" flag is still false
+// 1. exit.
+//
+// [1a locks, unlocks, exits]
+//
+// 2. runs, check "3-ran" and "got it" flags are TRUE ****
+// 2. check "3-ended" flag is false
+// 2. sleeps for a while so that...
+//
+// [2a locks, unlocks, exits]
+//
+// 3. runs, set "3-ended" flag,
+// 3. check "3-ran" and "got it" flags
+// 3. exit
+//
+// [3a locks, unlocks, exits]
+//
+// 2. awakens, checks all flags true,
+// 2. check that all "extra" threads that we started have indeed run
+// 2. end of test.
+//
+//
+//
+//
+// NO-INHERIT
+// ----------
+// thread 1 is waiting on the mutex
+//
+// [1a lock-fail]
+//
+// 2. runs, checks that "3-ran" and "got it" flags are FALSE ****
+// 2. check "3-ended" flag is false
+// 2. sleeps for a while so that...
+//
+// [2a. lock-fail]
+//
+// 3. runs, set a flag to say "3-ran",
+// 3. check "got it" is false,
+// 3. then unlock mutex,
+//
+// 1. runs, set a flag to say "got it",
+// 1. check "3-ended" flag is false
+// 1. unlock mutex,
+// 1. check "3-ended" flag is still false
+// 1. exit.
+//
+// [1a locks, unlocks, exits]
+// [2a locks, unlocks, exits]
+//
+// 3. runs, set "3-ended" flag,
+// 3. check "3-ran" and "got it" flags
+// 3. exit
+//
+// [3a locks, unlocks, exits]
+//
+// 2. awakens, checks all flags true,
+// 2. check that all "extra" threads that we started have indeed run
+// 2. end of test.
+//
+//
+// (the end)
+//
+//
+// ------------------------------------------------------------------------
+
+// EOF mutex3.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/philo.cxx b/cesar/ecos/packages/kernel/current/tests/philo.cxx
new file mode 100644
index 0000000000..892d0db72a
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/philo.cxx
@@ -0,0 +1,241 @@
+//==========================================================================
+//
+// philo.cxx
+//
+// A test of the dining philosophers problem
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-24
+// Description: A test of the dining philosophers problem
+//####DESCRIPTIONEND####
+//
+
+#include <cyg/kernel/kernel.hxx>
+
+#include <cyg/hal/hal_io.h>
+
+// -------------------------------------------------------------------------
+// Data for the philosophers problem
+
+#define PHILOSOPHERS 15 // number of philosophers
+#define STACKSIZE (2*1024) // size of thread stack
+
+#define NTHREADS PHILOSOPHERS
+#include "testaux.hxx"
+
+// array of chopsticks
+Cyg_Binary_Semaphore chopstick[PHILOSOPHERS];
+
+
+//cyg_thread_entry Philosopher;
+
+// -------------------------------------------------------------------------
+// State recording and display
+
+static char pstate[PHILOSOPHERS+1]; // state vector showing what each
+ // philosopher is doing
+
+Cyg_Mutex state_mutex;
+
+#ifdef CYG_HAL_MN10300_MN103002
+static cyg_count8 eaters = 0;
+#endif
+
+void change_state(int id, char newstate)
+{
+ CYG_INSTRUMENT_USER( 1, 0, 0);
+ state_mutex.lock();
+ CYG_INSTRUMENT_USER( 2, 0, 0);
+
+#ifdef CYG_HAL_MN10300_MN103002
+ if( pstate[id] == 'E' ) eaters--;
+ if( newstate == 'E' ) eaters++;
+// led(eaters);
+#endif
+
+ pstate[id] = newstate;
+
+ diag_write_string(pstate);
+#if 0
+ diag_write_char(' ');
+ diag_write_dec(Cyg_Scheduler::get_thread_switches());
+#endif
+ diag_write_char('\n');
+
+ CYG_INSTRUMENT_USER( 3, 0, 0);
+ state_mutex.unlock();
+ CYG_INSTRUMENT_USER( 4, 0, 0);
+
+}
+
+char get_state( int id)
+{
+ state_mutex.lock();
+
+ char s = pstate[id];
+
+ state_mutex.unlock();
+
+ return s;
+}
+
+// -------------------------------------------------------------------------
+// Thread to behave like a philosopher
+
+void Philosopher( CYG_ADDRESS id )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+ Cyg_Binary_Semaphore *first_stick = &chopstick[id];
+ Cyg_Binary_Semaphore *second_stick = &chopstick[(id+1)%PHILOSOPHERS];
+#ifdef CYGPKG_INFRA_DEBUG
+ int left_philo = ((id==0)?PHILOSOPHERS:id)-1;
+ int right_philo = (id==PHILOSOPHERS-1)?0:(id+1);
+#endif
+
+ CYG_ASSERT( id >= 0 && id < PHILOSOPHERS, "Bad id");
+
+ // Deadlock avoidance. The easiest way to make the philosophers
+ // behave is to make each pick up the lowest numbered stick
+ // first. This is how it works out anyway for all the philosophers
+ // except the last, who must have his sticks swapped.
+
+ if( id == PHILOSOPHERS-1 )
+ {
+ Cyg_Binary_Semaphore *t = first_stick;
+ first_stick = second_stick;
+ second_stick = t;
+ }
+
+ // The following variable is shared by all philosophers.
+ // It is incremented unprotected, but this does not matter
+ // since it is only present to introduce a little variability
+ // into the think and eat times.
+
+ static int cycle = 0;
+
+ for(;;)
+ {
+ // Think for a bit
+
+ self->delay((id+cycle++)%12); // Cogito ergo sum...
+
+ // I am now hungry, try to get the chopsticks
+
+ change_state(id,'H');
+
+ // Get the first stick
+ CYG_INSTRUMENT_USER( 5, 0, 0);
+ first_stick->wait();
+ CYG_INSTRUMENT_USER( 6, 0, 0);
+
+ // Get the second stick
+ CYG_INSTRUMENT_USER( 7, 0, 0);
+ second_stick->wait();
+ CYG_INSTRUMENT_USER( 8, 0, 0);
+
+ // Got them, now eat
+
+ change_state(id,'E');
+
+ // Check that the world is as I think it is...
+ CYG_ASSERT( !first_stick->posted(), "Not got first stick");
+ CYG_ASSERT( !second_stick->posted(), "Not got second stick");
+ CYG_ASSERT( get_state(left_philo) != 'E', "Left neighbour also eating!!");
+ CYG_ASSERT( get_state(right_philo) != 'E', "Right neighbour also eating!!");
+
+ self->delay((id+cycle++)%6); // munch munch
+
+ // Finished eating, put down sticks.
+
+ change_state(id,'T');
+
+ CYG_INSTRUMENT_USER( 9, 0, 0);
+ first_stick->post();
+ CYG_INSTRUMENT_USER( 10, 0, 0);
+ second_stick->post();
+ CYG_INSTRUMENT_USER( 11, 0, 0);
+
+// Cyg_Scheduler::lock();
+// Cyg_Scheduler::unlock();
+ CYG_INSTRUMENT_USER( 12, 0, 0);
+
+ }
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ diag_init();
+
+ diag_write_string("Philosophers\n");
+ diag_write_string("Started\n");
+
+ // Zero last element in state so it acts like
+ // a string.
+ pstate[PHILOSOPHERS] = 0;
+
+#if 1
+ for( int i = 0; i < PHILOSOPHERS; i++ )
+ {
+ change_state(i,'T'); // starting state
+
+ // Start the philosopher
+ Cyg_Thread *t = new_thread( Philosopher, i );
+
+ // resume it
+ t->resume();
+
+ // and make the matching chopstick present
+ chopstick[i].post();
+ }
+#endif
+
+ // Get the world going
+ Cyg_Scheduler::scheduler.start();
+
+}
+
+// -------------------------------------------------------------------------
+// EOF philo.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/release.cxx b/cesar/ecos/packages/kernel/current/tests/release.cxx
new file mode 100644
index 0000000000..e65a46e605
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/release.cxx
@@ -0,0 +1,129 @@
+//==========================================================================
+//
+// release.cxx
+//
+// Thread release test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1998-04-24
+// Description: Tests the functionality of thread release().
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/mutex.hxx>
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+#define NTHREADS 2
+
+#include "testaux.hxx"
+
+static Cyg_Binary_Semaphore s0, s1;
+
+static void entry0( CYG_ADDRWORD data )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ if (!s0.wait() )
+ {
+ if( self->get_wake_reason() != Cyg_Thread::BREAK )
+ CYG_TEST_FAIL_FINISH("Wake reason not BREAK");
+ }
+ else
+ {
+ CYG_TEST_FAIL_FINISH("Thread not released");
+ }
+
+ s1.post();
+
+ self->exit();
+}
+
+
+static void entry1( CYG_ADDRWORD data )
+{
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ // Give the other thread a chance to wait in SMP systems.
+ for( int i = 0; i < 100; i++ )
+ self->yield();
+
+ thread[0]->release();
+
+ s1.wait();
+
+ CYG_TEST_PASS_FINISH("Release OK");
+
+ Cyg_Thread::self()->exit();
+}
+
+void release_main(void)
+{
+ CYG_TEST_INIT();
+
+ new_thread( entry0, 0);
+ new_thread( entry1, 1);
+
+ thread[0]->set_priority(5);
+ thread[1]->set_priority(6);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ release_main();
+}
+
+// EOF release.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/sched1.cxx b/cesar/ecos/packages/kernel/current/tests/sched1.cxx
new file mode 100644
index 0000000000..6b8865d8ed
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/sched1.cxx
@@ -0,0 +1,111 @@
+//==========================================================================
+//
+// sched1.cxx
+//
+// Sched test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-26
+// Description: Tests some basic sched functions.
+// Omissions:
+// Doesn't test Cyg_Scheduler::get_thread_switches() very well
+// Cyg_SchedThread
+// inherit_priority
+// disinherit_priority
+// Options:
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sched.hxx> // Cyg_Scheduler::start()
+#include <cyg/kernel/thread.hxx> // Cyg_Thread
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/thread.inl>
+
+#define NTHREADS 2
+
+#include "testaux.hxx"
+
+static void entry0( CYG_ADDRWORD data )
+{
+ CHECK( 0 == Cyg_Scheduler::get_sched_lock() );
+ Cyg_Scheduler::lock(); {
+ CHECK( 1 == Cyg_Scheduler::get_sched_lock() );
+ Cyg_Scheduler::lock(); {
+ CHECK( 2 == Cyg_Scheduler::get_sched_lock() );
+ } Cyg_Scheduler::unlock();
+ } Cyg_Scheduler::unlock();
+ cyg_ucount32 t0=Cyg_Scheduler::get_thread_switches();
+ cyg_ucount32 t1=Cyg_Scheduler::get_thread_switches();
+ CHECK( t1 >= t0 );
+ CHECK( Cyg_Scheduler::get_current_thread() ==
+ Cyg_Thread::self() );
+ CYG_TEST_PASS_FINISH( "Sched 1 OK");
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ Cyg_Thread::self()->sleep();
+}
+
+void sched1_main(void)
+{
+ CYG_TEST_INIT();
+
+ new_thread(entry0, 222);
+ new_thread(entry1, 333);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ sched1_main();
+}
+// EOF sched1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/smp.cxx b/cesar/ecos/packages/kernel/current/tests/smp.cxx
new file mode 100644
index 0000000000..5f35abed41
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/smp.cxx
@@ -0,0 +1,474 @@
+//==========================================================================
+//
+// smp.cxx
+//
+// SMP tests
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2001-06-18
+// Description: Some basic SMP tests.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/hal.h>
+
+#if 1
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/mutex.hxx>
+#include <cyg/kernel/sema.hxx>
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/clock.hxx>
+#include <cyg/kernel/clock.inl>
+#endif
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+//==========================================================================
+
+#if defined(CYGPKG_KERNEL_SMP_SUPPORT) && \
+ defined(CYGFUN_KERNEL_API_C) && \
+ defined(CYGSEM_KERNEL_SCHED_MLQUEUE) && \
+ defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \
+ !defined(CYGPKG_HAL_I386_LINUX) && \
+ !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) && \
+ (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
+
+//==========================================================================
+
+#define NTHREADS 1
+#include "testaux.hxx"
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#define NTHREADS_MAX (CYGNUM_KERNEL_CPU_MAX*3)
+
+static int ncpus = CYGNUM_KERNEL_CPU_MAX;
+static int nthread = NTHREADS_MAX;
+
+static char stacks[NTHREADS_MAX][STACK_SIZE];
+static cyg_thread test_threads[NTHREADS_MAX];
+static cyg_handle_t threads[NTHREADS_MAX];
+
+static volatile cyg_uint32 cpu_run[CYGNUM_KERNEL_CPU_MAX];
+static volatile int failed = false;
+static volatile cyg_uint32 cpu_thread[CYGNUM_KERNEL_CPU_MAX];
+
+static volatile cyg_uint32 slicerun[NTHREADS_MAX][CYGNUM_KERNEL_CPU_MAX];
+
+
+static cyg_mutex_t mx;
+
+
+//==========================================================================
+// Compute a name for a thread
+char *
+thread_name(char *basename, int indx) {
+ return "<<NULL>>"; // Not currently used
+}
+
+//==========================================================================
+
+void
+test_thread_cpu(CYG_ADDRESS id)
+{
+ for(;;)
+ cpu_run[CYG_KERNEL_CPU_THIS()] = true;
+}
+
+//==========================================================================
+// First test: just run as many threads as CPUs and check that we
+// get to run on each CPU.
+
+void run_smp_test_cpus()
+{
+ int i;
+
+ CYG_TEST_INFO( "CPU Test: Check CPUs functional");
+
+ // Init flags.
+ for (i = 0; i < ncpus; i++)
+ cpu_run[i] = false;
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+
+ for (i = 0; i < ncpus; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test_thread_cpu, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume( threads[i]);
+ }
+
+ // Just wait a while, until the threads have all run for a bit.
+ cyg_thread_delay( 10 );
+
+ // Delete all the threads
+ for (i = 0; i < ncpus; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+
+ // And check that a thread ran on each CPU
+ for (i = 0; i < ncpus; i++) {
+// CYG_TEST_CHECK( cpu_run[i], "CPU didn't run");
+ if( !cpu_run[i] )
+ {
+ CYG_TEST_INFO( "CPU didn't run" );
+ failed++;
+ }
+ }
+
+ CYG_TEST_INFO( "CPU Test: done");
+}
+
+
+//==========================================================================
+
+void
+test_thread_pri(CYG_ADDRESS id)
+{
+ for(;;)
+ {
+ cpu_thread[CYG_KERNEL_CPU_THIS()] = id;
+ }
+}
+
+//==========================================================================
+// Second test: Run a thread on each CPU and then by manipulating the
+// priorities, get the current thread to migrate to each CPU in turn.
+
+
+void run_smp_test_pri()
+{
+ int i;
+
+ CYG_TEST_INFO( "Pri Test: Check set_priority functionality");
+
+ // Init flags.
+ for (i = 0; i < ncpus; i++)
+ cpu_run[i] = false;
+
+ // Set my priority higher than any I plan to creat
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+
+ for (i = 0; i < ncpus; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test_thread_pri, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume( threads[i]);
+ }
+
+ cyg_thread_delay( 2 );
+
+ cyg_handle_t cthread = threads[0];
+ cyg_thread_set_priority(cthread, 25);
+
+ // Just wait a while, until the threads have all run for a bit.
+ cyg_thread_delay( 2 );
+
+ for (i = 0; i < ncpus*500; i++)
+ {
+ HAL_SMP_CPU_TYPE cpu = i % CYG_KERNEL_CPU_COUNT();
+
+ if( cpu != CYG_KERNEL_CPU_THIS() )
+ {
+ // At this point we have the current thread running on a
+ // CPU at priority 2, ncpus-1 threads running at priority
+ // 10 and the last thread (cthread) in the run queue at
+ // priority 25.
+
+ // Pick a thread on a different CPU
+ cyg_handle_t dthread;
+
+ do
+ {
+ dthread = threads[cpu_thread[cpu]];
+ } while( dthread == cthread );
+
+ // Change the priority of the victim thread to 20. It is
+ // still higher priority than cthread so it will continue
+ // running.
+
+ cyg_thread_set_priority(dthread, 20);
+
+ // Now change our priority to 15. We are still higher
+ // priority that cthread so we will still run.
+
+ cyg_thread_set_priority(cyg_thread_self(), 15);
+
+ // Finally change the priority of cthread to 10. This will
+ // cause it to preempt us on the current CPU. In turn we
+ // will preempt dthread on its CPU.
+
+ // NOTE: This relies somewhat on the SMP scheduler doing
+ // what we expect here. Specifically, that it will preempt
+ // the current thread with cthread locally. A more
+ // sophisticated scheduler might decide that the most
+ // efficient thing to do is to preempt dthread with
+ // cthread remotely, leaving the current thread where it
+ // is. If we ever bother to implement this, then this test
+ // will need to change.
+
+ cyg_thread_set_priority(cthread, 10);
+
+ // Spin here a while until the scheduler sorts itself out.
+
+ for( int j = 0; j < 100000; j++ );
+
+ // Indicate that we have run on this CPU
+ cpu_run[CYG_KERNEL_CPU_THIS()]++;
+
+ // Restore our priority to 2 and depress dthread to 25 and
+ // make it the new cthread.
+
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+ cyg_thread_set_priority(dthread, 25);
+ cthread = dthread;
+ }
+ }
+
+
+ // Delete all the threads
+ for (i = 0; i < ncpus; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+
+ // And check that a thread ran on each CPU
+ for (i = 0; i < ncpus; i++) {
+// CYG_TEST_CHECK( cpu_run[i], "CPU didn't run");
+ if( !cpu_run[i] )
+ {
+ CYG_TEST_INFO( "CPU didn't run" );
+ failed++;
+ }
+ }
+
+ CYG_TEST_INFO( "PRI Test: done");
+}
+
+//==========================================================================
+
+void
+test_thread_timeslice(CYG_ADDRESS id)
+{
+ for(;;)
+ slicerun[id][CYG_KERNEL_CPU_THIS()]++;
+}
+
+//==========================================================================
+// First test: just run as many threads as CPUs and check that we
+// get to run on each CPU.
+
+void run_smp_test_timeslice()
+{
+ int i;
+
+ CYG_TEST_INFO( "Timeslice Test: Check timeslicing works");
+
+ // Init flags.
+ for (i = 0; i < nthread; i++)
+ for( int j = 0; j < ncpus; j++ )
+ slicerun[i][j] = 0;
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+
+ for (i = 0; i < nthread; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test_thread_timeslice, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume( threads[i]);
+ }
+
+ // Just wait a while, until the threads have all run for a bit.
+ cyg_thread_delay( 200 );
+
+ // Delete all the threads
+ for (i = 0; i < nthread; i++) {
+ cyg_thread_suspend(threads[i]);
+ }
+
+
+ // And check that a thread ran on each CPU
+
+ cyg_uint32 cpu_total[ncpus];
+ cyg_uint32 cpu_threads[ncpus];
+ cyg_uint32 thread_total[nthread];
+
+ diag_printf(" Thread ");
+ for( int j = 0; j < ncpus; j++ )
+ {
+ cpu_total[j] = 0;
+ cpu_threads[j] = 0;
+ diag_printf(" CPU %2d",j);
+ }
+ diag_printf(" Total\n");
+ for (i = 0; i < nthread; i++)
+ {
+ thread_total[i] = 0;
+ diag_printf(" %2d ",i);
+ for( int j = 0; j < ncpus; j++ )
+ {
+ thread_total[i] += slicerun[i][j];
+ cpu_total[j] += slicerun[i][j];
+ if( slicerun[i][j] > 0 )
+ cpu_threads[j]++;
+ diag_printf(" %8d",slicerun[i][j]);
+ }
+ diag_printf("%8d\n",thread_total[i]);
+ }
+ diag_printf(" Total ");
+ for( int j = 0; j < ncpus; j++ )
+ diag_printf(" %8d",cpu_total[j]);
+ diag_printf("\n");
+ diag_printf("Threads ");
+ for( int j = 0; j < ncpus; j++ )
+ {
+ diag_printf(" %8d",cpu_threads[j]);
+ if( cpu_threads[j] < 2 )
+ failed++;
+ }
+ diag_printf("\n");
+
+ // Delete all the threads
+ for (i = 0; i < nthread; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+
+ CYG_TEST_INFO( "Timeslice Test: done");
+}
+
+
+//==========================================================================
+
+void
+run_smp_tests(CYG_ADDRESS id)
+{
+ cyg_mutex_init( &mx );
+
+ for( int i = 0; i < 100; i++ )
+ {
+ run_smp_test_cpus();
+ run_smp_test_pri();
+ run_smp_test_timeslice();
+ }
+
+ if( failed )
+ CYG_TEST_FAIL_FINISH("SMP tests failed\n");
+
+ CYG_TEST_PASS_FINISH("SMP tests OK");
+}
+
+//==========================================================================
+
+void smp_main( void )
+{
+ CYG_TEST_INIT();
+
+ // Work out how many CPUs we actually have.
+ ncpus = CYG_KERNEL_CPU_COUNT();
+
+ new_thread(run_smp_tests, 0);
+
+ cyg_scheduler_start();
+}
+
+//==========================================================================
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ smp_main();
+}
+
+//==========================================================================
+
+#else // CYGPKG_KERNEL_SMP_SUPPORT etc.
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("SMP test requires:\n"
+ "CYGPKG_KERNEL_SMP_SUPPORT &&\n"
+ "CYGFUN_KERNEL_API_C && \n"
+ "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n"
+ "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
+ "!CYGPKG_HAL_I386_LINUX &&\n"
+ "!CYGDBG_INFRA_DIAG_USE_DEVICE &&\n"
+ "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n");
+ CYG_TEST_NA("SMP test requirements");
+}
+#endif // CYGPKG_KERNEL_SMP_SUPPORT etc.
+
+//==========================================================================
+// EOF tm_basic.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/stress_threads.c b/cesar/ecos/packages/kernel/current/tests/stress_threads.c
new file mode 100644
index 0000000000..daedf7f54b
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/stress_threads.c
@@ -0,0 +1,859 @@
+//==========================================================================
+//
+// stress_threads.cxx
+//
+// Basic thread stress test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): rosalia
+// Contributors: rosalia, jskov
+// Date: 1999-04-13
+// Description: Very simple thread stress test, with some memory
+// allocation and alarm handling.
+//
+// Notes:
+// If client_makes_request is big, it means that there are made many more
+// client requests than can be serviced. Consequently, clients are wasting
+// CPU time and should be sleeping more.
+//
+// The list of handler invocations show how many threads are running
+// at the same time. The more powerful the CPU, the more the numbers
+// should spread out.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/system.h>
+#include <cyg/infra/testcase.h>
+
+#include <cyg/hal/hal_arch.h>
+
+#if defined(CYGPKG_KERNEL) && defined(CYGPKG_IO) && defined(CYGPKG_ISOINFRA)
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/isoinfra.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/kernel/kapi.h>
+
+#ifdef CYGINT_ISO_STDIO_FORMATTED_IO
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(CYGPKG_LIBM)
+
+#include <math.h>
+#include <assert.h>
+
+#include <cyg/kernel/test/stackmon.h>
+
+#if defined(CYGFUN_KERNEL_THREADS_TIMER)
+#if CYGINT_ISO_MALLOC
+
+/* if TIME_LIMIT is defined, it represents the number of seconds this
+ test should last; if it is undefined the test will go forever */
+#define DEATH_TIME_LIMIT 20
+/* #undef DEATH_TIME_LIMIT */
+
+// STACK_SIZE is typical +2kB for printf family calls which use big
+// auto variables. Add more for handler which calls perform_stressful_tasks()
+#define STACK_SIZE (2*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL)
+#define STACK_SIZE_HANDLER (STACK_SIZE + 30*CYGNUM_HAL_STACK_FRAME_SIZE)
+
+#define N_MAIN 1
+
+// If we have instrumentation enabled, make the execution time in the
+// simulator even shorter that we were going to anyway.
+#ifdef CYGPKG_KERNEL_INSTRUMENT
+#define SIM_DELAY_DIVISOR 100
+#else
+#define SIM_DELAY_DIVISOR 10
+#endif
+
+//-----------------------------------------------------------------------
+// Some targets need to define a smaller number of handlers due to
+// memory restrictions.
+#if defined(CYGMEM_REGION_ram_SIZE) && (CYGMEM_REGION_ram_SIZE < 0x80000)
+#define MAX_HANDLERS 4
+#define N_LISTENERS 1
+#define N_CLIENTS 1
+
+#undef STACK_SIZE
+#undef STACK_SIZE_HANDLER
+#define STACK_SIZE (1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL)
+#define STACK_SIZE_HANDLER (STACK_SIZE + 10*CYGNUM_HAL_STACK_FRAME_SIZE)
+#endif
+
+//-----------------------------------------------------------------------
+// If no target specific definitions, use defaults
+#ifndef MAX_HANDLERS
+#define MAX_HANDLERS 19
+#define N_LISTENERS 4
+#define N_CLIENTS 4
+#endif
+
+/* Allocate priorities in this order. This ensures that handlers
+ (which are the ones using the CPU) get enough CPU time to actually
+ complete their tasks.
+
+ The empty space ensures that if libc main() thread should happen to
+ be in the priority range of the handlers, no handlers are
+ accidently reduced so much in priority to get below
+ listeners/clients. */
+
+#define P_MAIN_PROGRAM 1
+#define P_MAIN_PROGRAM_E (P_MAIN_PROGRAM+N_MAIN)
+
+#define P_BASE_HANDLER (P_MAIN_PROGRAM_E)
+#define P_BASE_HANDLER_E (P_BASE_HANDLER+MAX_HANDLERS)
+
+#define P_BASE_EMPTY (P_BASE_HANDLER_E)
+#define P_BASE_EMPTY_E (P_BASE_EMPTY+2)
+
+#define P_BASE_LISTENER (P_BASE_EMPTY_E)
+#define P_BASE_LISTENER_E (P_BASE_LISTENER+N_LISTENERS)
+
+#define P_BASE_CLIENT (P_BASE_LISTENER_E)
+#define P_BASE_CLIENT_E (P_BASE_CLIENT+N_CLIENTS)
+
+#define P_MAX (P_BASE_CLIENT_E)
+
+/* Ensure there's room for what we request */
+#if (CYGNUM_KERNEL_SCHED_PRIORITIES >= P_MAX)
+
+/* if we use the bitmap scheduler we must make sure we don't use the
+ same priority more than once, so we must store those already in use */
+static volatile char priority_in_use[P_MAX];
+
+/* We may not get the priority we ask for (scheduler may decide to ignore
+ schedule hint). So keep a table of priorities actually assigned to
+ the threads. This information may come in handy for debugging - it's
+ not actively used by the code. */
+static volatile int priority_translation[P_MAX];
+
+/* now declare (and allocate space for) some kernel objects, like the
+ threads we will use */
+cyg_thread main_thread_s;
+cyg_thread handler_thread_s[MAX_HANDLERS];
+cyg_thread listener_thread_s[N_LISTENERS];
+cyg_thread client_thread_s[N_CLIENTS];
+
+/* space for stacks for all threads */
+char main_stack[STACK_SIZE];
+char handler_stack[MAX_HANDLERS][STACK_SIZE_HANDLER];
+char listener_stack[N_LISTENERS][STACK_SIZE];
+char client_stack[N_CLIENTS][STACK_SIZE];
+
+/* now the handles for the threads */
+cyg_handle_t mainH;
+cyg_handle_t handlerH[MAX_HANDLERS];
+cyg_handle_t listenerH[N_LISTENERS];
+cyg_handle_t clientH[N_CLIENTS];
+
+/* space for thread names */
+char thread_name[P_MAX][20];
+
+/* and now variables for the procedure which is the thread */
+cyg_thread_entry_t main_program, client_program, listener_program,
+ handler_program;
+
+/* a few mutexes used in the code */
+cyg_mutex_t client_request_lock, handler_slot_lock, statistics_print_lock,
+ free_handler_lock;
+
+/* global variables with which the handler IDs and thread priorities
+ to free are communicated from handlers to main_program. Access to
+ these are protected by free_handler_lock. An id of -1 means the
+ that the variables are empty. */
+volatile int free_handler_pri = 0;
+volatile int free_handler_id = -1;
+
+/* a global variable with which the client and server coordinate */
+volatile int client_makes_request = 0;
+
+/* if this is true, clients will not make requests */
+volatile int clients_paused = 0;
+
+
+/* indicates that it's time to print out a report */
+volatile int time_to_report = 0;
+/* print status after a delay of this many secs. */
+int time_report_delay;
+
+/*** now application-specific variables ***/
+/* an array that stores whether the handler threads are in use */
+volatile int handler_thread_in_use[MAX_HANDLERS];
+/* total count of active handlers */
+volatile int handler_thread_in_use_count;
+
+
+/***** statistics-gathering variables *****/
+struct s_statistics {
+ /* store the number of times each handler has been invoked */
+ unsigned long handler_invocation_histogram[MAX_HANDLERS];
+
+ /* store how many times malloc has been attempted and how many times
+ it has failed */
+ unsigned long malloc_tries, malloc_failures;
+
+ /* how many threads have been created */
+ unsigned long thread_creations, thread_exits;
+};
+
+struct s_statistics statistics;
+
+/* some function prototypes; those with the sc_ prefix are
+ "statistics-collecting" versions of the cyg_ primitives */
+cyg_addrword_t sc_thread_create(
+ cyg_addrword_t sched_info, /* scheduling info (eg pri) */
+ cyg_thread_entry_t *entry, /* entry point function */
+ cyg_addrword_t entry_data, /* entry data */
+ char *name, /* optional thread name */
+ void *stack_base, /* stack base, NULL = alloc */
+ cyg_ucount32 stack_size, /* stack size, 0 = default */
+ cyg_handle_t *handle, /* returned thread handle */
+ cyg_thread *thread /* put thread here */
+ );
+
+void start_handler(void);
+void stop_handler(int handler_id, int handler_pri);
+void perform_stressful_tasks(void);
+void permute_array(char a[], int size, int seed);
+void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,
+ cyg_alarm *death_alarm_p, int *killed_p);
+void print_statistics(int print_full);
+
+/* we need to declare the alarm handling function (which is defined
+ below), so that we can pass it to cyg_alarm_initialize() */
+cyg_alarm_t report_alarm_func, death_alarm_func;
+
+/* handle and alarm for the report alarm */
+cyg_handle_t report_alarmH, counterH, system_clockH;
+cyg_alarm report_alarm;
+
+/* main launches all the threads of the test */
+int
+main(void)
+{
+ int i;
+
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("Stress threads test compiled on " __DATE__);
+
+ cyg_mutex_init(&client_request_lock);
+ cyg_mutex_init(&statistics_print_lock);
+ cyg_mutex_init(&free_handler_lock);
+
+ /* initialize statistics */
+ memset(&statistics, 0, sizeof(statistics));
+
+ /* clear priority table */
+ for (i = 0; i < sizeof(priority_in_use); i++)
+ priority_in_use[i] = 0;
+
+ /* initialize main thread */
+ {
+ priority_translation[P_MAIN_PROGRAM] =
+ sc_thread_create(P_MAIN_PROGRAM, main_program, (cyg_addrword_t) 0,
+ "main_program", (void *) main_stack, STACK_SIZE,
+ &mainH, &main_thread_s);
+ priority_in_use[P_MAIN_PROGRAM]++;
+ }
+
+ /* initialize all handler threads to not be in use */
+ for (i = 0; i < MAX_HANDLERS; ++i) {
+ handler_thread_in_use[i] = 0;
+ }
+ handler_thread_in_use_count = 0;
+ for (i = 0; i < N_LISTENERS; ++i) {
+ int prio = P_BASE_LISTENER + i;
+ char* name = &thread_name[prio][0];
+ sprintf(name, "listener-%02d", i);
+ priority_translation[prio] =
+ sc_thread_create(prio, listener_program, (cyg_addrword_t) i,
+ name, (void *) listener_stack[i], STACK_SIZE,
+ &listenerH[i], &listener_thread_s[i]);
+ CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!");
+ priority_in_use[prio]++;
+ }
+ for (i = 0; i < N_CLIENTS; ++i) {
+ int prio = P_BASE_CLIENT + i;
+ char* name = &thread_name[prio][0];
+ sprintf(name, "client-%02d", i);
+ priority_translation[prio] =
+ sc_thread_create(prio, client_program, (cyg_addrword_t) i,
+ name, (void *) client_stack[i], STACK_SIZE,
+ &(clientH[i]), &client_thread_s[i]);
+ CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!");
+ priority_in_use[prio]++;
+ }
+
+ cyg_thread_resume(mainH);
+ for (i = 0; i < N_CLIENTS; ++i) {
+ cyg_thread_resume(clientH[i]);
+ }
+ for (i = 0; i < N_LISTENERS; ++i) {
+ cyg_thread_resume(listenerH[i]);
+ }
+
+ /* set up the alarm which gives periodic wakeups to say "time to
+ print a report */
+ system_clockH = cyg_real_time_clock();
+ cyg_clock_to_counter(system_clockH, &counterH);
+
+ cyg_alarm_create(counterH, report_alarm_func,
+ (cyg_addrword_t) 4000,
+ &report_alarmH, &report_alarm);
+ if (cyg_test_is_simulator) {
+ time_report_delay = 2;
+ } else {
+ time_report_delay = 60;
+ }
+
+ cyg_alarm_initialize(report_alarmH, cyg_current_time()+200,
+ time_report_delay*100);
+
+ return 0;
+}
+
+/* main_program() -- frees resources and prints status. */
+void main_program(cyg_addrword_t data)
+{
+#ifdef DEATH_TIME_LIMIT
+ cyg_handle_t deathH;
+ cyg_alarm death_alarm;
+ int is_dead = 0;
+
+ setup_death_alarm(0, &deathH, &death_alarm, &is_dead);
+#endif /* DEATH_TIME_LIMIT */
+
+ for (;;) {
+ int handler_id = -1;
+ int handler_pri = 0;
+
+ cyg_mutex_lock(&free_handler_lock); {
+ // If any handler has left its ID, copy the ID and
+ // priority values to local variables, and free up the
+ // global communication variables again.
+ if (-1 != free_handler_id) {
+ handler_id = free_handler_id;
+ handler_pri = free_handler_pri;
+ free_handler_id = -1;
+ }
+ } cyg_mutex_unlock(&free_handler_lock);
+
+ if (-1 != handler_id) {
+ stop_handler(handler_id, handler_pri);
+ }
+
+ // If it's time to report status or quit, set pause flag and
+ // keep looping until all handlers have stopped.
+ if (time_to_report) {
+ // Pause clients
+ cyg_mutex_lock(&client_request_lock); {
+ clients_paused = 1;
+ } cyg_mutex_unlock(&client_request_lock);
+
+ // When all handlers have stopped, we can print statistics
+ // knowing that all (handler allocated) resources should have
+ // been freed. That is, we should be able to determine leaks.
+ if (0 == handler_thread_in_use_count) {
+ print_statistics(0);
+
+ // We've done the printing now. Resume the system.
+ time_to_report = 0;
+ cyg_mutex_lock(&client_request_lock); {
+ clients_paused = 0;
+ } cyg_mutex_unlock(&client_request_lock);
+ }
+ }
+
+#ifdef DEATH_TIME_LIMIT
+ // Stop test if time.
+ if (is_dead) {
+ // Pause clients
+ cyg_mutex_lock(&client_request_lock); {
+ clients_paused = 1;
+ } cyg_mutex_unlock(&client_request_lock);
+
+ // When all handlers have stopped, we can print statistics
+ // knowing that all (handler allocated) resources should have
+ // been freed. That is, we should be able to determine leaks.
+ if (0 == handler_thread_in_use_count) {
+ print_statistics(1);
+ CYG_TEST_PASS_FINISH("Kernel thread stress test OK");
+ }
+ }
+#endif /* DEATH_TIME_LIMIT */
+
+ cyg_thread_delay(3);
+ }
+}
+
+/* client_program() -- an obnoxious client which makes a lot of requests */
+void client_program(cyg_addrword_t data)
+{
+ int delay;
+
+ system_clockH = cyg_real_time_clock();
+ cyg_clock_to_counter(system_clockH, &counterH);
+
+ for (;;) {
+ delay = (rand() % 20);
+
+ /* now send a request to the server */
+ cyg_mutex_lock(&client_request_lock); {
+ if (0 == clients_paused)
+ client_makes_request++;
+ } cyg_mutex_unlock(&client_request_lock);
+
+ cyg_thread_delay(10+delay);
+ }
+}
+
+/* listener_program() -- listens for a request and spawns a handler to
+ take care of the request */
+void listener_program(cyg_addrword_t data)
+{
+ for (;;) {
+ int make_request = 0;
+ cyg_mutex_lock(&client_request_lock); {
+ if (client_makes_request > 0) {
+ --client_makes_request;
+ make_request = 1;
+ }
+ } cyg_mutex_unlock(&client_request_lock);
+
+ if (make_request)
+ start_handler();
+
+ cyg_thread_delay(2 + (rand() % 10));
+ }
+}
+
+/* handler_program() -- is spawned to handle each incoming request */
+void handler_program(cyg_addrword_t data)
+{
+ /* here is where we perform specific stressful tasks */
+ perform_stressful_tasks();
+
+ cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000)))));
+
+ {
+ // Loop until the handler id and priority can be communicated to
+ // the main_program.
+ int freed = 0;
+ do {
+ cyg_mutex_lock(&free_handler_lock); {
+ if (-1 == free_handler_id) {
+ free_handler_id = data;
+ free_handler_pri = P_BASE_HANDLER+(int) data;
+ freed = 1;
+ }
+ } cyg_mutex_unlock(&free_handler_lock);
+ if (!freed)
+ cyg_thread_delay(2);
+ } while (!freed);
+ }
+
+ // Then exit.
+ cyg_thread_exit();
+}
+
+/* start a new handler */
+void start_handler(void)
+{
+ int prio;
+ char* name;
+ int handler_slot = 0;
+ int found = 0;
+
+ while (!found) {
+ cyg_mutex_lock(&handler_slot_lock); {
+ for (handler_slot = 0; handler_slot < MAX_HANDLERS;++handler_slot){
+ if (!handler_thread_in_use[handler_slot]) {
+ found = 1;
+ handler_thread_in_use[handler_slot]++;
+ handler_thread_in_use_count++;
+ break;
+ }
+ }
+ } cyg_mutex_unlock(&handler_slot_lock);
+ if (!found)
+ cyg_thread_delay(1);
+ }
+
+ CYG_ASSERT(1 == handler_thread_in_use[handler_slot],
+ "Handler usage count wrong!");
+
+ prio = P_BASE_HANDLER+handler_slot;
+ CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!");
+ priority_in_use[prio]++;
+
+ name = &thread_name[prio][0];
+ sprintf(name, "handler-%02d/%02d", handler_slot, prio);
+
+ priority_translation[prio] =
+ sc_thread_create(prio, handler_program,
+ (cyg_addrword_t) handler_slot,
+ name, (void *) handler_stack[handler_slot],
+ STACK_SIZE_HANDLER, &handlerH[handler_slot],
+ &handler_thread_s[handler_slot]);
+ cyg_thread_resume(handlerH[handler_slot]);
+ ++statistics.handler_invocation_histogram[handler_slot];
+}
+
+/* free a locked handler thread */
+void stop_handler(int handler_id, int handler_pri)
+{
+ // Finally delete the handler thread. This must be done in a
+ // loop, waiting for the call to return true. If it returns
+ // false, go to sleep for a bit, so the killed thread gets a
+ // chance to run and complete its business.
+ while (!cyg_thread_delete(handlerH[handler_id])) {
+ cyg_thread_delay(1);
+ }
+ ++statistics.thread_exits;
+
+ // Free the handler resources.
+ cyg_mutex_lock(&handler_slot_lock); {
+ handler_thread_in_use[handler_id]--;
+ handler_thread_in_use_count--;
+ priority_in_use[handler_pri]--;
+ CYG_ASSERT(0 == priority_in_use[handler_pri],
+ "Priority not in use!");
+ CYG_ASSERT(0 == handler_thread_in_use[handler_id],
+ "Handler not in use!");
+ CYG_ASSERT(0 <= handler_thread_in_use_count,
+ "Stopped more handlers than was started!");
+ } cyg_mutex_unlock(&handler_slot_lock);
+
+}
+
+
+/* do things which will stress the system */
+void perform_stressful_tasks()
+{
+#define MAX_MALLOCED_SPACES 100 /* do this many mallocs at most */
+#define MALLOCED_BASE_SIZE 1 /* basic size in bytes */
+ char *spaces[MAX_MALLOCED_SPACES];
+ int sizes[MAX_MALLOCED_SPACES];
+ unsigned int i, j, size;
+
+ cyg_uint8 pool_space[10][100];
+ cyg_handle_t mempool_handles[10];
+ cyg_mempool_fix mempool_objects[10];
+
+ /* here I use malloc, which uses the kernel's variable memory pools.
+ note that malloc/free is a bit simple-minded here: it does not
+ try to really fragment things, and it does not try to make the
+ allocation/deallocation concurrent with other thread execution
+ (although I'm about to throw in a yield()) */
+ for (i = 0; i < MAX_MALLOCED_SPACES; ++i) {
+ ++statistics.malloc_tries;
+ size = (i*2+1)*MALLOCED_BASE_SIZE;
+ spaces[i] = (char *) malloc(size);
+ sizes[i] = size;
+
+ if (spaces[i] != NULL) {
+ // Fill with a known value (differs between chunk).
+ for (j = 0; j < size; ++j) {
+ spaces[i][j] = 0x50 | ((j+i) & 0x0f);
+ }
+ }
+
+ if (i % (MAX_MALLOCED_SPACES/10) == 0) {
+ cyg_thread_yield();
+ }
+ if (i % (MAX_MALLOCED_SPACES/15) == 0) {
+ cyg_thread_delay(i % 5);
+ }
+ }
+
+ cyg_thread_delay(5);
+
+ /* now free it all up */
+ for (i = 0; i < MAX_MALLOCED_SPACES; ++i) {
+ if (spaces[i] != NULL) {
+ size = sizes[i];
+ for (j = 0; j < size; ++j) {
+ // Validate chunk data.
+ if ((0x50 | ((j+i) & 0x0f)) != spaces[i][j]) {
+ printf("Bad byte in chunk\n");
+ }
+ spaces[i][j] = 0xAA; /* write a bit pattern */
+ }
+ free(spaces[i]);
+ } else {
+ ++statistics.malloc_failures;
+ }
+ }
+
+ /* now allocate and then free some fixed-size memory pools; for
+ now this is simple-minded because it does not have many threads
+ sharing the memory pools and racing for memory. */
+ for (i = 0; i < 10; ++i) {
+ cyg_mempool_fix_create(pool_space[i], 100, (i+1)*3,
+ &mempool_handles[i], &mempool_objects[i]);
+ }
+
+ for (i = 0; i < 10; ++i) {
+ spaces[i] = cyg_mempool_fix_try_alloc(mempool_handles[i]);
+ }
+
+ for (i = 0; i < 10; ++i) {
+ if (spaces[i]) {
+ cyg_mempool_fix_delete(mempool_handles[i]);
+ }
+ }
+}
+
+/* report_alarm_func() is invoked as an alarm handler, so it should be
+ quick and simple. in this case it sets a global flag which is
+ checked by main_program. */
+void report_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
+{
+ time_to_report = 1;
+}
+
+#ifdef DEATH_TIME_LIMIT
+/* this sets up death alarms. it gets the handle and alarm from the
+ caller, since they must persist for the life of the alarm */
+void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,
+ cyg_alarm *death_alarm_p, int *killed_p)
+{
+ cyg_handle_t system_clockH, counterH;
+ cyg_resolution_t rtc_res;
+
+ system_clockH = cyg_real_time_clock();
+ cyg_clock_to_counter(system_clockH, &counterH);
+
+ cyg_alarm_create(counterH, death_alarm_func,
+ (cyg_addrword_t) killed_p,
+ deathHp, death_alarm_p);
+ rtc_res = cyg_clock_get_resolution(system_clockH);
+ {
+ cyg_tick_count_t tick_delay;
+ tick_delay = (long long)
+ ((1000000000.0*rtc_res.divisor)
+ *((double)DEATH_TIME_LIMIT)/((double)rtc_res.dividend));
+ if ( cyg_test_is_simulator )
+ tick_delay /= SIM_DELAY_DIVISOR;
+#ifdef CYGPKG_HAL_SYNTH
+ // 20 seconds is a long time compared to the run time of other tests.
+ // Reduce to 10 seconds, allowing more tests to get run.
+ tick_delay /= 2;
+#endif
+
+ cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0);
+ }
+}
+#endif
+
+/* death_alarm_func() is the alarm handler that kills the current
+ thread after a specified timeout. It does so by setting a flag the
+ thread is constantly checking. */
+void death_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
+{
+ int *killed_p;
+ killed_p = (int *) data;
+ *killed_p = 1;
+}
+
+/* now I write the sc_ versions of the cyg_functions */
+cyg_addrword_t sc_thread_create(
+ cyg_addrword_t sched_info, /* scheduling info (eg pri) */
+ cyg_thread_entry_t *entry, /* entry point function */
+ cyg_addrword_t entry_data, /* entry data */
+ char *name, /* optional thread name */
+ void *stack_base, /* stack base, NULL = alloc */
+ cyg_ucount32 stack_size, /* stack size, 0 = default */
+ cyg_handle_t *handle, /* returned thread handle */
+ cyg_thread *thread /* put thread here */
+ )
+{
+ ++statistics.thread_creations;
+
+ cyg_thread_create(sched_info, entry, entry_data, name,
+ stack_base, stack_size, handle, thread);
+
+ return cyg_thread_get_priority(*handle);
+}
+
+
+#define MINS_HOUR (60)
+#define MINS_DAY (60*24)
+
+void print_statistics(int print_full)
+{
+ int i;
+ static int stat_dumps = 0;
+ static int print_count = 0;
+ static int shift_count = 0;
+ int minutes;
+
+ stat_dumps++;
+
+ // Find number of minutes.
+ minutes = time_report_delay*stat_dumps / 60;
+
+ if (!print_full) {
+ // Return if time/minutes not integer.
+ if ((time_report_delay*stat_dumps % 60) != 0)
+ return;
+
+ // After the first day, only dump stat once per day. Do print
+ // a . on the hour though.
+ if ((minutes > MINS_DAY) && ((minutes % MINS_DAY) != 0)) {
+ if ((minutes % MINS_HOUR) == 0) {
+ printf(".");
+ fflush(stdout);
+ }
+ return;
+ }
+
+ // After the first hour of the first day, only dump stat once
+ // per hour. Do print . each minute though.
+ if ((minutes < MINS_DAY) && (minutes > MINS_HOUR)
+ && ((minutes % MINS_HOUR) != 0)) {
+ printf(".");
+ fflush(stdout);
+ return;
+ }
+ }
+
+ printf("\nState dump %d (%d hours, %d minutes) [numbers >>%d]\n",
+ ++print_count, minutes / MINS_HOUR, minutes % MINS_HOUR,
+ shift_count);
+
+ cyg_mutex_lock(&statistics_print_lock); {
+ //--------------------------------
+ // Information private to this test:
+ printf(" Handler-invocations: ");
+ for (i = 0; i < MAX_HANDLERS; ++i) {
+ printf("%4lu ", statistics.handler_invocation_histogram[i]);
+ }
+ printf("\n");
+ printf(" malloc()-tries/failures: -- %7lu %7lu\n",
+ statistics.malloc_tries, statistics.malloc_failures);
+ printf(" client_makes_request: %d\n", client_makes_request);
+
+ // Check for big numbers and reduce if getting close to overflow
+ if (statistics.malloc_tries > 0x40000000) {
+ shift_count++;
+ for (i = 0; i < MAX_HANDLERS; ++i) {
+ statistics.handler_invocation_histogram[i] >>= 1;
+ }
+ statistics.malloc_tries >>= 1;
+ statistics.malloc_failures >>= 1;
+ }
+ } cyg_mutex_unlock(&statistics_print_lock);
+
+#if CYGINT_ISO_MALLINFO
+ //--------------------------------
+ // System information
+ {
+ struct mallinfo mem_info;
+
+ mem_info = mallinfo();
+
+ printf(" Memory system: Total=0x%08x Free=0x%08x Max=0x%08x\n",
+ mem_info.arena, mem_info.fordblks, mem_info.maxfree);
+ }
+#endif
+
+ // Dump stack status
+ printf(" Stack usage:\n");
+ cyg_test_dump_interrupt_stack_stats( " Interrupt" );
+ cyg_test_dump_idlethread_stack_stats( " Idle" );
+
+ cyg_test_dump_stack_stats(" Main", main_stack,
+ main_stack + sizeof(main_stack));
+ for (i = 0; i < MAX_HANDLERS; i++) {
+ cyg_test_dump_stack_stats(" Handler", handler_stack[i],
+ handler_stack[i] + sizeof(handler_stack[i]));
+ }
+ for (i = 0; i < N_LISTENERS; i++) {
+ cyg_test_dump_stack_stats(" Listener", listener_stack[i],
+ listener_stack[i] + sizeof(listener_stack[i]));
+ }
+ for (i = 0; i < N_CLIENTS; i++) {
+ cyg_test_dump_stack_stats(" Client", client_stack[i],
+ client_stack[i] + sizeof(client_stack[i]));
+ }
+}
+
+#else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */
+/* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */
+#define N_A_MSG "not enough priorities available"
+#endif /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */
+/* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */
+
+#else /* CYGINT_ISO_MALLOC */
+# define N_A_MSG "this test needs malloc"
+#endif /* CYGINT_ISO_MALLOC */
+
+#else /* CYGFUN_KERNEL_THREADS_TIMER */
+# define N_A_MSG "this test needs kernel threads timer"
+#endif /* CYGFUN_KERNEL_THREADS_TIMER */
+
+#else /* CYGPKG_LIBM */
+# define N_A_MSG "this test needs libm"
+#endif /* CYGPKG_LIBM */
+
+#else /* CYGINT_ISO_STDIO_FORMATTED_IO */
+# define N_A_MSG "this test needs stdio formatted I/O"
+#endif /* CYGINT_ISO_STDIO_FORMATTED_IO */
+
+#else // def CYGFUN_KERNEL_API_C
+# define N_A_MSG "this test needs Kernel C API"
+#endif
+
+#else // def CYGPKG_KERNEL && CYGPKG_IO && CYGPKG_ISOINFRA
+# define N_A_MSG "this tests needs Kernel, isoinfra and IO"
+#endif
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
diff --git a/cesar/ecos/packages/kernel/current/tests/sync2.cxx b/cesar/ecos/packages/kernel/current/tests/sync2.cxx
new file mode 100644
index 0000000000..d6e349a048
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/sync2.cxx
@@ -0,0 +1,201 @@
+//==========================================================================
+//
+// sync2.cxx
+//
+// Sync test 2 -- test of different locking mechanisms
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-18
+// Description:
+// Creates some threads and tests the various synchronization
+// mechanisms. Four threads are created t0..t3. t0 and t3 grab a
+// mutex and check they have exclusive access to shared variable.
+// t0,t1,t2 post each other in a loop with a semaphore so that
+// only one is running at any time. t1,t2,t3 do a similar thing
+// with counting semaphores, except that there are two active
+// threads.
+// Omissions:
+// Doesn't test condition variables
+//
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/mutex.hxx>
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+#define NTHREADS 4
+
+#include "testaux.hxx"
+
+static Cyg_Mutex m0;
+static Cyg_Binary_Semaphore s0, s1, s2(1);
+static Cyg_Counting_Semaphore cs0, cs1, cs2, cs3;
+
+static const cyg_ucount16 n = 1000;
+static cyg_ucount8 m0d=99, sd=2, cd0=99, cd1=99;
+
+static void entry0( CYG_ADDRWORD data )
+{
+ for(cyg_ucount16 i=0; i<n; i++) {
+ s2.wait();
+ CHECK( 2 == sd );
+ sd = 0;
+ m0.lock(); {
+ m0d = 0;
+ s0.post();
+ CHECK( 0 == m0d );
+ } m0.unlock();
+ }
+ // wait for 3 explicit posts to indicate threads have stopped.
+ for(cyg_ucount8 i=0; i<3; i++)
+ cs3.wait();
+
+ CHECK( ! s0.posted() );
+ CHECK( ! s1.posted() );
+ CHECK( s2.posted() );
+
+ CHECK( 0 == cs0.peek() );
+ CHECK( 0 == cs1.peek() );
+ CHECK( 0 == cs2.peek() );
+ CHECK( 0 == cs3.peek() );
+
+ CHECK( 0 == cd0 );
+ CHECK( 0 == cd1 );
+ CYG_TEST_PASS_FINISH("Sync 2 OK");
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ for(cyg_ucount16 i=0; i<n; i++) {
+ s0.wait();
+ CHECK( 0 == sd );
+ sd = 1;
+ cd0 = 1;
+ cs1.post();
+ cd1 = 1;
+ cs1.post();
+ s1.post();
+ cs0.wait();
+ CHECK( 0 == cd0 );
+ cs0.wait();
+ CHECK( 0 == cd1 );
+ }
+ cs3.post();
+ s0.wait();
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+static void entry2( CYG_ADDRWORD data )
+{
+ for(cyg_ucount16 i=0; i<n; i++) {
+ s1.wait();
+ CHECK( 1 == sd );
+ sd = 2;
+ cs1.wait();
+ CHECK( 1 == cd0 );
+ cd0 = 2;
+ cs2.post();
+ s2.post();
+ cs1.wait();
+ CHECK( 1 == cd1 );
+ cd1 = 2;
+ cs2.post();
+ }
+ cs3.post();
+ s1.wait();
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+static void entry3( CYG_ADDRWORD data )
+{
+ for(cyg_ucount16 i=0; i < n*2; i++) {
+ cs2.wait();
+ CHECK( 2 == cd0 || 2 == cd1 );
+ m0.lock(); {
+ m0d = 3;
+ if( 2 == cd0 )
+ cd0 = 0;
+ else {
+ CHECK( 2 == cd1 );
+ cd1 = 0;
+ }
+ cs0.post();
+ CHECK( 3 == m0d );
+ } m0.unlock();
+ }
+ cs3.post();
+ cs1.wait();
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+
+void sync2_main(void)
+{
+ CYG_TEST_INIT();
+
+ new_thread(entry0, 0);
+ new_thread(entry1, 1);
+ new_thread(entry2, 2);
+ new_thread(entry3, 3);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_PASS_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ sync2_main();
+}
+
+// EOF sync2.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/sync3.cxx b/cesar/ecos/packages/kernel/current/tests/sync3.cxx
new file mode 100644
index 0000000000..f2c6e2ec13
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/sync3.cxx
@@ -0,0 +1,232 @@
+//==========================================================================
+//
+// sync3.cxx
+//
+// Sync test 3 -- tests priorities and priority inheritance
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-18
+// Description:
+// Creates mutexes and threads to set up starvation condition.
+// Checks simple priority inheritance cures this.
+//
+// The starvation condition is caused by the highest priority
+// thread, t0 waiting on a mutex which is never released because
+// it is held by t2. t2 never releases it because t1 will be
+// running at a priority level higher than t2 (but lower than t0).
+//
+// With priority inheritance enabled, t2 will inherit its priority
+// from t0 when t0 tries to grab the mutex.
+//
+// Options:
+// CYGIMP_THREAD_PRIORITY
+// CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT
+// CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_SIMPLE
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/mutex.hxx>
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+#if defined(CYGIMP_THREAD_PRIORITY) && \
+ !defined(CYGPKG_KERNEL_SMP_SUPPORT)
+
+// ------------------------------------------------------------------------
+// Manufacture a simpler feature test macro for priority inheritance than
+// the configuration gives us. We have priority inheritance if it is configured
+// as the only protocol, or if it is the default protocol for dynamic protocol
+// choice.
+// FIXME: If we have dynamic protocol choice, we can also set priority inheritance
+// as the protocol to be used on the mutexes we are interested in. At present we
+// do not do this.
+
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC
+# ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_INHERIT
+# define PRIORITY_INHERITANCE
+# else
+# undef PRIORITY_INHERITANCE
+# endif
+# else
+# define PRIORITY_INHERITANCE
+# endif
+#else
+# undef PRIORITY_INHERITANCE
+#endif
+
+// ------------------------------------------------------------------------
+
+#define NTHREADS 3
+
+#include "testaux.hxx"
+
+static Cyg_Mutex m0;
+static Cyg_Binary_Semaphore s0, s1, s2;
+
+static cyg_ucount8 m0d = 9;
+
+static void check_priorities_normal()
+{
+ CHECK( 5 == thread[0]->get_priority());
+ CHECK( 6 == thread[1]->get_priority());
+ CHECK( 7 == thread[2]->get_priority());
+}
+
+static void check_priorities_inherited()
+{
+ CHECK( 5 == thread[0]->get_priority());
+ CHECK( 6 == thread[1]->get_priority());
+#ifdef PRIORITY_INHERITANCE
+ CHECK( 5 == thread[2]->get_current_priority());
+#endif
+ CHECK( 7 == thread[2]->get_priority());
+
+}
+
+static void entry0( CYG_ADDRWORD data )
+{
+ s0.wait(); // wait until t2 has gained m0.lock
+ check_priorities_normal();
+ m0.lock(); {
+ check_priorities_normal();
+ CHECK( 2 == m0d );
+ m0d = 0;
+ } m0.unlock();
+ check_priorities_normal();
+#ifdef PRIORITY_INHERITANCE
+ CYG_TEST_PASS_FINISH("Sync 3 OK -- priority inheritance worked");
+#else
+ CYG_TEST_FAIL_FINISH("Sync 3: thread not starved");
+#endif
+ // NOT REACHED
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ s1.wait();
+ // The delay below will allow testing of the priority inheritance
+ // mechanism when scheduler does not guarantee to schedule threads
+ // in strict priority order.
+ for ( volatile cyg_ucount32 i=0; i < 100000; i++ )
+ ; // math is hard
+
+#ifdef PRIORITY_INHERITANCE
+ // thread0 should have stopped by this point
+ CYG_TEST_FAIL_FINISH("Sync 3: priority inheritance mechanism failed");
+#else
+ // With strict priority scheduling and no priority inheritance
+ // this is expected to happen.
+ CYG_TEST_PASS_FINISH("Sync 3 OK");
+#endif
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+void entry2( CYG_ADDRWORD data )
+{
+ m0.lock(); {
+ CHECK( 9 == m0d );
+ check_priorities_normal();
+ s0.post(); // Now I have lock on m0, wake t0 then t1
+ check_priorities_inherited();
+ s1.post();
+ check_priorities_inherited();
+ m0d = 2;
+ } m0.unlock();
+ check_priorities_normal();
+ m0.lock(); {
+ check_priorities_normal();
+ CHECK( 0 == m0d );
+ m0d = 21;
+ s2.wait(); // never posted
+ } m0.unlock();
+}
+
+
+
+void sync3_main(void)
+{
+ CYG_TEST_INIT();
+
+ new_thread( entry0, 0);
+ new_thread( entry1, 1);
+ new_thread( entry2, 2);
+
+ thread[0]->set_priority(5);
+ thread[1]->set_priority(6);
+ thread[2]->set_priority(7);
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ sync3_main();
+}
+
+#else // defined(CYGIMP_THREAD_PRIORITY) etc
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("Sync3 test requires:\n"
+ "defined(CYGIMP_THREAD_PRIORITY) &&\n"
+ "!defined(CYGPKG_KERNEL_SMP_SUPPORT)\n");
+ CYG_TEST_NA("Sync3 test requirements");
+
+}
+
+#endif // defined(CYGIMP_THREAD_PRIORITY) etc
+
+// EOF sync3.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/tcdiag.cxx b/cesar/ecos/packages/kernel/current/tests/tcdiag.cxx
new file mode 100644
index 0000000000..ea4d8c648d
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/tcdiag.cxx
@@ -0,0 +1,97 @@
+//==========================================================================
+//
+// tcdiag.cxx
+//
+// Kernel diag test harness.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-17
+// Description: Test harness implementation that uses the kernel's
+// diag channel. This is intended for manual testing
+// of the kernel.
+//####DESCRIPTIONEND####
+
+#include <testcase.h>
+#include <diag.h>
+
+bool cyg_test_is_simulator=false; // infrastructure changes as necessary
+
+void cyg_test_init()
+{
+ diag_init();
+}
+
+void cyg_test_output(int status, char *msg, int line, char *file)
+{
+ char *st;
+
+ switch (status) {
+ case 0:
+ st = "FAIL:";
+ break;
+ case 1:
+ st = "PASS:";
+ break;
+ case 2:
+ st = "EXIT:";
+ break;
+ case 3:
+ st = "INFO:";
+ break;
+ }
+
+ diag_write_string(st);
+ diag_write_char('<');
+ diag_write_string(msg);
+ diag_write_string("> Line: ");
+ diag_write_dec(line);
+ diag_write_string(", File: ");
+ diag_write_string(file);
+ diag_write_char('\n');
+
+}
+
+// This is an appropriate function to set a breakpoint on
+void cyg_test_exit()
+{
+ for(;;)
+ ;
+}
+// EOF tcdiag.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/testaux.h b/cesar/ecos/packages/kernel/current/tests/testaux.h
new file mode 100644
index 0000000000..10712c28a6
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/testaux.h
@@ -0,0 +1,62 @@
+#ifndef CYGONCE_KERNEL_TESTS_TESTAUX_H
+#define CYGONCE_KERNEL_TESTS_TESTAUX_H
+
+/*=================================================================
+//
+// testaux.h
+//
+// Auxiliary test header file
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-09
+// Description:
+// Defines some convenience functions to get us going. In
+// particular this file reserves space for NTHREADS threads,
+// which can be created by calls to aux_new_thread()
+// It also defines a CHECK function.
+//
+//####DESCRIPTIONEND####
+*/
+
+#define CHECK(b) CYG_TEST_CHECK(b,#b)
+
+#endif /* ifndef CYGONCE_KERNEL_TESTS_TESTAUX_H */
+
+/* EOF testaux.h */
diff --git a/cesar/ecos/packages/kernel/current/tests/testaux.hxx b/cesar/ecos/packages/kernel/current/tests/testaux.hxx
new file mode 100644
index 0000000000..b258600433
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/testaux.hxx
@@ -0,0 +1,110 @@
+#ifndef CYGONCE_KERNEL_TESTS_TESTAUX_HXX
+#define CYGONCE_KERNEL_TESTS_TESTAUX_HXX
+
+//==========================================================================
+//
+// testaux.hxx
+//
+// Auxiliary test header file
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-03-09
+// Description:
+// Defines some convenience functions to get us going. In
+// particular this file reserves space for NTHREADS threads,
+// which can be created by calls to aux_new_thread()
+// It also defines a CHECK function.
+//
+//####DESCRIPTIONEND####
+
+
+inline void *operator new(size_t size, void *ptr) { return ptr; };
+
+
+#include <pkgconf/hal.h>
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+#ifdef NTHREADS
+
+#ifndef STACKSIZE
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+#endif
+
+static Cyg_Thread *thread[NTHREADS];
+
+typedef CYG_WORD64 CYG_ALIGNMENT_TYPE;
+
+static CYG_ALIGNMENT_TYPE thread_obj[NTHREADS] [
+ (sizeof(Cyg_Thread)+sizeof(CYG_ALIGNMENT_TYPE)-1)
+ / sizeof(CYG_ALIGNMENT_TYPE) ];
+
+static CYG_ALIGNMENT_TYPE stack[NTHREADS] [
+ (STACKSIZE+sizeof(CYG_ALIGNMENT_TYPE)-1)
+ / sizeof(CYG_ALIGNMENT_TYPE) ];
+
+static volatile int nthreads = 0;
+
+static Cyg_Thread *new_thread(cyg_thread_entry *entry, CYG_ADDRWORD data)
+{
+ int _nthreads = nthreads++;
+
+ CYG_ASSERT(_nthreads < NTHREADS,
+ "Attempt to create more than NTHREADS threads");
+
+ thread[_nthreads] = new( (void *)&thread_obj[_nthreads] )
+ Cyg_Thread(CYG_SCHED_DEFAULT_INFO,
+ entry, data,
+ NULL, // no name
+ (CYG_ADDRESS)stack[_nthreads], STACKSIZE );
+
+ thread[_nthreads]->resume();
+
+ return thread[_nthreads];
+}
+#endif // defined(NTHREADS)
+
+#define CHECK(b) CYG_TEST_CHECK(b,#b)
+
+#endif // ifndef CYGONCE_KERNEL_TESTS_TESTAUX_HXX
+
+// End of testaux.hxx
diff --git a/cesar/ecos/packages/kernel/current/tests/thread0.cxx b/cesar/ecos/packages/kernel/current/tests/thread0.cxx
new file mode 100644
index 0000000000..db0209e77e
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/thread0.cxx
@@ -0,0 +1,114 @@
+//==========================================================================
+//
+// thread0.cxx
+//
+// Thread test 0
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-11
+// Description: Limited to checking constructors/destructors
+// Omissions:
+// Thread constructors with 2 or 3 args are not supported at time
+// of writing test.
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/thread.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/thread.inl>
+
+#include "testaux.hxx"
+
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+static char stack[STACKSIZE];
+
+static cyg_thread_entry entry;
+
+static void entry( CYG_ADDRWORD data )
+{
+}
+
+static int *p;
+
+static bool flash( void )
+{
+#if 0 // no facility to allocate stack exists yet.
+ Cyg_Thread t0( entry, 0x111 );
+
+ CYG_ASSERTCLASS(&t0, "error");
+
+ Cyg_Thread t1( entry, (CYG_ADDRWORD)&t0, STACKSIZE );
+
+ CYG_ASSERTCLASS(&t1, "error");
+#endif
+ Cyg_Thread t2( CYG_SCHED_DEFAULT_INFO,
+ entry, (CYG_ADDRWORD)p,
+ "thread t2",
+ (CYG_ADDRESS)stack, STACKSIZE );
+
+ CYG_ASSERTCLASS(&t2, "error");
+
+ return true;
+}
+
+void thread0_main( void )
+{
+ CYG_TEST_INIT();
+
+ CHECK(flash());
+ CHECK(flash());
+
+ CYG_TEST_PASS_FINISH("Thread 0 OK");
+
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ thread0_main();
+}
+// EOF thread0.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/thread1.cxx b/cesar/ecos/packages/kernel/current/tests/thread1.cxx
new file mode 100644
index 0000000000..2596a1016a
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/thread1.cxx
@@ -0,0 +1,172 @@
+//==========================================================================
+//
+// thread1.cxx
+//
+// Thread test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-11
+// Description: Tests some basic thread functions.
+// Omissions: Cyg_ThreadTimer
+// Cyg_Thread
+// exit -- not necessarily called
+// yield
+// set_priority
+// get_priority
+// get/set_sleep_reason
+// get/set_wake_reason
+// set/clear_timer
+// Cyg_ThreadQueue
+//
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/thread.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/thread.inl>
+
+#include "testaux.hxx"
+
+#ifdef CYGNUM_HAL_STACK_SIZE_TYPICAL
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+#else
+#define STACKSIZE 2000
+#endif
+
+static char stack[2][STACKSIZE];
+
+static char thread[2][sizeof(Cyg_Thread)];
+
+static Cyg_Thread *pt0,*pt1;
+static cyg_uint16 uid0,uid1;
+
+
+static void entry0( CYG_ADDRWORD data )
+{
+ CHECK( 222 == data );
+
+ uid0 = pt0->get_unique_id();
+
+ pt1->suspend();
+ pt1->resume();
+
+ do {
+ pt0->delay(1);
+ } while( Cyg_Thread::RUNNING == pt1->get_state() );
+
+ CHECK( Cyg_Thread::SLEEPING == pt1->get_state() );
+
+ pt1->wake();
+
+ CHECK( uid0 != uid1 );
+
+ CYG_TEST_PASS_FINISH("Thread 1 OK");
+}
+
+static void entry1( CYG_ADDRWORD data )
+{
+ CHECK( 333 == data );
+
+ uid1 = pt1->get_unique_id();
+
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ CHECK( self == pt1 );
+
+ pt1->sleep();
+ pt1->suspend();
+
+ Cyg_Thread::exit(); // no guarantee this will be called
+}
+
+void thread1_main( void )
+{
+ CYG_TEST_INIT();
+
+ pt0 = new((void *)&thread[0])
+ Cyg_Thread(CYG_SCHED_DEFAULT_INFO,
+ entry0, 222,
+ "thread 0",
+ (CYG_ADDRESS)stack[0], STACKSIZE );
+ pt1 = new((void *)&thread[1])
+ Cyg_Thread(CYG_SCHED_DEFAULT_INFO,
+ entry1, 333,
+ "thread 1",
+ (CYG_ADDRESS)stack[1], STACKSIZE );
+
+ CYG_ASSERTCLASS( pt0, "error" );
+ CYG_ASSERTCLASS( pt1, "error" );
+
+ pt0->resume();
+ pt1->resume();
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ thread1_main();
+}
+
+#else // ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA("Kernel threads timer disabled");
+}
+
+#endif // ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+// EOF thread1.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/thread2.cxx b/cesar/ecos/packages/kernel/current/tests/thread2.cxx
new file mode 100644
index 0000000000..e53181987d
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/thread2.cxx
@@ -0,0 +1,236 @@
+//==========================================================================
+//
+// thread2.cxx
+//
+// Thread test 2
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm
+// Date: 1998-02-19
+// Description:
+// tests scheduler & threads & priorities
+// + create multiple threads with various priorities
+// + check highest priority running thread is always running
+// + check next highest runs when highest suspended
+// + check several threads of equal priority share time
+// (only !CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES)
+// + check other threads are starved
+// + check setting priority dynamically causes a thread to
+// become/stay current/non-current
+// Omissions:
+// check yield
+// check can set threads with min and max priority
+// Options:
+// CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
+// CYGIMP_THREAD_PRIORITY
+// CYGNUM_KERNEL_SCHED_PRIORITIES
+// CYGSEM_KERNEL_SCHED_BITMAP
+// CYGSEM_KERNEL_SCHED_MLQUEUE
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/mutex.hxx>
+#include <cyg/kernel/sema.hxx>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/sched.inl>
+
+// ------------------------------------------------------------------------
+
+#if defined(CYGIMP_THREAD_PRIORITY) && \
+ !defined(CYGPKG_KERNEL_SMP_SUPPORT)
+
+// ------------------------------------------------------------------------
+
+static Cyg_Counting_Semaphore s0, s1, s2;
+
+static volatile cyg_ucount8 q = 0;
+
+static Cyg_Thread *thread0, *thread1, *thread2;
+
+#define NTHREADS 3
+#include "testaux.hxx"
+
+// ------------------------------------------------------------------------
+
+static void entry0( CYG_ADDRWORD data )
+{
+ CHECK( 0 == q++ );
+ s0.wait();
+ CHECK( 3 == q++ );
+ s1.post();
+ CHECK( 4 == q++ );
+ s0.wait();
+ s0.wait();
+ CYG_TEST_PASS_FINISH("Thread 2 OK");
+}
+
+// ------------------------------------------------------------------------
+
+static void entry1( CYG_ADDRWORD data )
+{
+ CHECK( 1 == q++ );
+ s1.wait();
+ CHECK( 5 == q++ );
+ thread0->set_priority(9);
+ s0.post();
+ CHECK( 6 == q++ );
+ thread2->set_priority(3);
+ CHECK( 8 == q++ );
+ s2.post();
+ CHECK( 12 == q++ );
+ CHECK( 9 == thread0->get_priority() );
+ CHECK( 6 == thread1->get_priority() );
+ CHECK( 7 == thread2->get_priority() );
+ q = 100;
+#if !(CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES) \
+ && defined(CYGSEM_KERNEL_SCHED_TIMESLICE)
+ thread2->set_priority(6);
+ CHECK( 6 == thread1->get_priority() );
+ CHECK( 6 == thread2->get_priority() );
+
+ while ( 100 == q )
+ ;
+ CHECK( 101 == q++ );
+ s1.wait();
+ CHECK( 103 == q++ );
+#endif
+ s0.post();
+ s1.wait();
+}
+
+// ------------------------------------------------------------------------
+
+static void entry2( CYG_ADDRWORD data )
+{
+ CHECK( 2 == q++ );
+ s0.post();
+ CHECK( 7 == q++ );
+ s2.wait();
+ CHECK( 9 == q++ );
+ thread1->set_priority(6);
+ CHECK( 10 == q++ );
+ thread2->set_priority(2);
+ CHECK( 11 == q++ );
+ thread2->set_priority(7);
+
+#if !(CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES) \
+ && defined(CYGSEM_KERNEL_SCHED_TIMESLICE)
+ CHECK( 6 == thread1->get_priority() );
+ CHECK( 6 == thread2->get_priority() );
+
+ CHECK( 100 == q++ );
+ while ( 101 == q )
+ ;
+ CHECK( 102 == q++ );
+ s1.post();
+#endif
+ s0.post();
+ s2.wait();
+}
+
+
+// ------------------------------------------------------------------------
+
+void thread2_main( void )
+{
+ CYG_TEST_INIT();
+
+ thread0 = new_thread( entry0, 0 );
+ thread1 = new_thread( entry1, 1 );
+ thread2 = new_thread( entry2, 2 );
+
+ thread0->resume();
+ thread1->resume();
+ thread2->resume();
+
+ thread0->set_priority(5);
+ thread1->set_priority(6);
+ thread2->set_priority(7);
+
+ if( 9 >= CYG_THREAD_MIN_PRIORITY )
+ CYG_TEST_FAIL_FINISH("Test requires priorities up to 9");
+
+ if( 2 <= CYG_THREAD_MAX_PRIORITY )
+ CYG_TEST_FAIL_FINISH("Test requires priorities as low as 2");
+
+ Cyg_Scheduler::start();
+
+ CYG_TEST_FAIL_FINISH("Unresolved");
+}
+
+// ------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ thread2_main();
+}
+// ------------------------------------------------------------------------
+
+
+#else // CYGPKG_KERNEL_SMP_SUPPORT etc
+
+// ------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("Thread2 test requires:\n"
+ "defined(CYGIMP_THREAD_PRIORITY) &&\n"
+ "!defined(CYGPKG_KERNEL_SMP_SUPPORT)\n");
+ CYG_TEST_NA("Thread2 test requirements");
+}
+
+// ------------------------------------------------------------------------
+
+#endif // CYGPKG_KERNEL_SMP_SUPPORT etc
+
+// ------------------------------------------------------------------------
+// EOF thread2.cxx
diff --git a/cesar/ecos/packages/kernel/current/tests/thread_gdb.c b/cesar/ecos/packages/kernel/current/tests/thread_gdb.c
new file mode 100644
index 0000000000..15ca90a7f7
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/thread_gdb.c
@@ -0,0 +1,413 @@
+//==========================================================================
+//
+// thread_gdb.c
+//
+// A test for thread support in GDB
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1998-09-21
+// Description: GDB thread support test.
+//####DESCRIPTIONEND####
+//
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/cyg_ass.h>
+
+#include <cyg/infra/testcase.h>
+
+#if defined(CYGFUN_KERNEL_API_C) && defined(CYGSEM_KERNEL_SCHED_MLQUEUE) &&\
+ (CYGNUM_KERNEL_SCHED_PRIORITIES > 26)
+
+#include <cyg/hal/hal_arch.h> // for CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+// -------------------------------------------------------------------------
+
+#define THREADS 10
+
+#ifdef CYGNUM_HAL_STACK_SIZE_TYPICAL
+#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+#else
+#define STACKSIZE (2*1024)
+#endif
+
+#define CONTROLLER_PRI_HI 0
+#define CONTROLLER_PRI_LO 25
+
+#define WORKER_PRI 3
+#define WORKER_PRI_RANGE 20
+
+
+// -------------------------------------------------------------------------
+
+// array of stacks for threads
+char thread_stack[THREADS][STACKSIZE];
+
+// array of threads.
+cyg_thread thread[THREADS];
+
+cyg_handle_t thread_handle[THREADS];
+
+volatile cyg_uint8 worker_state;
+
+#define WORKER_STATE_WAIT 1
+#define WORKER_STATE_BREAK 2
+#define WORKER_STATE_EXIT 9
+
+cyg_mutex_t worker_mutex;
+cyg_cond_t worker_cv;
+
+cyg_count32 workers_asleep = 0;
+
+cyg_count32 thread_count[THREADS];
+
+cyg_priority_t thread_pri[THREADS];
+
+
+
+// -------------------------------------------------------------------------
+
+extern void breakme(void)
+{
+}
+
+// -------------------------------------------------------------------------
+
+void worker( cyg_addrword_t id )
+{
+ for(;;)
+ {
+ thread_count[id]++;
+ thread_pri[id] = cyg_thread_get_priority( cyg_thread_self() );
+
+ switch( worker_state )
+ {
+ case WORKER_STATE_BREAK:
+ if( 0 == (id % 4) )
+ breakme();
+
+ case WORKER_STATE_WAIT:
+ cyg_mutex_lock( &worker_mutex );
+ workers_asleep++;
+ cyg_cond_wait( &worker_cv );
+ workers_asleep--;
+ cyg_mutex_unlock( &worker_mutex );
+ break;
+
+ case WORKER_STATE_EXIT:
+ cyg_thread_exit();
+
+ }
+ }
+}
+
+// -------------------------------------------------------------------------
+
+void controller( cyg_addrword_t id )
+{
+ cyg_priority_t pri;
+ int i;
+
+ cyg_mutex_init( &worker_mutex );
+ cyg_cond_init( &worker_cv, &worker_mutex );
+
+// 1 thread, it is running, it calls BREAKME();
+// +++ Thread status returned:
+// +++ 1 thread, running, is the current one
+
+ breakme();
+
+// Create N more threads; they are all suspended after creation. Adjust
+// the priorities of all the threads to lower than the controlling thread.
+// Make them all be distinct priorities as far as possible. BREAKME();
+// +++ 1 thread, running, + N suspended ones of different prios.
+
+ for( i = 1; i < THREADS; i++ )
+ {
+ pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE;
+
+ cyg_thread_create(pri, worker, (cyg_addrword_t)i, "worker",
+ (void *)(&thread_stack[i]), STACKSIZE,
+ &thread_handle[i], &thread[i]);
+
+ }
+
+ breakme();
+
+// Adjust the priorities of all the threads to lower than the controlling
+// thread. Make them all be THE SAME priority. BREAKME();
+// +++ 1 thread, running, + N suspended ones of same prio.
+
+ for( i = 1; i < THREADS; i++ )
+ {
+ cyg_thread_set_priority( thread_handle[i], WORKER_PRI );
+ }
+
+ breakme();
+
+// Release all the N threads, BREAKME();
+// +++ 1 thread, running, + N ready ones of same prio.
+
+ for( i = 1; i < THREADS; i++ )
+ {
+ cyg_thread_resume( thread_handle[i] );
+ }
+
+ breakme();
+
+// Adjust the priorities of all the threads, lower than the controlling
+// thread. Make them all be distinct priorities as far as possible.
+// BREAKME();
+// +++ 1 thread, running, + N ready ones of different prios.
+
+ for( i = 1; i < THREADS; i++ )
+ {
+ pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE;
+
+ cyg_thread_set_priority( thread_handle[i], pri );
+ }
+
+ breakme();
+
+// Command all the N threads to sleep; switch my own priority to lower
+// than theirs so that they all run and sleep, then I get back in and
+// BREAKME();
+// +++ 1 thread, running, + N sleeping ones of different prios.
+
+ worker_state = WORKER_STATE_WAIT;
+
+ cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_LO );
+
+ breakme();
+
+// Make them all be THE SAME priority; BREAKME();
+// +++ 1 thread, running, + N sleeping ones of same prio.
+
+ for( i = 1; i < THREADS; i++ )
+ {
+ cyg_thread_set_priority( thread_handle[i], WORKER_PRI );
+ }
+
+ breakme();
+
+// Wake them all up, they'll loop once and sleep again; I get in and
+// BREAKME();
+// +++ 1 thread, running, + N sleeping ones of same prio.
+
+ cyg_cond_broadcast( &worker_cv );
+
+ breakme();
+
+// Adjust the priorities of all the threads, higher than the controlling
+// thread. Make them all be distinct priorities as far as possible.
+// BREAKME();
+// +++ 1 thread, running, + N sleeping ones of different prios.
+
+ for( i = 1; i < THREADS; i++ )
+ {
+ pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE;
+
+ cyg_thread_set_priority( thread_handle[i], pri );
+ }
+
+ breakme();
+
+// Wake them all up, they'll loop once and sleep again; I get in and
+// BREAKME();
+// +++ 1 thread, running, + N sleeping ones of different prios.
+
+ cyg_cond_broadcast( &worker_cv );
+
+ breakme();
+
+// Set them all the same prio, set me to the same prio, BREAKME();
+// +++ 1 running, + N sleeping, *all* the same prio.
+
+ for( i = 0; i < THREADS; i++ )
+ {
+ cyg_thread_set_priority( thread_handle[i], WORKER_PRI );
+ }
+
+ breakme();
+
+// Wake them all up, they'll loop once and sleep again; I get in and
+// BREAKME(); repeatedly until they have all slept again.
+// +++ 1 running, + some sleeping, some ready, *all* the same prio.
+
+ cyg_cond_broadcast( &worker_cv );
+
+// cyg_thread_yield();
+
+ do
+ {
+ breakme();
+
+ } while( workers_asleep != THREADS-1 );
+
+ breakme();
+
+// Suspend some of the threads, BREAKME();
+// +++ 1 running, + some sleeping, some suspended, *all* the same prio.
+
+ for( i = 1; i < THREADS; i++ )
+ {
+ // suspend every 3rd thread
+ if( 0 == (i % 3) ) cyg_thread_suspend( thread_handle[i] );
+ }
+
+ breakme();
+
+
+// Change the prios all different, change my prio to highest , BREAKME();
+// +++ 1 running, + some sleeping, some suspended, different prios.
+
+ cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_HI );
+
+ for( i = 1; i < THREADS; i++ )
+ {
+ pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE;
+
+ cyg_thread_set_priority( thread_handle[i], pri );
+ }
+
+ breakme();
+
+// Wake up all the threads, BREAKME();
+// +++ 1 running, + some ready, some suspended/ready, different prios.
+
+ cyg_cond_broadcast( &worker_cv );
+
+ breakme();
+
+
+// Change my prio to lowest, let all the threads run, BREAKME().
+// +++ 1 running + some sleeping, some suspended/ready, different prios.
+
+ cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_LO );
+
+ breakme();
+
+// Resume all the threads, BREAKME();
+// +++ 1 running, + N ready, different prios.
+
+ for( i = 1; i < THREADS; i++ )
+ {
+ cyg_thread_resume( thread_handle[i] );
+ }
+
+ breakme();
+
+// Command some of the N threads to call BREAKME(); themselves (then sleep
+// again). Change my prio to low, so that they all get to run and hit the
+// breakpoint.
+// +++ A different one running every time, others in a mixture of
+// ready and sleeping states.
+
+ worker_state = WORKER_STATE_BREAK;
+
+ cyg_cond_broadcast( &worker_cv );
+
+ cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_LO );
+
+ breakme();
+
+// Command all the threads to exit; switch my own priority to lower
+// than theirs so that they all run and exit, then I get back in and
+// BREAKME();
+// +++ 1 thread, running, + N dormant ones.
+
+ worker_state = WORKER_STATE_EXIT;
+
+ cyg_cond_broadcast( &worker_cv );
+
+ breakme();
+
+#if 0
+
+// Cannot do this yet...
+
+// Destroy some of the N threads to invalidate their IDs. Re-create them
+// with new IDs, so that we get IDs 1,2,4,6,8,11,12,13,14,15 in use instead
+// of 1,2,3,4,5,6,7,8,9, if you see what I mean. Do all the above again.
+// Loop forever, or whatever...
+
+#endif
+
+ breakme();
+
+ CYG_TEST_PASS_FINISH("GDB Thread test OK");
+
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+
+ CYG_TEST_INIT();
+
+ cyg_thread_create(CONTROLLER_PRI_HI, controller, (cyg_addrword_t)0, "controller",
+ (void *)(&thread_stack[0]), STACKSIZE,
+ &thread_handle[0], &thread[0]);
+
+ // resume it
+ cyg_thread_resume(thread_handle[0]);
+
+
+ // Get the world going
+ cyg_scheduler_start();
+
+ CYG_TEST_FAIL_FINISH("Not reached");
+
+}
+
+#else /* def CYGFUN_KERNEL_API_C */
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_PASS_FINISH("Incorrect configuration for this test");
+}
+#endif /* def CYGFUN_KERNEL_API_C && ... */
+
+// -------------------------------------------------------------------------
+// EOF thread_gdb.c
diff --git a/cesar/ecos/packages/kernel/current/tests/timeslice.c b/cesar/ecos/packages/kernel/current/tests/timeslice.c
new file mode 100644
index 0000000000..eb61fc488f
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/timeslice.c
@@ -0,0 +1,282 @@
+//==========================================================================
+//
+// timeslice.c
+//
+// Timeslice test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2001-06-18
+// Description: A basic timeslicing test.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/kernel/smp.hxx>
+
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+//==========================================================================
+
+#if defined(CYGSEM_KERNEL_SCHED_TIMESLICE) && \
+ defined(CYGFUN_KERNEL_API_C) && \
+ defined(CYGSEM_KERNEL_SCHED_MLQUEUE) && \
+ defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \
+ !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) && \
+ (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
+
+//==========================================================================
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL*5
+
+#define NTHREADS_MAX (CYGNUM_KERNEL_CPU_MAX*6)
+
+static int ncpus = CYGNUM_KERNEL_CPU_MAX;
+
+static char test_stack[STACK_SIZE];
+static cyg_thread test_thread;
+static cyg_handle_t main_thread;
+
+static char stacks[NTHREADS_MAX][STACK_SIZE];
+static cyg_thread test_threads[NTHREADS_MAX];
+static cyg_handle_t threads[NTHREADS_MAX];
+
+static volatile int failed = false;
+
+static volatile cyg_uint32 slicerun[NTHREADS_MAX][CYGNUM_KERNEL_CPU_MAX];
+
+//==========================================================================
+
+void
+test_thread_timeslice(CYG_ADDRESS id)
+{
+ for(;;)
+ slicerun[id][CYG_KERNEL_CPU_THIS()]++;
+}
+
+//==========================================================================
+
+void run_test_timeslice(int nthread)
+{
+ int i,j;
+ cyg_uint32 cpu_total[CYGNUM_KERNEL_CPU_MAX];
+ cyg_uint32 cpu_threads[CYGNUM_KERNEL_CPU_MAX];
+ cyg_uint32 thread_total[NTHREADS_MAX];
+
+ CYG_TEST_INFO( "Timeslice Test: Check timeslicing works");
+
+ // Init flags.
+ for (i = 0; i < nthread; i++)
+ for( j = 0; j < ncpus; j++ )
+ slicerun[i][j] = 0;
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+
+ for (i = 0; i < nthread; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test_thread_timeslice, // entry
+ i, // index
+ "test_thread", // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume( threads[i]);
+ }
+
+ // Just wait a while, until the threads have all run for a bit.
+ cyg_thread_delay( CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS*100 );
+
+ // Suspend all the threads
+ for (i = 0; i < nthread; i++) {
+ cyg_thread_suspend(threads[i]);
+ }
+
+
+ // And check that a thread ran on each CPU, and that each thread
+ // ran.
+
+
+ diag_printf(" Thread ");
+ for( j = 0; j < ncpus; j++ )
+ {
+ cpu_total[j] = 0;
+ cpu_threads[j] = 0;
+ // " %11d" __123456789ab"
+ diag_printf(" CPU %2d",j);
+ }
+ // " %11d" __123456789ab"
+ diag_printf(" Total\n");
+ for (i = 0; i < nthread; i++)
+ {
+ thread_total[i] = 0;
+ diag_printf(" %2d ",i);
+ for( j = 0; j < ncpus; j++ )
+ {
+ thread_total[i] += slicerun[i][j];
+ cpu_total[j] += slicerun[i][j];
+ if( slicerun[i][j] > 0 )
+ cpu_threads[j]++;
+ diag_printf(" %11d",slicerun[i][j]);
+ }
+ diag_printf(" %11d\n",thread_total[i]);
+ if( thread_total[i] == 0 )
+ failed++;
+ }
+
+ diag_printf(" Total ");
+ for( j = 0; j < ncpus; j++ )
+ diag_printf(" %11d",cpu_total[j]);
+ diag_printf("\n");
+ diag_printf("Threads ");
+ for( j = 0; j < ncpus; j++ )
+ {
+ diag_printf(" %11d",cpu_threads[j]);
+ if( cpu_threads[j] < 2 )
+ failed++;
+ }
+ diag_printf("\n");
+
+ // Delete all the threads
+ for (i = 0; i < nthread; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+
+ CYG_TEST_INFO( "Timeslice Test: done");
+}
+
+
+//==========================================================================
+
+void
+run_tests(CYG_ADDRESS id)
+{
+ int step;
+ int nthread;
+
+ // Try to run about 10 times in total, with varying numbers of threads
+ // from only one extra up to the full set:
+
+ step = (NTHREADS_MAX - (1 + CYG_KERNEL_CPU_COUNT()))/10;
+ if( step == 0 ) step = 1;
+
+ for( nthread = 1 + CYG_KERNEL_CPU_COUNT() ;
+ nthread <= NTHREADS_MAX ;
+ nthread += step )
+ run_test_timeslice(nthread);
+
+ if( failed )
+ CYG_TEST_FAIL_FINISH("Timeslice test failed\n");
+
+ CYG_TEST_PASS_FINISH("Timeslice test OK");
+}
+
+//==========================================================================
+
+void timeslice_main( void )
+{
+ CYG_TEST_INIT();
+
+ // Work out how many CPUs we actually have.
+ ncpus = CYGNUM_KERNEL_CPU_MAX; //CYG_KERNEL_CPU_COUNT();
+
+ cyg_thread_create(0, // Priority - just a number
+ run_tests, // entry
+ 0, // index
+ "run_tests", // Name
+ test_stack, // Stack
+ STACK_SIZE, // Size
+ &main_thread, // Handle
+ &test_thread // Thread data structure
+ );
+ cyg_thread_resume( main_thread);
+
+ cyg_scheduler_start();
+}
+
+//==========================================================================
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ timeslice_main();
+}
+
+//==========================================================================
+
+#else // CYGSEM_KERNEL_SCHED_TIMESLICE etc
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("SMP test requires:\n"
+ "CYGSEM_KERNEL_SCHED_TIMESLICE &&\n"
+ "CYGPKG_KERNEL_SMP_SUPPORT &&\n"
+ "CYGFUN_KERNEL_API_C && \n"
+ "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n"
+ "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
+ "!CYGPKG_HAL_I386_LINUX &&\n"
+ "!CYGDBG_INFRA_DIAG_USE_DEVICE &&\n"
+ "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n");
+ CYG_TEST_NA("SMP test requirements");
+}
+
+#endif // CYGSEM_KERNEL_SCHED_TIMESLICE etc.
+
+//==========================================================================
+// EOF timeslice.c
diff --git a/cesar/ecos/packages/kernel/current/tests/tm_basic.cxx b/cesar/ecos/packages/kernel/current/tests/tm_basic.cxx
new file mode 100644
index 0000000000..c9e34b5581
--- /dev/null
+++ b/cesar/ecos/packages/kernel/current/tests/tm_basic.cxx
@@ -0,0 +1,1880 @@
+//==========================================================================
+//
+// tm_basic.cxx
+//
+// Basic timing test / scaffolding
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002, 2003 Gary Thomas
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1998-10-19
+// Description: Very simple kernel timing test
+//####DESCRIPTIONEND####
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/mutex.hxx>
+#include <cyg/kernel/sema.hxx>
+#include <cyg/kernel/flag.hxx>
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/clock.hxx>
+#include <cyg/kernel/clock.inl>
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/kernel/test/stackmon.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+// Define this to see the statistics with the first sample datum removed.
+// This can expose the effects of caches on the speed of operations.
+#undef STATS_WITHOUT_FIRST_SAMPLE
+
+#if defined(CYGFUN_KERNEL_API_C) && \
+ defined(CYGSEM_KERNEL_SCHED_MLQUEUE) && \
+ defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \
+ !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) && \
+ (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
+
+#define NTHREADS 1
+#include "testaux.hxx"
+
+// Structure used to keep track of times
+typedef struct fun_times {
+ cyg_uint32 start;
+ cyg_uint32 end;
+} fun_times;
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+#if defined(CYGMEM_REGION_ram_SIZE) && !(defined(CYGPKG_HAL_SPARC_LEON3_OPTIONS) || defined(CYGPKG_HAL_SPARC_LEON_OPTIONS))
+#define CYG_THREAD_OVERHEAD (STACK_SIZE+sizeof(cyg_thread)+(sizeof(fun_times)*2))
+#define NTEST_THREADS ((CYGMEM_REGION_ram_SIZE/16)/CYG_THREAD_OVERHEAD)
+#define CYG_MUTEX_OVERHEAD (sizeof(cyg_mutex_t)+sizeof(fun_times))
+#define NMUTEXES ((CYGMEM_REGION_ram_SIZE/16)/CYG_MUTEX_OVERHEAD)
+#define CYG_MBOX_OVERHEAD (sizeof(cyg_mbox)+sizeof(fun_times))
+#define NMBOXES ((CYGMEM_REGION_ram_SIZE/24)/CYG_MBOX_OVERHEAD)
+#define CYG_SEMAPHORE_OVERHEAD (sizeof(cyg_sem_t)+sizeof(fun_times))
+#define NSEMAPHORES ((CYGMEM_REGION_ram_SIZE/16)/CYG_SEMAPHORE_OVERHEAD)
+#define CYG_COUNTER_OVERHEAD (sizeof(cyg_counter)+sizeof(fun_times))
+#define NCOUNTERS ((CYGMEM_REGION_ram_SIZE/24)/CYG_COUNTER_OVERHEAD)
+#define CYG_FLAG_OVERHEAD (sizeof(cyg_flag_t)+sizeof(fun_times))
+#define NFLAGS ((CYGMEM_REGION_ram_SIZE/24)/CYG_FLAG_OVERHEAD)
+#define CYG_ALARM_OVERHEAD (sizeof(cyg_alarm)+sizeof(fun_times))
+#define NALARMS ((CYGMEM_REGION_ram_SIZE/16)/CYG_ALARM_OVERHEAD)
+#else
+// Defaults
+#define NTEST_THREADS 16
+#define NMUTEXES 32
+#define NMBOXES 32
+#define NSEMAPHORES 32
+#define NFLAGS 32
+#define NCOUNTERS 32
+#define NALARMS 32
+#endif
+
+#define NSAMPLES 32
+#define NTHREAD_SWITCHES 128
+#define NSCHEDS 128
+
+#define NSAMPLES_SIM 2
+#define NTEST_THREADS_SIM 2
+#define NTHREAD_SWITCHES_SIM 4
+#define NMUTEXES_SIM 2
+#define NMBOXES_SIM 2
+#define NSEMAPHORES_SIM 2
+#define NSCHEDS_SIM 4
+#define NFLAGS_SIM 2
+#define NCOUNTERS_SIM 2
+#define NALARMS_SIM 2
+
+static int nsamples;
+static int ntest_threads;
+static int nthread_switches;
+static int nmutexes;
+static int nmboxes;
+static int nsemaphores;
+static int nscheds;
+static int nflags;
+static int ncounters;
+static int nalarms;
+
+static char stacks[NTEST_THREADS][STACK_SIZE];
+static cyg_thread test_threads[NTEST_THREADS];
+static cyg_handle_t threads[NTEST_THREADS];
+static int overhead;
+static cyg_sem_t synchro;
+static fun_times thread_ft[NTEST_THREADS];
+
+static fun_times test2_ft[NTHREAD_SWITCHES];
+
+static cyg_mutex_t test_mutexes[NMUTEXES];
+static fun_times mutex_ft[NMUTEXES];
+static cyg_thread mutex_test_thread;
+static cyg_handle_t mutex_test_thread_handle;
+
+static cyg_mbox test_mboxes[NMBOXES];
+static cyg_handle_t test_mbox_handles[NMBOXES];
+static fun_times mbox_ft[NMBOXES];
+#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+static cyg_thread mbox_test_thread;
+static cyg_handle_t mbox_test_thread_handle;
+#endif
+
+static cyg_sem_t test_semaphores[NSEMAPHORES];
+static fun_times semaphore_ft[NSEMAPHORES];
+static cyg_thread semaphore_test_thread;
+static cyg_handle_t semaphore_test_thread_handle;
+
+static fun_times sched_ft[NSCHEDS];
+
+static cyg_counter test_counters[NCOUNTERS];
+static cyg_handle_t counters[NCOUNTERS];
+static fun_times counter_ft[NCOUNTERS];
+
+static cyg_flag_t test_flags[NFLAGS];
+static fun_times flag_ft[NFLAGS];
+
+static cyg_alarm test_alarms[NALARMS];
+static cyg_handle_t alarms[NALARMS];
+static fun_times alarm_ft[NALARMS];
+
+static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;
+static long ns_per_system_clock;
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
+// Data kept by kernel real time clock measuring clock interrupt latency
+extern cyg_tick_count total_clock_latency, total_clock_interrupts;
+extern cyg_int32 min_clock_latency, max_clock_latency;
+extern bool measure_clock_latency;
+#endif
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) && defined(HAL_CLOCK_LATENCY)
+extern cyg_tick_count total_clock_dsr_latency, total_clock_dsr_calls;
+extern cyg_int32 min_clock_dsr_latency, max_clock_dsr_latency;
+extern bool measure_clock_latency;
+#endif
+
+void run_sched_tests(void);
+void run_thread_tests(void);
+void run_thread_switch_test(void);
+void run_mutex_tests(void);
+void run_mutex_circuit_test(void);
+void run_mbox_tests(void);
+void run_mbox_circuit_test(void);
+void run_semaphore_tests(void);
+void run_semaphore_circuit_test(void);
+void run_counter_tests(void);
+void run_flag_tests(void);
+void run_alarm_tests(void);
+
+#ifndef max
+#define max(n,m) (m > n ? n : m)
+#endif
+
+// Wait until a clock tick [real time clock] has passed. This should keep it
+// from happening again during a measurement, thus minimizing any fluctuations
+void
+wait_for_tick(void)
+{
+ cyg_tick_count_t tv0, tv1;
+ tv0 = cyg_current_time();
+ while (true) {
+ tv1 = cyg_current_time();
+ if (tv1 != tv0) break;
+ }
+}
+
+// Display a number of ticks as microseconds
+// Note: for improved calculation significance, values are kept in ticks*1000
+void
+show_ticks_in_us(cyg_uint32 ticks)
+{
+ long long ns;
+ ns = (ns_per_system_clock * (long long)ticks) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+ ns += 5; // for rounding to .01us
+ diag_printf("%5d.%02d", (int)(ns/1000), (int)((ns%1000)/10));
+}
+
+//
+// If the kernel is instrumented to measure clock interrupt latency, these
+// measurements can be drastically perturbed by printing via "diag_printf()"
+// since that code may run with interrupts disabled for long periods.
+//
+// In order to get accurate/reasonable latency figures _for the kernel
+// primitive functions beint tested_, the kernel's latency measurements
+// are suspended while the printing actually takes place.
+//
+// The measurements are reenabled after the printing, thus allowing for
+// fair measurements of the kernel primitives, which are not distorted
+// by the printing mechanisms.
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
+void
+disable_clock_latency_measurement(void)
+{
+ wait_for_tick();
+ measure_clock_latency = false;
+}
+
+void
+enable_clock_latency_measurement(void)
+{
+ wait_for_tick();
+ measure_clock_latency = true;
+}
+
+// Ensure that the measurements are reasonable (no startup anomalies)
+void
+reset_clock_latency_measurement(void)
+{
+ disable_clock_latency_measurement();
+ total_clock_latency = 0;
+ total_clock_interrupts = 0;
+ min_clock_latency = 0x7FFFFFFF;
+ max_clock_latency = 0;
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) && defined(HAL_CLOCK_LATENCY)
+ total_clock_dsr_latency = 0;
+ total_clock_dsr_calls = 0;
+ min_clock_dsr_latency = 0x7FFFFFFF;
+ max_clock_dsr_latency = 0;
+#endif
+ enable_clock_latency_measurement();
+
+}
+#else
+#define disable_clock_latency_measurement()
+#define enable_clock_latency_measurement()
+#define reset_clock_latency_measurement()
+#endif
+
+void
+show_times_hdr(void)
+{
+ disable_clock_latency_measurement();
+ diag_printf("\n");
+ diag_printf(" Confidence\n");
+ diag_printf(" Ave Min Max Var Ave Min Function\n");
+ diag_printf(" ====== ====== ====== ====== ========== ========\n");
+ enable_clock_latency_measurement();
+}
+
+void
+show_times_detail(fun_times ft[], int nsamples, char *title, bool ignore_first)
+{
+ int i, delta, min, max, con_ave, con_min, ave_dev;
+ int start_sample, total_samples;
+ cyg_int32 total, ave;
+
+ if (ignore_first) {
+ start_sample = 1;
+ total_samples = nsamples-1;
+ } else {
+ start_sample = 0;
+ total_samples = nsamples;
+ }
+ total = 0;
+ min = 0x7FFFFFFF;
+ max = 0;
+ for (i = start_sample; i < nsamples; i++) {
+ if (ft[i].end < ft[i].start) {
+ // Clock wrapped around (timer tick)
+ delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;
+ } else {
+ delta = ft[i].end - ft[i].start;
+ }
+ delta -= overhead;
+ if (delta < 0) delta = 0;
+ delta *= 1000;
+ total += delta;
+ if (delta < min) min = delta;
+ if (delta > max) max = delta;
+ }
+ ave = total / total_samples;
+ total = 0;
+ ave_dev = 0;
+ for (i = start_sample; i < nsamples; i++) {
+ if (ft[i].end < ft[i].start) {
+ // Clock wrapped around (timer tick)
+ delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;
+ } else {
+ delta = ft[i].end - ft[i].start;
+ }
+ delta -= overhead;
+ if (delta < 0) delta = 0;
+ delta *= 1000;
+ delta = delta - ave;
+ if (delta < 0) delta = -delta;
+ ave_dev += delta;
+ }
+ ave_dev /= total_samples;
+ con_ave = 0;
+ con_min = 0;
+ for (i = start_sample; i < nsamples; i++) {
+ if (ft[i].end < ft[i].start) {
+ // Clock wrapped around (timer tick)
+ delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;
+ } else {
+ delta = ft[i].end - ft[i].start;
+ }
+ delta -= overhead;
+ if (delta < 0) delta = 0;
+ delta *= 1000;
+ if ((delta <= (ave+ave_dev)) && (delta >= (ave-ave_dev))) con_ave++;
+ if ((delta <= (min+ave_dev)) && (delta >= (min-ave_dev))) con_min++;
+ }
+ con_ave = (con_ave * 100) / total_samples;
+ con_min = (con_min * 100) / total_samples;
+ show_ticks_in_us(ave);
+ show_ticks_in_us(min);
+ show_ticks_in_us(max);
+ show_ticks_in_us(ave_dev);
+ disable_clock_latency_measurement();
+ diag_printf(" %3d%% %3d%%", con_ave, con_min);
+ diag_printf(" %s\n", title);
+ enable_clock_latency_measurement();
+}
+
+void
+show_times(fun_times ft[], int nsamples, char *title)
+{
+ show_times_detail(ft, nsamples, title, false);
+#ifdef STATS_WITHOUT_FIRST_SAMPLE
+ show_times_detail(ft, nsamples, "", true);
+#endif
+}
+
+void
+show_test_parameters(void)
+{
+ disable_clock_latency_measurement();
+ diag_printf("\nTesting parameters:\n");
+ diag_printf(" Clock samples: %5d\n", nsamples);
+ diag_printf(" Threads: %5d\n", ntest_threads);
+ diag_printf(" Thread switches: %5d\n", nthread_switches);
+ diag_printf(" Mutexes: %5d\n", nmutexes);
+ diag_printf(" Mailboxes: %5d\n", nmboxes);
+ diag_printf(" Semaphores: %5d\n", nsemaphores);
+ diag_printf(" Scheduler operations: %5d\n", nscheds);
+ diag_printf(" Counters: %5d\n", ncounters);
+ diag_printf(" Flags: %5d\n", nflags);
+ diag_printf(" Alarms: %5d\n", nalarms);
+ diag_printf("\n");
+ enable_clock_latency_measurement();
+}
+
+void
+end_of_test_group(void)
+{
+ disable_clock_latency_measurement();
+ diag_printf("\n");
+ enable_clock_latency_measurement();
+}
+
+// Compute a name for a thread
+char *
+thread_name(char *basename, int indx) {
+ return "<<NULL>>"; // Not currently used
+}
+
+// test0 - null test, never executed
+void
+test0(cyg_uint32 indx)
+{
+#ifndef CYGPKG_KERNEL_SMP_SUPPORT
+ // In SMP, somw of these threads will execute
+ diag_printf("test0.%d executed?\n", indx);
+#endif
+ cyg_thread_exit();
+}
+
+// test1 - empty test, simply exit. Last thread signals parent.
+void
+test1(cyg_uint32 indx)
+{
+ if (indx == (cyg_uint32)(ntest_threads-1)) {
+ cyg_semaphore_post(&synchro); // Signal that last thread is dying
+ }
+ cyg_thread_exit();
+}
+
+// test2 - measure thread switch times
+void
+test2(cyg_uint32 indx)
+{
+ int i;
+ for (i = 0; i < nthread_switches; i++) {
+ if (indx == 0) {
+ HAL_CLOCK_READ(&test2_ft[i].start);
+ } else {
+ HAL_CLOCK_READ(&test2_ft[i].end);
+ }
+ cyg_thread_yield();
+ }
+ if (indx == 1) {
+ cyg_semaphore_post(&synchro);
+ }
+ cyg_thread_exit();
+}
+
+// Full-circuit mutex unlock/lock test
+void
+mutex_test(cyg_uint32 indx)
+{
+ int i;
+ cyg_mutex_lock(&test_mutexes[0]);
+ for (i = 0; i < nmutexes; i++) {
+ cyg_semaphore_wait(&synchro);
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ HAL_CLOCK_READ(&mutex_ft[i].start);
+ cyg_mutex_unlock(&test_mutexes[0]);
+ cyg_mutex_lock(&test_mutexes[0]);
+ cyg_semaphore_post(&synchro);
+ }
+ cyg_thread_exit();
+}
+
+// Full-circuit mbox put/get test
+void
+mbox_test(cyg_uint32 indx)
+{
+ void *item;
+ do {
+ item = cyg_mbox_get(test_mbox_handles[0]);
+ HAL_CLOCK_READ(&mbox_ft[(int)item].end);
+ cyg_semaphore_post(&synchro);
+ } while ((int)item != (nmboxes-1));
+ cyg_thread_exit();
+}
+
+// Full-circuit semaphore post/wait test
+void
+semaphore_test(cyg_uint32 indx)
+{
+ int i;
+ for (i = 0; i < nsemaphores; i++) {
+ cyg_semaphore_wait(&test_semaphores[0]);
+ HAL_CLOCK_READ(&semaphore_ft[i].end);
+ cyg_semaphore_post(&synchro);
+ }
+ cyg_thread_exit();
+}
+
+//
+// This set of tests is used to measure kernel primitives that deal with threads
+//
+void
+run_thread_tests(void)
+{
+ int i;
+ cyg_priority_t prio;
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_create(10, // Priority - just a number
+ test0, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Create thread");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_yield();
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Yield thread [all suspended]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_suspend(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Suspend [suspended] thread");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_resume(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Resume thread");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_set_priority(threads[i], 11);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Set priority");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ prio = cyg_thread_get_priority(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Get priority");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_kill(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Kill [suspended] thread");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_yield();
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Yield [no other] thread");
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+
+ // Recreate the test set
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test0, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ }
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_resume(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Resume [suspended low prio] thread");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_resume(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Resume [runnable low prio] thread");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_suspend(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Suspend [runnable] thread");
+
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_yield();
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Yield [only low prio] thread");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_suspend(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Suspend [runnable->not runnable]");
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_resume(threads[i]);
+ }
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_kill(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Kill [runnable] thread");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_delete(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Destroy [dead] thread");
+
+ // Recreate the test set
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test0, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume(threads[i]);
+ }
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_delete(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Destroy [runnable] thread");
+
+ // Set my priority lower than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 3);
+
+ // Set up the end-of-threads synchronizer
+ cyg_semaphore_init(&synchro, 0);
+
+ // Recreate the test set
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_create(2, // Priority - just a number
+ test1, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ }
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ntest_threads; i++) {
+ HAL_CLOCK_READ(&thread_ft[i].start);
+ cyg_thread_resume(threads[i]);
+ HAL_CLOCK_READ(&thread_ft[i].end);
+ }
+ show_times(thread_ft, ntest_threads, "Resume [high priority] thread");
+ cyg_semaphore_wait(&synchro); // Wait for all threads to finish
+ // Make sure they are all dead
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+
+ run_thread_switch_test();
+ end_of_test_group();
+}
+
+void
+run_thread_switch_test(void)
+{
+ int i;
+
+ // Set up for thread context switch
+ for (i = 0; i < 2; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test2, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume(threads[i]);
+ }
+ // Set up the end-of-threads synchronizer
+ cyg_semaphore_init(&synchro, 0);
+ cyg_semaphore_wait(&synchro);
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ show_times(test2_ft, nthread_switches, "Thread switch");
+ // Clean up
+ for (i = 0; i < 2; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+}
+
+void
+run_mutex_tests(void)
+{
+ int i;
+
+ // Mutex primitives
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmutexes; i++) {
+ HAL_CLOCK_READ(&mutex_ft[i].start);
+ cyg_mutex_init(&test_mutexes[i]);
+ HAL_CLOCK_READ(&mutex_ft[i].end);
+ }
+ show_times(mutex_ft, nmutexes, "Init mutex");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmutexes; i++) {
+ HAL_CLOCK_READ(&mutex_ft[i].start);
+ cyg_mutex_lock(&test_mutexes[i]);
+ HAL_CLOCK_READ(&mutex_ft[i].end);
+ }
+ show_times(mutex_ft, nmutexes, "Lock [unlocked] mutex");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmutexes; i++) {
+ HAL_CLOCK_READ(&mutex_ft[i].start);
+ cyg_mutex_unlock(&test_mutexes[i]);
+ HAL_CLOCK_READ(&mutex_ft[i].end);
+ }
+ show_times(mutex_ft, nmutexes, "Unlock [locked] mutex");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmutexes; i++) {
+ HAL_CLOCK_READ(&mutex_ft[i].start);
+ cyg_mutex_trylock(&test_mutexes[i]);
+ HAL_CLOCK_READ(&mutex_ft[i].end);
+ }
+ show_times(mutex_ft, nmutexes, "Trylock [unlocked] mutex");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmutexes; i++) {
+ HAL_CLOCK_READ(&mutex_ft[i].start);
+ cyg_mutex_trylock(&test_mutexes[i]);
+ HAL_CLOCK_READ(&mutex_ft[i].end);
+ }
+ show_times(mutex_ft, nmutexes, "Trylock [locked] mutex");
+
+ // Must unlock mutices before destroying them.
+ for (i = 0; i < nmutexes; i++) {
+ cyg_mutex_unlock(&test_mutexes[i]);
+ }
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmutexes; i++) {
+ HAL_CLOCK_READ(&mutex_ft[i].start);
+ cyg_mutex_destroy(&test_mutexes[i]);
+ HAL_CLOCK_READ(&mutex_ft[i].end);
+ }
+ show_times(mutex_ft, nmutexes, "Destroy mutex");
+ run_mutex_circuit_test();
+ end_of_test_group();
+}
+
+void
+run_mutex_circuit_test(void)
+{
+ int i;
+ // Set my priority lower than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 4);
+ // Set up for full mutex unlock/lock test
+ cyg_mutex_init(&test_mutexes[0]);
+ cyg_semaphore_init(&synchro, 0);
+ cyg_thread_create(3, // Priority - just a number
+ mutex_test, // entry
+ 0, // index
+ thread_name("thread", 0), // Name
+ &stacks[0][0], // Stack
+ STACK_SIZE, // Size
+ &mutex_test_thread_handle, // Handle
+ &mutex_test_thread // Thread data structure
+ );
+ cyg_thread_resume(mutex_test_thread_handle);
+ // Need to raise priority so that this thread will block on the "lock"
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+ for (i = 0; i < nmutexes; i++) {
+ cyg_semaphore_post(&synchro);
+ cyg_mutex_lock(&test_mutexes[0]);
+ HAL_CLOCK_READ(&mutex_ft[i].end);
+ cyg_mutex_unlock(&test_mutexes[0]);
+ cyg_semaphore_wait(&synchro);
+ }
+ cyg_thread_delete(mutex_test_thread_handle);
+ show_times(mutex_ft, nmutexes, "Unlock/Lock mutex");
+}
+
+void
+run_mbox_tests(void)
+{
+ int i, cnt;
+ void *item;
+ // Mailbox primitives
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cyg_mbox_create(&test_mbox_handles[i], &test_mboxes[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Create mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cnt = cyg_mbox_peek(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Peek [empty] mbox");
+
+#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cyg_mbox_put(test_mbox_handles[i], (void *)i);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Put [first] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cnt = cyg_mbox_peek(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Peek [1 msg] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cyg_mbox_put(test_mbox_handles[i], (void *)i);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Put [second] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cnt = cyg_mbox_peek(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Peek [2 msgs] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ item = cyg_mbox_get(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Get [first] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ item = cyg_mbox_get(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Get [second] mbox");
+#endif // ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cyg_mbox_tryput(test_mbox_handles[i], (void *)i);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Tryput [first] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ item = cyg_mbox_peek_item(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Peek item [non-empty] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ item = cyg_mbox_tryget(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Tryget [non-empty] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ item = cyg_mbox_peek_item(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Peek item [empty] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ item = cyg_mbox_tryget(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Tryget [empty] mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cyg_mbox_waiting_to_get(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Waiting to get mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cyg_mbox_waiting_to_put(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Waiting to put mbox");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nmboxes; i++) {
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cyg_mbox_delete(test_mbox_handles[i]);
+ HAL_CLOCK_READ(&mbox_ft[i].end);
+ }
+ show_times(mbox_ft, nmboxes, "Delete mbox");
+
+ run_mbox_circuit_test();
+ end_of_test_group();
+}
+
+void
+run_mbox_circuit_test(void)
+{
+#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+ int i;
+ // Set my priority lower than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 3);
+ // Set up for full mbox put/get test
+ cyg_mbox_create(&test_mbox_handles[0], &test_mboxes[0]);
+ cyg_semaphore_init(&synchro, 0);
+ cyg_thread_create(2, // Priority - just a number
+ mbox_test, // entry
+ 0, // index
+ thread_name("thread", 0), // Name
+ &stacks[0][0], // Stack
+ STACK_SIZE, // Size
+ &mbox_test_thread_handle, // Handle
+ &mbox_test_thread // Thread data structure
+ );
+ cyg_thread_resume(mbox_test_thread_handle);
+ for (i = 0; i < nmboxes; i++) {
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ HAL_CLOCK_READ(&mbox_ft[i].start);
+ cyg_mbox_put(test_mbox_handles[0], (void *)i);
+ cyg_semaphore_wait(&synchro);
+ }
+ cyg_thread_delete(mbox_test_thread_handle);
+ show_times(mbox_ft, nmboxes, "Put/Get mbox");
+#endif
+}
+
+void
+run_semaphore_tests(void)
+{
+ int i;
+ cyg_count32 sem_val;
+ // Semaphore primitives
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nsemaphores; i++) {
+ HAL_CLOCK_READ(&semaphore_ft[i].start);
+ cyg_semaphore_init(&test_semaphores[i], 0);
+ HAL_CLOCK_READ(&semaphore_ft[i].end);
+ }
+ show_times(semaphore_ft, nsemaphores, "Init semaphore");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nsemaphores; i++) {
+ HAL_CLOCK_READ(&semaphore_ft[i].start);
+ cyg_semaphore_post(&test_semaphores[i]);
+ HAL_CLOCK_READ(&semaphore_ft[i].end);
+ }
+ show_times(semaphore_ft, nsemaphores, "Post [0] semaphore");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nsemaphores; i++) {
+ HAL_CLOCK_READ(&semaphore_ft[i].start);
+ cyg_semaphore_wait(&test_semaphores[i]);
+ HAL_CLOCK_READ(&semaphore_ft[i].end);
+ }
+ show_times(semaphore_ft, nsemaphores, "Wait [1] semaphore");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nsemaphores; i++) {
+ HAL_CLOCK_READ(&semaphore_ft[i].start);
+ cyg_semaphore_trywait(&test_semaphores[i]);
+ HAL_CLOCK_READ(&semaphore_ft[i].end);
+ }
+ show_times(semaphore_ft, nsemaphores, "Trywait [0] semaphore");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nsemaphores; i++) {
+ cyg_semaphore_post(&test_semaphores[i]);
+ HAL_CLOCK_READ(&semaphore_ft[i].start);
+ cyg_semaphore_trywait(&test_semaphores[i]);
+ HAL_CLOCK_READ(&semaphore_ft[i].end);
+ }
+ show_times(semaphore_ft, nsemaphores, "Trywait [1] semaphore");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nsemaphores; i++) {
+ HAL_CLOCK_READ(&semaphore_ft[i].start);
+ cyg_semaphore_peek(&test_semaphores[i], &sem_val);
+ HAL_CLOCK_READ(&semaphore_ft[i].end);
+ }
+ show_times(semaphore_ft, nsemaphores, "Peek semaphore");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nsemaphores; i++) {
+ HAL_CLOCK_READ(&semaphore_ft[i].start);
+ cyg_semaphore_destroy(&test_semaphores[i]);
+ HAL_CLOCK_READ(&semaphore_ft[i].end);
+ }
+ show_times(semaphore_ft, nsemaphores, "Destroy semaphore");
+
+ run_semaphore_circuit_test();
+ end_of_test_group();
+}
+
+void
+run_semaphore_circuit_test(void)
+{
+ int i;
+ // Set my priority lower than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 3);
+ // Set up for full semaphore post/wait test
+ cyg_semaphore_init(&test_semaphores[0], 0);
+ cyg_semaphore_init(&synchro, 0);
+ cyg_thread_create(2, // Priority - just a number
+ semaphore_test, // entry
+ 0, // index
+ thread_name("thread", 0), // Name
+ &stacks[0][0], // Stack
+ STACK_SIZE, // Size
+ &semaphore_test_thread_handle, // Handle
+ &semaphore_test_thread // Thread data structure
+ );
+ cyg_thread_resume(semaphore_test_thread_handle);
+ for (i = 0; i < nsemaphores; i++) {
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ HAL_CLOCK_READ(&semaphore_ft[i].start);
+ cyg_semaphore_post(&test_semaphores[0]);
+ cyg_semaphore_wait(&synchro);
+ }
+ cyg_thread_delete(semaphore_test_thread_handle);
+ show_times(semaphore_ft, nsemaphores, "Post/Wait semaphore");
+}
+
+void
+run_counter_tests(void)
+{
+ int i;
+ cyg_tick_count_t val=0;
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ncounters; i++) {
+ HAL_CLOCK_READ(&counter_ft[i].start);
+ cyg_counter_create(&counters[i], &test_counters[i]);
+ HAL_CLOCK_READ(&counter_ft[i].end);
+ }
+ show_times(counter_ft, ncounters, "Create counter");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ncounters; i++) {
+ HAL_CLOCK_READ(&counter_ft[i].start);
+ val = cyg_counter_current_value(counters[i]);
+ HAL_CLOCK_READ(&counter_ft[i].end);
+ }
+ show_times(counter_ft, ncounters, "Get counter value");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ncounters; i++) {
+ HAL_CLOCK_READ(&counter_ft[i].start);
+ cyg_counter_set_value(counters[i], val);
+ HAL_CLOCK_READ(&counter_ft[i].end);
+ }
+ show_times(counter_ft, ncounters, "Set counter value");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ncounters; i++) {
+ HAL_CLOCK_READ(&counter_ft[i].start);
+ cyg_counter_tick(counters[i]);
+ HAL_CLOCK_READ(&counter_ft[i].end);
+ }
+ show_times(counter_ft, ncounters, "Tick counter");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ncounters; i++) {
+ HAL_CLOCK_READ(&counter_ft[i].start);
+ cyg_counter_delete(counters[i]);
+ HAL_CLOCK_READ(&counter_ft[i].end);
+ }
+ show_times(counter_ft, ncounters, "Delete counter");
+ end_of_test_group();
+}
+
+void
+run_flag_tests(void)
+{
+ int i;
+ cyg_flag_value_t val;
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nflags; i++) {
+ HAL_CLOCK_READ(&flag_ft[i].start);
+ cyg_flag_init(&test_flags[i]);
+ HAL_CLOCK_READ(&flag_ft[i].end);
+ }
+ show_times(flag_ft, nflags, "Init flag");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nflags; i++) {
+ HAL_CLOCK_READ(&flag_ft[i].start);
+ cyg_flag_destroy(&test_flags[i]);
+ HAL_CLOCK_READ(&flag_ft[i].end);
+ }
+ show_times(flag_ft, nflags, "Destroy flag");
+
+ // Recreate the flags - reused in the remaining tests
+ for (i = 0; i < nflags; i++) {
+ cyg_flag_init(&test_flags[i]);
+ }
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nflags; i++) {
+ HAL_CLOCK_READ(&flag_ft[i].start);
+ cyg_flag_maskbits(&test_flags[i], 0);
+ HAL_CLOCK_READ(&flag_ft[i].end);
+ }
+ show_times(flag_ft, nflags, "Mask bits in flag");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nflags; i++) {
+ HAL_CLOCK_READ(&flag_ft[i].start);
+ cyg_flag_setbits(&test_flags[i], 0x11);
+ HAL_CLOCK_READ(&flag_ft[i].end);
+ }
+ show_times(flag_ft, nflags, "Set bits in flag [no waiters]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nflags; i++) {
+ cyg_flag_setbits(&test_flags[i], 0x11);
+ HAL_CLOCK_READ(&flag_ft[i].start);
+ cyg_flag_wait(&test_flags[i], 0x11, CYG_FLAG_WAITMODE_AND);
+ HAL_CLOCK_READ(&flag_ft[i].end);
+ }
+ show_times(flag_ft, nflags, "Wait for flag [AND]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nflags; i++) {
+ cyg_flag_setbits(&test_flags[i], 0x11);
+ HAL_CLOCK_READ(&flag_ft[i].start);
+ cyg_flag_wait(&test_flags[i], 0x11, CYG_FLAG_WAITMODE_OR);
+ HAL_CLOCK_READ(&flag_ft[i].end);
+ }
+ show_times(flag_ft, nflags, "Wait for flag [OR]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nflags; i++) {
+ cyg_flag_setbits(&test_flags[i], 0x11);
+ HAL_CLOCK_READ(&flag_ft[i].start);
+ cyg_flag_wait(&test_flags[i], 0x11, CYG_FLAG_WAITMODE_AND|CYG_FLAG_WAITMODE_CLR);
+ HAL_CLOCK_READ(&flag_ft[i].end);
+ }
+ show_times(flag_ft, nflags, "Wait for flag [AND/CLR]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nflags; i++) {
+ cyg_flag_setbits(&test_flags[i], 0x11);
+ HAL_CLOCK_READ(&flag_ft[i].start);
+ cyg_flag_wait(&test_flags[i], 0x11, CYG_FLAG_WAITMODE_OR|CYG_FLAG_WAITMODE_CLR);
+ HAL_CLOCK_READ(&flag_ft[i].end);
+ }
+ show_times(flag_ft, nflags, "Wait for flag [OR/CLR]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nflags; i++) {
+ cyg_flag_setbits(&test_flags[i], 0x11);
+ HAL_CLOCK_READ(&flag_ft[i].start);
+ val = cyg_flag_peek(&test_flags[i]);
+ HAL_CLOCK_READ(&flag_ft[i].end);
+ }
+ show_times(flag_ft, nflags, "Peek on flag");
+
+ // Destroy flags - no longer needed
+ for (i = 0; i < nflags; i++) {
+ cyg_flag_destroy(&test_flags[i]);
+ }
+ end_of_test_group();
+}
+
+// Alarm callback function
+void
+alarm_cb(cyg_handle_t alarm, cyg_addrword_t val)
+{
+ // empty call back
+}
+
+// Callback used to test determinancy
+static volatile int alarm_cnt;
+void
+alarm_cb2(cyg_handle_t alarm, cyg_addrword_t indx)
+{
+ if (alarm_cnt == nscheds) return;
+ sched_ft[alarm_cnt].start = 0;
+ HAL_CLOCK_READ(&sched_ft[alarm_cnt++].end);
+ if (alarm_cnt == nscheds) {
+ cyg_semaphore_post(&synchro);
+ }
+}
+
+static void
+alarm_cb3(cyg_handle_t alarm, cyg_addrword_t indx)
+{
+ if (alarm_cnt == nscheds) {
+ cyg_semaphore_post(&synchro);
+ } else {
+ sched_ft[alarm_cnt].start = 0;
+ cyg_thread_resume((cyg_handle_t)indx);
+ }
+}
+
+// Null thread, used to keep scheduler busy
+void
+alarm_test(cyg_uint32 id)
+{
+ while (true) {
+ cyg_thread_yield();
+ }
+}
+
+// Thread that suspends itself at the first opportunity
+void
+alarm_test2(cyg_uint32 id)
+{
+ cyg_handle_t me = cyg_thread_self();
+ while (true) {
+ HAL_CLOCK_READ(&sched_ft[alarm_cnt++].end);
+ cyg_thread_suspend(me);
+ }
+}
+
+void
+run_alarm_tests(void)
+{
+ int i;
+ cyg_tick_count_t init_val, step_val;
+ cyg_handle_t rtc_handle;
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < ncounters; i++) {
+ cyg_counter_create(&counters[i], &test_counters[i]);
+ }
+ for (i = 0; i < nalarms; i++) {
+ HAL_CLOCK_READ(&alarm_ft[i].start);
+ cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]);
+ HAL_CLOCK_READ(&alarm_ft[i].end);
+ }
+ show_times(alarm_ft, nalarms, "Create alarm");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ init_val = 0; step_val = 0;
+ for (i = 0; i < nalarms; i++) {
+ HAL_CLOCK_READ(&alarm_ft[i].start);
+ cyg_alarm_initialize(alarms[i], init_val, step_val);
+ HAL_CLOCK_READ(&alarm_ft[i].end);
+ }
+ show_times(alarm_ft, nalarms, "Initialize alarm");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ init_val = 0; step_val = 0;
+ for (i = 0; i < nalarms; i++) {
+ HAL_CLOCK_READ(&alarm_ft[i].start);
+ cyg_alarm_disable(alarms[i]);
+ HAL_CLOCK_READ(&alarm_ft[i].end);
+ }
+ show_times(alarm_ft, nalarms, "Disable alarm");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ init_val = 0; step_val = 0;
+ for (i = 0; i < nalarms; i++) {
+ HAL_CLOCK_READ(&alarm_ft[i].start);
+ cyg_alarm_enable(alarms[i]);
+ HAL_CLOCK_READ(&alarm_ft[i].end);
+ }
+ show_times(alarm_ft, nalarms, "Enable alarm");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nalarms; i++) {
+ HAL_CLOCK_READ(&alarm_ft[i].start);
+ cyg_alarm_delete(alarms[i]);
+ HAL_CLOCK_READ(&alarm_ft[i].end);
+ }
+ show_times(alarm_ft, nalarms, "Delete alarm");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ cyg_counter_create(&counters[0], &test_counters[0]);
+ cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]);
+ init_val = 9999; step_val = 9999;
+ cyg_alarm_initialize(alarms[0], init_val, step_val);
+ cyg_alarm_enable(alarms[0]);
+ for (i = 0; i < ncounters; i++) {
+ HAL_CLOCK_READ(&counter_ft[i].start);
+ cyg_counter_tick(counters[0]);
+ HAL_CLOCK_READ(&counter_ft[i].end);
+ }
+ show_times(counter_ft, ncounters, "Tick counter [1 alarm]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ cyg_counter_create(&counters[0], &test_counters[0]);
+ for (i = 0; i < nalarms; i++) {
+ cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]);
+ init_val = 9999; step_val = 9999;
+ cyg_alarm_initialize(alarms[i], init_val, step_val);
+ cyg_alarm_enable(alarms[i]);
+ }
+ for (i = 0; i < ncounters; i++) {
+ HAL_CLOCK_READ(&counter_ft[i].start);
+ cyg_counter_tick(counters[0]);
+ HAL_CLOCK_READ(&counter_ft[i].end);
+ }
+ show_times(counter_ft, ncounters, "Tick counter [many alarms]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ cyg_counter_create(&counters[0], &test_counters[0]);
+ cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]);
+ init_val = 1; step_val = 1;
+ cyg_alarm_initialize(alarms[0], init_val, step_val);
+ cyg_alarm_enable(alarms[0]);
+ for (i = 0; i < ncounters; i++) {
+ HAL_CLOCK_READ(&counter_ft[i].start);
+ cyg_counter_tick(counters[0]);
+ HAL_CLOCK_READ(&counter_ft[i].end);
+ }
+ show_times(counter_ft, ncounters, "Tick & fire counter [1 alarm]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ cyg_counter_create(&counters[0], &test_counters[0]);
+ for (i = 0; i < nalarms; i++) {
+ cyg_alarm_create(counters[0], alarm_cb, i, &alarms[i], &test_alarms[i]);
+ init_val = 1; step_val = 1;
+ cyg_alarm_initialize(alarms[i], init_val, step_val);
+ cyg_alarm_enable(alarms[i]);
+ }
+ for (i = 0; i < nalarms; i++) {
+ HAL_CLOCK_READ(&alarm_ft[i].start);
+ cyg_counter_tick(counters[0]);
+ HAL_CLOCK_READ(&alarm_ft[i].end);
+ }
+ for (i = 0; i < nalarms; i++) {
+ cyg_alarm_delete(alarms[i]);
+ }
+ show_times(alarm_ft, nalarms, "Tick & fire counters [>1 together]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ cyg_counter_create(&counters[0], &test_counters[0]);
+ for (i = 0; i < nalarms; i++) {
+ cyg_alarm_create(counters[0], alarm_cb, i, &alarms[i], &test_alarms[i]);
+ init_val = i+1; step_val = nalarms+1;
+ cyg_alarm_initialize(alarms[i], init_val, step_val);
+ cyg_alarm_enable(alarms[i]);
+ }
+ for (i = 0; i < nalarms; i++) {
+ HAL_CLOCK_READ(&alarm_ft[i].start);
+ cyg_counter_tick(counters[0]);
+ HAL_CLOCK_READ(&alarm_ft[i].end);
+ }
+ for (i = 0; i < nalarms; i++) {
+ cyg_alarm_delete(alarms[i]);
+ }
+ show_times(alarm_ft, nalarms, "Tick & fire counters [>1 separately]");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle);
+ cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]);
+ init_val = 5; step_val = 5; alarm_cnt = 0;
+ cyg_alarm_initialize(alarms[0], init_val, step_val);
+ cyg_semaphore_init(&synchro, 0);
+ cyg_alarm_enable(alarms[0]);
+ cyg_semaphore_wait(&synchro);
+ cyg_alarm_disable(alarms[0]);
+ cyg_alarm_delete(alarms[0]);
+ show_times(sched_ft, nscheds, "Alarm latency [0 threads]");
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+ for (i = 0; i < 2; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ alarm_test, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume(threads[i]);
+ }
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle);
+ cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]);
+ init_val = 5; step_val = 5; alarm_cnt = 0;
+ cyg_alarm_initialize(alarms[0], init_val, step_val);
+ cyg_semaphore_init(&synchro, 0);
+ cyg_alarm_enable(alarms[0]);
+ cyg_semaphore_wait(&synchro);
+ cyg_alarm_disable(alarms[0]);
+ cyg_alarm_delete(alarms[0]);
+ show_times(sched_ft, nscheds, "Alarm latency [2 threads]");
+ for (i = 0; i < 2; i++) {
+ cyg_thread_suspend(threads[i]);
+ cyg_thread_delete(threads[i]);
+ }
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ alarm_test, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume(threads[i]);
+ }
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle);
+ cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]);
+ init_val = 5; step_val = 5; alarm_cnt = 0;
+ cyg_alarm_initialize(alarms[0], init_val, step_val);
+ cyg_semaphore_init(&synchro, 0);
+ cyg_alarm_enable(alarms[0]);
+ cyg_semaphore_wait(&synchro);
+ cyg_alarm_disable(alarms[0]);
+ cyg_alarm_delete(alarms[0]);
+ show_times(sched_ft, nscheds, "Alarm latency [many threads]");
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_suspend(threads[i]);
+ cyg_thread_delete(threads[i]);
+ }
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+ cyg_thread_create(10, // Priority - just a number
+ alarm_test2, // entry
+ i, // index
+ thread_name("thread", 0), // Name
+ &stacks[0][0], // Stack
+ STACK_SIZE, // Size
+ &threads[0], // Handle
+ &test_threads[0] // Thread data structure
+ );
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle);
+ cyg_alarm_create(rtc_handle, alarm_cb3, threads[0], &alarms[0],
+ &test_alarms[0]);
+ init_val = 5; step_val = 5; alarm_cnt = 0;
+ cyg_alarm_initialize(alarms[0], init_val, step_val);
+ cyg_semaphore_init(&synchro, 0);
+ cyg_alarm_enable(alarms[0]);
+ cyg_semaphore_wait(&synchro);
+ cyg_alarm_disable(alarms[0]);
+ cyg_alarm_delete(alarms[0]);
+ show_times(sched_ft, nscheds, "Alarm -> thread resume latency");
+ cyg_thread_suspend(threads[0]);
+ cyg_thread_delete(threads[0]);
+
+ end_of_test_group();
+}
+
+void
+run_sched_tests(void)
+{
+ int i;
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nscheds; i++) {
+ HAL_CLOCK_READ(&sched_ft[i].start);
+ cyg_scheduler_lock();
+ HAL_CLOCK_READ(&sched_ft[i].end);
+ cyg_scheduler_unlock();
+ }
+ show_times(sched_ft, nscheds, "Scheduler lock");
+
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nscheds; i++) {
+ cyg_scheduler_lock();
+ HAL_CLOCK_READ(&sched_ft[i].start);
+ cyg_scheduler_unlock();
+ HAL_CLOCK_READ(&sched_ft[i].end);
+ }
+ show_times(sched_ft, nscheds, "Scheduler unlock [0 threads]");
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+ for (i = 0; i < 1; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test0, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ }
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nscheds; i++) {
+ cyg_scheduler_lock();
+ HAL_CLOCK_READ(&sched_ft[i].start);
+ cyg_scheduler_unlock();
+ HAL_CLOCK_READ(&sched_ft[i].end);
+ }
+ show_times(sched_ft, nscheds, "Scheduler unlock [1 suspended]");
+ for (i = 0; i < 1; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test0, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ }
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nscheds; i++) {
+ cyg_scheduler_lock();
+ HAL_CLOCK_READ(&sched_ft[i].start);
+ cyg_scheduler_unlock();
+ HAL_CLOCK_READ(&sched_ft[i].end);
+ }
+ show_times(sched_ft, nscheds, "Scheduler unlock [many suspended]");
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+
+ // Set my priority higher than any I plan to create
+ cyg_thread_set_priority(cyg_thread_self(), 2);
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_create(10, // Priority - just a number
+ test0, // entry
+ i, // index
+ thread_name("thread", i), // Name
+ &stacks[i][0], // Stack
+ STACK_SIZE, // Size
+ &threads[i], // Handle
+ &test_threads[i] // Thread data structure
+ );
+ cyg_thread_resume(threads[i]);
+ }
+ wait_for_tick(); // Wait until the next clock tick to minimize aberations
+ for (i = 0; i < nscheds; i++) {
+ cyg_scheduler_lock();
+ HAL_CLOCK_READ(&sched_ft[i].start);
+ cyg_scheduler_unlock();
+ HAL_CLOCK_READ(&sched_ft[i].end);
+ }
+ show_times(sched_ft, nscheds, "Scheduler unlock [many low prio]");
+ for (i = 0; i < ntest_threads; i++) {
+ cyg_thread_delete(threads[i]);
+ }
+ end_of_test_group();
+}
+
+static void
+_run_all_tests(CYG_ADDRESS id)
+{
+ int i, j;
+ cyg_uint32 tv[nsamples], tv0, tv1;
+ cyg_uint32 min_stack, max_stack, total_stack, actual_stack;
+ cyg_tick_count_t ticks, tick0, tick1;
+#ifdef CYG_SCHEDULER_LOCK_TIMINGS
+ cyg_uint32 lock_ave, lock_max;
+#endif
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
+ cyg_int32 clock_ave;
+#endif
+
+ disable_clock_latency_measurement();
+
+#ifndef CYGPKG_KERNEL_SMP_SUPPORT
+ cyg_test_dump_thread_stack_stats( "Startup, main stack", thread[0] );
+ cyg_test_dump_interrupt_stack_stats( "Startup" );
+ cyg_test_dump_idlethread_stack_stats( "Startup" );
+ cyg_test_clear_interrupt_stack();
+#endif
+
+ diag_printf("\neCos Kernel Timings\n");
+ diag_printf("Notes: all times are in microseconds (.000001) unless otherwise stated\n");
+#ifdef STATS_WITHOUT_FIRST_SAMPLE
+ diag_printf(" second line of results have first sample removed\n");
+#endif
+
+ cyg_thread_delay(2); // Make sure the clock is actually running
+
+ ns_per_system_clock = 1000000/rtc_resolution[1];
+
+ wait_for_tick();
+ for (i = 0; i < nsamples; i++) {
+ HAL_CLOCK_READ(&tv[i]);
+ }
+ tv0 = 0;
+ for (i = 1; i < nsamples; i++) {
+ tv0 += tv[i] - tv[i-1];
+ }
+ end_of_test_group();
+
+ overhead = tv0 / (nsamples-1);
+ diag_printf("Reading the hardware clock takes %d 'ticks' overhead\n", overhead);
+ diag_printf("... this value will be factored out of all other measurements\n");
+
+ // Try and measure how long the clock interrupt handling takes
+ for (i = 0; i < nsamples; i++) {
+ tick0 = cyg_current_time();
+ while (true) {
+ tick1 = cyg_current_time();
+ if (tick0 != tick1) break;
+ }
+ HAL_CLOCK_READ(&tv[i]);
+ }
+ tv1 = 0;
+ for (i = 0; i < nsamples; i++) {
+ tv1 += tv[i] * 1000;
+ }
+ tv1 = tv1 / nsamples;
+ tv1 -= overhead; // Adjust out the cost of getting the timer value
+ diag_printf("Clock interrupt took");
+ show_ticks_in_us(tv1);
+ diag_printf(" microseconds (%d raw clock ticks)\n", tv1/1000);
+ enable_clock_latency_measurement();
+
+ ticks = cyg_current_time();
+
+ show_test_parameters();
+ show_times_hdr();
+
+ reset_clock_latency_measurement();
+
+ run_thread_tests();
+ run_sched_tests();
+ run_mutex_tests();
+ run_mbox_tests();
+ run_semaphore_tests();
+ run_counter_tests();
+ run_flag_tests();
+ run_alarm_tests();
+
+#ifdef CYG_SCHEDULER_LOCK_TIMINGS
+ Cyg_Scheduler::get_lock_times(&lock_ave, &lock_max);
+ diag_printf("\nMax lock:");
+ show_ticks_in_us(lock_max);
+ diag_printf(", Ave lock:");
+ show_ticks_in_us(lock_ave);
+ diag_printf("\n");
+#endif
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
+ // Display latency figures in same format as all other numbers
+ disable_clock_latency_measurement();
+ clock_ave = (total_clock_latency*1000) / total_clock_interrupts;
+ show_ticks_in_us(clock_ave);
+ show_ticks_in_us(min_clock_latency*1000);
+ show_ticks_in_us(max_clock_latency*1000);
+ show_ticks_in_us(0);
+ diag_printf(" Clock/interrupt latency\n\n");
+ enable_clock_latency_measurement();
+#endif
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) && defined(HAL_CLOCK_LATENCY)
+ disable_clock_latency_measurement();
+ clock_ave = (total_clock_dsr_latency*1000) / total_clock_dsr_calls;
+ show_ticks_in_us(clock_ave);
+ show_ticks_in_us(min_clock_dsr_latency*1000);
+ show_ticks_in_us(max_clock_dsr_latency*1000);
+ show_ticks_in_us(0);
+ diag_printf(" Clock DSR latency\n\n");
+ enable_clock_latency_measurement();
+#endif
+
+#ifndef CYGPKG_KERNEL_SMP_SUPPORT
+ disable_clock_latency_measurement();
+ min_stack = STACK_SIZE;
+ max_stack = 0;
+ total_stack = 0;
+ for (i = 0; i < (int)NTEST_THREADS; i++) {
+ for (j = 0; j < STACK_SIZE; j++) {
+ if (stacks[i][j]) break;
+ }
+ actual_stack = STACK_SIZE-j;
+ if (actual_stack < min_stack) min_stack = actual_stack;
+ if (actual_stack > max_stack) max_stack = actual_stack;
+ total_stack += actual_stack;
+ }
+ for (j = 0; j < STACKSIZE; j++) {
+ if (((char *)stack[0])[j]) break;
+ }
+ diag_printf("%5ld %5d %5d (main stack: %5d) Thread stack used (%d total)\n",
+ (unsigned long) total_stack/NTEST_THREADS, min_stack, max_stack,
+ STACKSIZE - j, STACK_SIZE);
+
+ cyg_test_dump_thread_stack_stats( "All done, main stack", thread[0] );
+ cyg_test_dump_interrupt_stack_stats( "All done" );
+ cyg_test_dump_idlethread_stack_stats( "All done" );
+#endif
+
+ enable_clock_latency_measurement();
+
+ ticks = cyg_current_time();
+ diag_printf("\nTiming complete - %d ms total\n\n", (int)((ticks*ns_per_system_clock)/1000));
+}
+
+void
+run_all_tests(CYG_ADDRESS id)
+{
+#if CYGNUM_TESTS_RUN_COUNT < 0
+ while (1)
+#else
+ int i;
+ for (i = 0; i < CYGNUM_TESTS_RUN_COUNT; i++)
+#endif
+ _run_all_tests(id);
+ CYG_TEST_PASS_FINISH("Basic timing OK");
+}
+
+void tm_basic_main( void )
+{
+ CYG_TEST_INIT();
+
+ if (cyg_test_is_simulator) {
+ nsamples = NSAMPLES_SIM;
+ ntest_threads = NTEST_THREADS_SIM;
+ nthread_switches = NTHREAD_SWITCHES_SIM;
+ nmutexes = NMUTEXES_SIM;
+ nmboxes = NMBOXES_SIM;
+ nsemaphores = NSEMAPHORES_SIM;
+ nscheds = NSCHEDS_SIM;
+ nflags = NFLAGS_SIM;
+ ncounters = NCOUNTERS_SIM;
+ nalarms = NALARMS_SIM;
+ } else {
+ nsamples = NSAMPLES;
+ ntest_threads = NTEST_THREADS;
+ nthread_switches = NTHREAD_SWITCHES;
+ nmutexes = NMUTEXES;
+ nmboxes = NMBOXES;
+ nsemaphores = NSEMAPHORES;
+ nscheds = NSCHEDS;
+ nflags = NFLAGS;
+ ncounters = NCOUNTERS;
+ nalarms = NALARMS;
+ }
+
+ // Sanity
+#ifdef WORKHORSE_TEST
+ ntest_threads = max(512, ntest_threads);
+ nmutexes = max(1024, nmutexes);
+ nsemaphores = max(1024, nsemaphores);
+ nmboxes = max(1024, nmboxes);
+ ncounters = max(1024, ncounters);
+ nalarms = max(1024, nalarms);
+#else
+ ntest_threads = max(64, ntest_threads);
+ nmutexes = max(32, nmutexes);
+ nsemaphores = max(32, nsemaphores);
+ nmboxes = max(32, nmboxes);
+ ncounters = max(32, ncounters);
+ nflags = max(32, nflags);
+ nalarms = max(32, nalarms);
+#endif
+
+ new_thread(run_all_tests, 0);
+
+ Cyg_Scheduler::scheduler.start();
+
+}
+
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+externC void
+cyg_hal_invoke_constructors();
+#endif
+
+externC void
+cyg_start( void )
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ cyg_hal_invoke_constructors();
+#endif
+ tm_basic_main();
+}
+
+#else // CYGFUN_KERNEL_API_C
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_INFO("Timing tests require:\n"
+ "CYGFUN_KERNEL_API_C && \n"
+ "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n"
+ "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n"
+ "!CYGDBG_INFRA_DIAG_USE_DEVICE &&\n"
+ "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n");
+ CYG_TEST_NA("Timing tests requirements");
+}
+#endif // CYGFUN_KERNEL_API_C, etc.
+
+// EOF tm_basic.cxx