summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--testsuites/sptests/ChangeLog12
-rw-r--r--testsuites/sptests/Makefile.am2
-rw-r--r--testsuites/sptests/configure.ac2
-rw-r--r--testsuites/sptests/sp34/.cvsignore2
-rw-r--r--testsuites/sptests/sp34/Makefile.am24
-rw-r--r--testsuites/sptests/sp34/changepri.c165
-rw-r--r--testsuites/sptests/sp34/sp34.doc0
-rw-r--r--testsuites/sptests/sp34/sp34.scn26
-rw-r--r--testsuites/sptests/sp35/.cvsignore2
-rw-r--r--testsuites/sptests/sp35/Makefile.am24
-rw-r--r--testsuites/sptests/sp35/priinv.c488
-rw-r--r--testsuites/sptests/sp35/sp35.doc0
-rw-r--r--testsuites/sptests/sp35/sp35.scn59
13 files changed, 805 insertions, 1 deletions
diff --git a/testsuites/sptests/ChangeLog b/testsuites/sptests/ChangeLog
index f81389bc17..bc9629e4db 100644
--- a/testsuites/sptests/ChangeLog
+++ b/testsuites/sptests/ChangeLog
@@ -1,5 +1,17 @@
2007-03-05 Joel Sherrill <joel@OARcorp.com>
+ PR 1222/cpukit
+ * Makefile.am, configure.ac: Enhance so that when the prioirity of a
+ thread that is blocked on a priority based thread queue is changed,
+ that its placement in the queue is reevaluated based upon the new
+ priority. This enhancement includes modifications to the SuperCore as
+ well as new test cases.
+ * sp34/.cvsignore, sp34/Makefile.am, sp34/changepri.c, sp34/sp34.doc,
+ sp34/sp34.scn, sp35/.cvsignore, sp35/Makefile.am, sp35/priinv.c,
+ sp35/sp35.doc, sp35/sp35.scn: New files.
+
+2007-03-05 Joel Sherrill <joel@OARcorp.com>
+
* sp26/system.h: Correct memory required for stack sizes.
2007-02-06 Joel Sherrill <joel@OARcorp.com>
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index ae7bf234d2..610003c0da 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -7,7 +7,7 @@ ACLOCAL_AMFLAGS = -I ../aclocal
## spfatal is not included for now
SUBDIRS = sp01 sp02 sp03 sp04 sp05 sp06 sp07 sp08 sp09 sp11 sp12 sp13 sp14 \
sp15 sp16 sp17 sp19 sp20 sp21 sp22 sp23 sp24 sp25 sp26 sp27 sp28 sp29 \
- sp30 sp31 sp32 sp33 spsize
+ sp30 sp31 sp32 sp33 sp34 sp35 spsize
DIST_SUBDIRS = $(SUBDIRS) spfatal
include $(top_srcdir)/../automake/subdirs.am
diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac
index 73062b7edc..61f7270707 100644
--- a/testsuites/sptests/configure.ac
+++ b/testsuites/sptests/configure.ac
@@ -58,6 +58,8 @@ sp30/Makefile
sp31/Makefile
sp32/Makefile
sp33/Makefile
+sp34/Makefile
+sp35/Makefile
spsize/Makefile
spfatal/Makefile
])
diff --git a/testsuites/sptests/sp34/.cvsignore b/testsuites/sptests/sp34/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/testsuites/sptests/sp34/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/testsuites/sptests/sp34/Makefile.am b/testsuites/sptests/sp34/Makefile.am
new file mode 100644
index 0000000000..c7890cc017
--- /dev/null
+++ b/testsuites/sptests/sp34/Makefile.am
@@ -0,0 +1,24 @@
+##
+## $Id$
+##
+
+rtems_tests_PROGRAMS = sp34.exe
+sp34_exe_SOURCES = changepri.c
+
+dist_rtems_tests_DATA = sp34.scn
+dist_rtems_tests_DATA += sp34.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(sp34_exe_OBJECTS) $(sp34_exe_LDADD)
+LINK_LIBS = $(sp34_exe_LDLIBS)
+
+sp34.exe$(EXEEXT): $(sp34_exe_OBJECTS) $(sp34_exe_DEPENDENCIES)
+ @rm -f sp34.exe$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/sp34/changepri.c b/testsuites/sptests/sp34/changepri.c
new file mode 100644
index 0000000000..5ec0432553
--- /dev/null
+++ b/testsuites/sptests/sp34/changepri.c
@@ -0,0 +1,165 @@
+/*
+ * Test program to demonstrate reordering of threads on thread queues
+ * when their priority changes.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <stdio.h>
+
+/********************************************************************/
+/* define this to use the RTEMS 4.5 scheme for object names */
+#define TEST_ON_RTEMS_45
+
+/* define this to print the Id of the calling task */
+/* #define TEST_ON_TASK_ID */
+
+/********************************************************************/
+
+#include <bsp.h>
+#include <stdio.h>
+#include "tmacros.h"
+
+rtems_task BlockingTasks(rtems_task_argument arg);
+
+/*
+ * CallerName -- print the calling tasks name or id as configured
+ */
+const char *CallerName()
+{
+ static char buffer[32];
+#if defined(TEST_PRINT_TASK_ID)
+ sprintf( buffer, "0x%08x -- %d",
+ _Thread_Executing->Object.id, _Thread_Executing->current_priority );
+#else
+ union {
+ uint32_t u;
+ unsigned char c[4];
+ } TempName;
+
+ #if defined(TEST_ON_RTEMS_45)
+ TempName.u = *(uint32_t *)_Thread_Executing->Object.name;
+ #else
+ TempName.u = _Thread_Executing->Object.name;
+ #endif
+ sprintf( buffer, "%c%c%c%c -- %d",
+ TempName.c[0], TempName.c[1], TempName.c[2], TempName.c[3],
+ _Thread_Executing->current_priority
+ );
+#endif
+ return buffer;
+}
+
+#define NUMBER_OF_BLOCKING_TASKS 5
+
+/* RTEMS ids of blocking threads */
+rtems_id Blockers[NUMBER_OF_BLOCKING_TASKS];
+
+/* Semaphore they are all blocked on */
+rtems_id Semaphore;
+
+rtems_task BlockingTasks(rtems_task_argument arg)
+{
+ rtems_status_code status;
+ rtems_task_priority opri;
+ rtems_task_priority npri;
+
+ status = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &opri);
+ directive_failed( status, "rtems_task_set_priority" );
+
+ printf("semaphore_obtain -- BlockingTask %d @ pri=%d) blocks\n", arg, opri);
+ status = rtems_semaphore_obtain(Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ directive_failed( status, "rtems_semaphore_obtain" );
+
+ /* priority should have changed while blocked */
+ status = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &npri);
+ directive_failed( status, "rtems_task_set_priority" );
+
+ printf("semaphore_obtain -- BlockingTask %d @ pri=%d) returns\n", arg, npri);
+
+ (void) rtems_task_delete( RTEMS_SELF );
+}
+
+/*************************************************************************/
+/********************** INITIALIZATION *********************/
+/*************************************************************************/
+
+rtems_task Init(rtems_task_argument ignored)
+{
+ rtems_status_code status;
+ int i;
+
+ puts( "\n\n*** TEST 34 ***" );
+
+ /* Create synchronisation semaphore for LocalHwIsr -> Test Tasks */
+ status = rtems_semaphore_create(
+ rtems_build_name ('S', 'E', 'M', '1'), /* name */
+ 0, /* initial count = 0 */
+ RTEMS_LOCAL |
+ RTEMS_COUNTING_SEMAPHORE |
+ RTEMS_PRIORITY,
+ 0,
+ &Semaphore); /* *id */
+ directive_failed( status, "rtems_semaphore_create" );
+
+ /* Create and start all tasks in the test */
+
+ for (i = 0; i < NUMBER_OF_BLOCKING_TASKS; i++) {
+ status = rtems_task_create(
+ rtems_build_name('B','L','K','0'+i), /* Name */
+ 2+i, /* Priority */
+ RTEMS_MINIMUM_STACK_SIZE*2, /* Stack size (8KB) */
+ RTEMS_DEFAULT_MODES | RTEMS_NO_ASR, /* Mode */
+ RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, /* Attributes */
+ &Blockers[i]); /* Assigned ID */
+ directive_failed( status, "rtems_task_create (BLKn)" );
+
+ printf( "Blockers[%d] Id = 0x%08x\n", i, Blockers[i] );
+ status = rtems_task_start(Blockers[i], BlockingTasks, i);
+ directive_failed( status, "rtems_task_start (BLKn)" );
+ }
+
+ status = rtems_task_wake_after( 100 );
+ directive_failed( status, "rtems_task_wake_after" );
+
+ puts( "rtems_task_set_priority -- invert priorities of tasks" );
+ for (i = 0; i < NUMBER_OF_BLOCKING_TASKS; i++) {
+ rtems_task_priority opri;
+ rtems_task_priority npri= 2 + NUMBER_OF_BLOCKING_TASKS - i - 1;
+
+ status = rtems_task_set_priority(Blockers[i], npri, &opri);
+ directive_failed( status, "rtems_task_set_priority" );
+ }
+
+ for (i = 0; i < NUMBER_OF_BLOCKING_TASKS; i++) {
+ puts( "rtems_semaphore_release -- OK" );
+ status = rtems_semaphore_release(Semaphore);
+ directive_failed( status, "rtems_semaphore_release" );
+
+ status = rtems_task_wake_after( 100 );
+ directive_failed( status, "rtems_task_wake_after" );
+ }
+
+ /* exit the test */
+ puts( "*** END OF TEST 34 ***" );
+ exit(0);
+}
+
+/* configuration information */
+
+#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_MEMORY_OVERHEAD 64
+
+#define CONFIGURE_MAXIMUM_TASKS 6
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/* end of file */
diff --git a/testsuites/sptests/sp34/sp34.doc b/testsuites/sptests/sp34/sp34.doc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testsuites/sptests/sp34/sp34.doc
diff --git a/testsuites/sptests/sp34/sp34.scn b/testsuites/sptests/sp34/sp34.scn
new file mode 100644
index 0000000000..770d5788ce
--- /dev/null
+++ b/testsuites/sptests/sp34/sp34.scn
@@ -0,0 +1,26 @@
+Exception handling initialization done
+
+
+*** TEST 34 ***
+Blockers[0] Id = 0x0a010002
+Blockers[1] Id = 0x0a010003
+Blockers[2] Id = 0x0a010004
+Blockers[3] Id = 0x0a010005
+Blockers[4] Id = 0x0a010006
+semaphore_obtain -- BlockingTask 0 @ pri=2) blocks
+semaphore_obtain -- BlockingTask 1 @ pri=3) blocks
+semaphore_obtain -- BlockingTask 2 @ pri=4) blocks
+semaphore_obtain -- BlockingTask 3 @ pri=5) blocks
+semaphore_obtain -- BlockingTask 4 @ pri=6) blocks
+rtems_task_set_priority -- invert priorities of tasks
+rtems_semaphore_release -- OK
+semaphore_obtain -- BlockingTask 4 @ pri=2) returns
+rtems_semaphore_release -- OK
+semaphore_obtain -- BlockingTask 3 @ pri=3) returns
+rtems_semaphore_release -- OK
+semaphore_obtain -- BlockingTask 2 @ pri=4) returns
+rtems_semaphore_release -- OK
+semaphore_obtain -- BlockingTask 1 @ pri=5) returns
+rtems_semaphore_release -- OK
+semaphore_obtain -- BlockingTask 0 @ pri=6) returns
+*** END OF TEST 34 ***
diff --git a/testsuites/sptests/sp35/.cvsignore b/testsuites/sptests/sp35/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/testsuites/sptests/sp35/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/testsuites/sptests/sp35/Makefile.am b/testsuites/sptests/sp35/Makefile.am
new file mode 100644
index 0000000000..2d5b263509
--- /dev/null
+++ b/testsuites/sptests/sp35/Makefile.am
@@ -0,0 +1,24 @@
+##
+## $Id$
+##
+
+rtems_tests_PROGRAMS = sp35.exe
+sp35_exe_SOURCES = priinv.c
+
+dist_rtems_tests_DATA = sp35.scn
+dist_rtems_tests_DATA += sp35.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(sp35_exe_OBJECTS) $(sp35_exe_LDADD)
+LINK_LIBS = $(sp35_exe_LDLIBS)
+
+sp35.exe$(EXEEXT): $(sp35_exe_OBJECTS) $(sp35_exe_DEPENDENCIES)
+ @rm -f sp35.exe$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/sp35/priinv.c b/testsuites/sptests/sp35/priinv.c
new file mode 100644
index 0000000000..8f3263fd97
--- /dev/null
+++ b/testsuites/sptests/sp35/priinv.c
@@ -0,0 +1,488 @@
+/*
+ * Simple test program to demonstrate priority inversion when blocking
+ *
+ -Ulf Ivraeus ------------- --- -- - - -
+ * Saab Ericsson Space AB
+ * phone: +46 (0)31 735 4542
+ * e-mail: ulf.ivraeus@space.se
+ * ----------------------------- --- -- - - -
+ *
+ * $Id$
+ */
+
+/********************************************************************
+
+ Semaphore Ids:
+ Sync Mutex Id = 0x18010009
+ Local Mutex Id = 0x1801000a
+ Remote Mutex Id = 0x1801000b
+
+ Task Ids:
+ TaMedium[0] Id = 0x08010002
+ TaMedium[1] Id = 0x08010003
+ TaMedium[2] Id = 0x08010004
+ TaHigh Id = 0x08010005
+ TaLow Id = 0x08010006
+ TaHwSim Id = 0x08010007
+
+********************************************************************/
+
+/********************************************************************/
+/* define this to use the RTEMS 4.5 scheme for object names */
+/* #define TEST_ON_RTEMS_45 */
+
+/* define this to print the Id of the calling task */
+/* #define TEST_ON_TASK_ID */
+
+/* define this to print statistics when acquiring the mutex */
+/* #define TEST_PRINT_STATISTICS */
+
+/* define this if you are (1) on a ERC32 and (2) want a SW ISR trigger */
+#if defined(__sparc__)
+/* #define TEST_USE_ISR */
+#endif
+
+/* define this if you want the test to exit */
+#define TEST_EXIT_AFTER_ITERATIONS 10
+/********************************************************************/
+
+#include <bsp.h>
+#include <stdio.h>
+#include "tmacros.h"
+
+#if defined(TEST_EXIT_AFTER_ITERATIONS)
+volatile uint32_t Iterations = 0;
+#endif
+
+/* Task entry point prototypes */
+rtems_task Medium_Exec(rtems_task_argument TaskArg);
+rtems_task Low_Exec(rtems_task_argument TaskArg);
+rtems_task High_Exec(rtems_task_argument TaskArg);
+rtems_task LocalHwSim_Exec(rtems_task_argument TaskArg);
+
+/* ISR that signals that HW has completed */
+rtems_isr LocalHwIsr(/*in*/ rtems_vector_number Vector);
+
+/* Test driver functions */
+void AccessLocalHw(void);
+void AccessRemoteHw(void);
+
+const char *CallerName()
+{
+ static char buffer[32];
+#if defined(TEST_PRINT_TASK_ID)
+ sprintf( buffer, "0x%08x -- %d",
+ _Thread_Executing->Object.id, _Thread_Executing->current_priority );
+#else
+ union {
+ uint32_t u;
+ unsigned char c[4];
+ } TempName;
+
+ #if defined(TEST_ON_RTEMS_45)
+ TempName.u = *(uint32_t *)_Thread_Executing->Object.name;
+ #else
+ TempName.u = _Thread_Executing->Object.name;
+ #endif
+ sprintf( buffer, "%c%c%c%c -- %d",
+ TempName.c[0], TempName.c[1], TempName.c[2], TempName.c[3],
+ _Thread_Executing->current_priority
+ );
+#endif
+ return buffer;
+}
+
+#define NofMediumTask_C 3
+
+/* RTEMS identifiers */
+rtems_id TaMedium[NofMediumTask_C]; /* Medium-prio tasks accessing */
+ /* the common local HW */
+rtems_id TaHwSim; /* HW simulator */
+rtems_id TaLow; /* Low-prio task accessing common */
+ /* remote HW */
+rtems_id TaHigh; /* High-prio task accessing common */
+ /* remote HW */
+
+
+rtems_id LocalHwSync_S; /* Syncrhonize task to local HW */
+rtems_id LocalHwAccess_R; /* Execlusive access to the local HW */
+rtems_id RemoteHwAccess_R; /* Execlusive access to the remote HW */
+
+
+/* The following variable triggers simulated HW activity */
+volatile boolean StartHw = FALSE;
+
+rtems_task Medium_Exec(rtems_task_argument TaskArg)
+{
+ printf("Medium_Exec (%d) begins...\n", TaskArg);
+
+ rtems_task_wake_after(50);
+
+ while(1) {
+ AccessLocalHw();
+ }
+
+ /* JRS - task does not get here */
+
+ printf("Medium_Exec (%d) ends...\n", TaskArg);
+ while(1) {
+ rtems_task_wake_after(10000);
+ }
+}
+
+rtems_task High_Exec(rtems_task_argument TaskArg)
+{
+ printf("High_Exec (%d) begins...\n", TaskArg);
+
+ /* Delay more than the Low-prio task so that Remote HW access resource is
+ * taken before call to AccesRemoteHw.
+ */
+ rtems_task_wake_after(250);
+
+ while(1) {
+ AccessRemoteHw();
+ }
+
+ /* JRS - task does not get here */
+
+ printf("High_Exec (%d) ends...\n", TaskArg);
+ while(1) {
+ rtems_task_wake_after(10000);
+ }
+ /* task does not get here */
+}
+
+rtems_task Low_Exec(rtems_task_argument TaskArg)
+{
+ printf("Low_Exec (%d) begins...\n", TaskArg);
+
+ /* Delay less than High-prio task so that we take the remote HW access
+ * resource before it does it. However, delay longer than the mid-prio
+ * tasks so that we know for certain that they have taken control over
+ * the local HW access.
+ */
+ rtems_task_wake_after(100);
+
+ while(1) {
+ AccessRemoteHw();
+ }
+
+ /* JRS - task does not get here */
+
+ printf("Low_Exec (%d) ends...\n", TaskArg);
+ while(1) {
+ rtems_task_wake_after(10000);
+ }
+}
+
+
+rtems_task LocalHwSim_Exec(rtems_task_argument TaskArg)
+{
+ int ISRCount = 0;
+ printf("LocalHwSim_Exec begins...\n");
+
+ while(1) {
+ if (StartHw) {
+ /* A test task has activated the HW, wait for a while and then
+ * generate an interrupt
+ */
+ rtems_task_wake_after(100);
+
+ StartHw = FALSE;
+#if 0
+ fprintf( stderr, "StartHw -- fire ISR (%d)\n", ++ISRCount );
+#endif
+#if defined(TEST_USE_ISR)
+ __asm__ volatile ("ta 5");
+ __asm__ volatile ("nop");
+ __asm__ volatile ("nop");
+#else
+ LocalHwIsr( 0x85 );
+#endif
+ }
+
+ }
+
+ printf("LocalHwSim_Exec ends...\n");
+ while(1) {
+ rtems_task_wake_after(10000);
+ }
+}
+
+
+rtems_isr LocalHwIsr(/*in*/ rtems_vector_number Vector)
+{
+ rtems_status_code status;
+
+ /* Signal synchroniztion semaphore to invoke waiting task */
+ status = rtems_semaphore_release(LocalHwSync_S);
+ if (status != RTEMS_SUCCESSFUL) {
+ fprintf( stderr, "LocalHwISR release %d\n", status );
+ while(1); /* Error */
+ }
+
+ return;
+}
+
+void AccessLocalHw(void)
+{
+ rtems_status_code Sts;
+
+ rtems_task_priority EnterPrio; /* Statistics log */
+ rtems_task_priority AccessPrio; /* : */
+ rtems_task_priority LeavePrio; /* : */
+ uint32_t EnterCnt; /* : */
+ uint32_t AccessCnt; /* : */
+ uint32_t LeaveCnt; /* : */
+
+ /* Store information about the current situation */
+ EnterPrio = _Thread_Executing->current_priority;
+ EnterCnt = _Thread_Executing->resource_count;
+
+
+ printf(" AccessLocalHw called by %s\n", CallerName());
+
+ /* Obtain exclusive access to local HW, Start HW, Wait for completion,
+ * Release access
+ */
+
+ Sts = rtems_semaphore_obtain(LocalHwAccess_R, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ directive_failed( Sts, "rtems_semaphore_obtain(LocalHwAccess_R...)" );
+
+ StartHw = TRUE;
+
+ Sts = rtems_semaphore_obtain(LocalHwSync_S, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ directive_failed( Sts, "rtems_semaphore_obtain(LocalHwAccess_R...)" );
+
+ /* Store information about the current situation */
+ AccessPrio = _Thread_Executing->current_priority;
+ AccessCnt = _Thread_Executing->resource_count;
+
+ Sts = rtems_semaphore_release(LocalHwAccess_R);
+ directive_failed( Sts, "rtems_semaphore_release(LocalHwAccess_R)" );
+
+ /* Store information about the current situation */
+ LeavePrio = _Thread_Executing->current_priority;
+ LeaveCnt = _Thread_Executing->resource_count;
+
+#if defined(TEST_PRINT_STATISTICS)
+ printf(
+ " AccessLocalHw from %s statistics:\n"
+ " - Prio: %d -> %d -> %d\n - Cnt: %d -> %d -> %d\n",
+ CallerName(),
+ EnterPrio, AccessPrio, LeavePrio,
+ EnterCnt, AccessCnt, LeaveCnt
+ );
+#endif
+
+ printf(" AccessLocalHw returns to %s\n", CallerName());
+ #if defined(TEST_EXIT_AFTER_ITERATIONS)
+ if ( ++Iterations == 10 ) {
+ puts( "*** END OF TEST 35 ***" );
+ exit(0);
+ }
+ #endif
+ return;
+}
+
+void AccessRemoteHw(void)
+{
+ rtems_status_code Sts;
+
+ rtems_task_priority EnterPrio; /* Statistics log */
+ rtems_task_priority AccessPrio; /* : */
+ rtems_task_priority LeavePrio; /* : */
+ uint32_t EnterCnt; /* : */
+ uint32_t AccessCnt; /* : */
+ uint32_t LeaveCnt; /* : */
+
+ /* Store information about the current situation */
+ EnterPrio = _Thread_Executing->current_priority;
+ EnterCnt = _Thread_Executing->resource_count;
+
+
+ printf("AccessRemoteHw called by %s\n", CallerName());
+
+ /* Obtain exclusive access to remote HW, Start HW, Wait for completion,
+ * Release access
+ */
+
+ Sts = rtems_semaphore_obtain(RemoteHwAccess_R, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ directive_failed( Sts, "rtems_semaphore_obtain(RemoteHwAccess_R...)" );
+
+ /* Carry out the remote access via the Local HW interface */
+ printf("AccessRemoteHw access local %s\n", CallerName());
+ AccessLocalHw();
+
+ /* Store information about the current situation */
+ AccessPrio = _Thread_Executing->current_priority;
+ AccessCnt = _Thread_Executing->resource_count;
+
+ Sts = rtems_semaphore_release(RemoteHwAccess_R);
+ directive_failed( Sts, "rtems_semaphore_release(RemoreHwAccess_R" );
+
+ /* Store information about the current situation */
+ LeavePrio = _Thread_Executing->current_priority;
+ LeaveCnt = _Thread_Executing->resource_count;
+
+#if defined(TEST_PRINT_STATISTICS)
+ printf(
+ "\nAccessRemoteHw from %s statistics:\n"
+ " - Prio: %d -> %d -> %d\n - Cnt: %d -> %d -> %d\n",
+ CallerName(),
+ EnterPrio, AccessPrio, LeavePrio,
+ EnterCnt, AccessCnt, LeaveCnt);
+#endif
+
+ printf("AccessRemoteHw returns to %s\n", CallerName());
+ return;
+}
+
+/*************************************************************************/
+/********************** INITIALIZATION *********************/
+/*************************************************************************/
+
+/* The Init operation (the Init-task) */
+rtems_task Init(rtems_task_argument ignored)
+{
+ rtems_status_code status;
+#if defined(TEST_USE_ISR)
+ rtems_isr_entry DummyIsr;
+#endif
+ int i;
+
+ puts( "\n\n*** TEST 35 ***" );
+
+ /* Create synchronisation semaphore for LocalHwIsr -> Test Tasks */
+ status = rtems_semaphore_create(
+ rtems_build_name ('S', 'Y', 'N', 'C'), /* name */
+ 0, /* initial count = 0 */
+ RTEMS_LOCAL |
+ RTEMS_SIMPLE_BINARY_SEMAPHORE |
+ RTEMS_NO_INHERIT_PRIORITY |
+ RTEMS_NO_PRIORITY_CEILING |
+ RTEMS_FIFO,
+ 0,
+ &LocalHwSync_S); /* *id */
+ directive_failed( status, "rtems_semaphore_create (SYNC)" );
+
+ printf( "Sync Mutex Id = 0x%08x\n", LocalHwSync_S );
+
+ /* Create resource semaphore for exclusive access to the local HW */
+ status = rtems_semaphore_create(
+ rtems_build_name ('R', 'E', 'S', '1'), /* name */
+ 1, /* count */
+ RTEMS_PRIORITY |
+ RTEMS_BINARY_SEMAPHORE |
+ RTEMS_INHERIT_PRIORITY |
+ RTEMS_LOCAL, /* attribute_set */
+ 1, /* insignificant */ /* priority_ceiling */
+ &LocalHwAccess_R); /* *id */
+ directive_failed( status, "rtems_semaphore_create (RES1)" );
+
+ printf( "Local Mutex Id = 0x%08x\n", LocalHwAccess_R );
+
+ /* Create resource semaphore for exclusive access to the remote HW */
+ status = rtems_semaphore_create(
+ rtems_build_name ('R', 'E', 'S', '2'), /* name */
+ 1, /* count */
+ RTEMS_PRIORITY |
+ RTEMS_BINARY_SEMAPHORE |
+ RTEMS_INHERIT_PRIORITY |
+ RTEMS_LOCAL, /* attribute_set */
+ 1, /* insignificant */ /* priority_ceiling */
+ &RemoteHwAccess_R); /* *id */
+ directive_failed( status, "rtems_semaphore_create (RES2)" );
+
+ printf( "Remote Mutex Id = 0x%08x\n", RemoteHwAccess_R );
+
+#if defined(TEST_USE_ISR)
+ /* Install ISR for HW/SW synchronization, use ta 0x85 which is synchronous */
+ status = rtems_interrupt_catch(LocalHwIsr, 0x85 + 0x100, &DummyIsr);
+ directive_failed( status, "rtems_interrupt_catch" );
+#endif
+
+
+ printf("Ending Init-task\n");
+ /* Create and start all tasks in the test */
+
+ /* -- Medium-prio Test Tasks --- */
+ for (i = 0; i < NofMediumTask_C; i++) {
+ status = rtems_task_create(
+ rtems_build_name('M','E','D','0'+i), /* Name */
+ 100, /* Priority */
+ RTEMS_MINIMUM_STACK_SIZE*2, /* Stack size (8KB) */
+ RTEMS_DEFAULT_MODES | RTEMS_NO_ASR, /* Mode */
+ RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, /* Attributes */
+ &TaMedium[i]); /* Assigned ID */
+ directive_failed( status, "rtems_task_create (MEDn)" );
+
+ printf( "TaMedium[%d] Id = 0x%08x\n", i, TaMedium[i] );
+ status = rtems_task_start(TaMedium[i], Medium_Exec, i);
+ directive_failed( status, "rtems_task_start (MEDn)" );
+ }
+
+ /* -- High-prio Test Task --- */
+ status = rtems_task_create(
+ rtems_build_name('H','I','G','H'), /* Name */
+ 10, /* Priority */
+ RTEMS_MINIMUM_STACK_SIZE*2, /* Stack size (8KB) */
+ RTEMS_DEFAULT_MODES | RTEMS_NO_ASR, /* Mode */
+ RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, /* Attributes */
+ &TaHigh); /* Assigned ID */
+ directive_failed( status, "rtems_task_create (HIGH)" );
+
+ printf( "TaHigh Id = 0x%08x\n", TaHigh );
+ status = rtems_task_start(TaHigh, High_Exec, 0);
+ directive_failed( status, "rtems_task_start (HIGH)" );
+
+ /* -- Low-prio Test Task --- */
+ status = rtems_task_create(
+ rtems_build_name('L','O','W',' '), /* Name */
+ 200, /* Priority */
+ RTEMS_MINIMUM_STACK_SIZE*2, /* Stack size (8KB) */
+ RTEMS_DEFAULT_MODES | RTEMS_NO_ASR, /* Mode */
+ RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, /* Attributes */
+ &TaLow); /* Assigned ID */
+ directive_failed( status, "rtems_task_create (LOW)" );
+
+ printf( "TaLow Id = 0x%08x\n", TaLow );
+ status = rtems_task_start(TaLow, Low_Exec, 0);
+ directive_failed( status, "rtems_task_start (LOW)" );
+
+ /* -- HW Simulator Task --- */
+ status = rtems_task_create(
+ rtems_build_name('H','W','S','M'), /* Name */
+ 240, /* Priority */
+ RTEMS_MINIMUM_STACK_SIZE*2, /* Stack size (8KB) */
+ RTEMS_DEFAULT_MODES | RTEMS_NO_ASR, /* Mode */
+ RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, /* Attributes */
+ &TaHwSim); /* Assigned ID */
+ directive_failed( status, "rtems_task_create (HWSM)" );
+
+ printf( "TaHwSim Id = 0x%08x\n", TaHwSim );
+
+ status = rtems_task_start(TaHwSim, LocalHwSim_Exec, 0);
+ directive_failed( status, "rtems_task_start (HWSM)" );
+
+ /* Destroy the Init task (and let the ready tasks start running) */
+ rtems_task_delete(RTEMS_SELF);
+}
+
+/* configuration information */
+
+#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_MEMORY_OVERHEAD 64
+
+#define CONFIGURE_MAXIMUM_TASKS 10
+#define CONFIGURE_MAXIMUM_SEMAPHORES 10
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/* end of file */
diff --git a/testsuites/sptests/sp35/sp35.doc b/testsuites/sptests/sp35/sp35.doc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testsuites/sptests/sp35/sp35.doc
diff --git a/testsuites/sptests/sp35/sp35.scn b/testsuites/sptests/sp35/sp35.scn
new file mode 100644
index 0000000000..c07f87cee6
--- /dev/null
+++ b/testsuites/sptests/sp35/sp35.scn
@@ -0,0 +1,59 @@
+Exception handling initialization done
+
+
+*** TEST 35 ***
+Sync Mutex Id = 0x1a010009
+Local Mutex Id = 0x1a01000a
+Remote Mutex Id = 0x1a01000b
+Ending Init-task
+TaMedium[0] Id = 0x0a010002
+TaMedium[1] Id = 0x0a010003
+TaMedium[2] Id = 0x0a010004
+TaHigh Id = 0x0a010005
+TaLow Id = 0x0a010006
+TaHwSim Id = 0x0a010007
+High_Exec (0) begins...
+Medium_Exec (0) begins...
+Medium_Exec (1) begins...
+Medium_Exec (2) begins...
+Low_Exec (0) begins...
+LocalHwSim_Exec begins...
+ AccessLocalHw called by MED0 -- 100
+ AccessLocalHw called by MED2 -- 100
+ AccessLocalHw called by MED1 -- 100
+AccessRemoteHw called by LOW -- 200
+AccessRemoteHw access local LOW -- 200
+ AccessLocalHw called by LOW -- 200
+ AccessLocalHw returns to MED0 -- 100
+ AccessLocalHw called by MED0 -- 100
+AccessRemoteHw called by HIGH -- 10
+ AccessLocalHw returns to MED2 -- 100
+ AccessLocalHw called by MED2 -- 100
+ AccessLocalHw returns to LOW -- 10
+AccessRemoteHw access local HIGH -- 10
+ AccessLocalHw called by HIGH -- 10
+AccessRemoteHw returns to LOW -- 200
+AccessRemoteHw called by LOW -- 200
+ AccessLocalHw returns to MED1 -- 100
+ AccessLocalHw called by MED1 -- 100
+ AccessLocalHw returns to HIGH -- 10
+AccessRemoteHw returns to HIGH -- 10
+AccessRemoteHw called by HIGH -- 10
+AccessRemoteHw access local LOW -- 10
+ AccessLocalHw called by LOW -- 10
+ AccessLocalHw returns to MED0 -- 100
+ AccessLocalHw called by MED0 -- 100
+ AccessLocalHw returns to LOW -- 10
+AccessRemoteHw access local HIGH -- 10
+ AccessLocalHw called by HIGH -- 10
+AccessRemoteHw returns to LOW -- 200
+AccessRemoteHw called by LOW -- 200
+ AccessLocalHw returns to MED2 -- 100
+ AccessLocalHw called by MED2 -- 100
+ AccessLocalHw returns to HIGH -- 10
+AccessRemoteHw returns to HIGH -- 10
+AccessRemoteHw called by HIGH -- 10
+AccessRemoteHw access local LOW -- 10
+ AccessLocalHw called by LOW -- 10
+ AccessLocalHw returns to MED1 -- 100
+*** END OF TEST 35 ***