summaryrefslogtreecommitdiffstats
path: root/testsuites/sptests
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-03 08:15:21 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-06 12:57:07 +0200
commit3ad5f86cf6803204b98760cdce0c56ef6d79bccd (patch)
treeae018224b2cdda837bd174ad94397a5e043dc2ea /testsuites/sptests
parenttftp: Use proper semaphore attr for mutex (diff)
downloadrtems-3ad5f86cf6803204b98760cdce0c56ef6d79bccd.tar.bz2
rtems: Fix no protocol mutex release
The Classic binary semaphores without a locking protocol (RTEMS_BINARY_SEMAPHORE) could be released by everyone, e.g. in contrast to the POSIX mutexes (all variants) or the Classic binary semphores with priority inheritance or ceiling, there was no owner check in the release path. This behaviour was a bit unexpected and not documented. Add an owner check to the release path. Update sptests/sp42 accordingly. This change has nothing to do with the simple binary semaphores (RTEMS_SIMPLE_BINARY_SEMAPHORE) which have no owner at all. Update #2725
Diffstat (limited to 'testsuites/sptests')
-rw-r--r--testsuites/sptests/sp42/init.c109
-rw-r--r--testsuites/sptests/sp42/sp42.scn4
2 files changed, 71 insertions, 42 deletions
diff --git a/testsuites/sptests/sp42/init.c b/testsuites/sptests/sp42/init.c
index 55faa9b97d..6d96edee51 100644
--- a/testsuites/sptests/sp42/init.c
+++ b/testsuites/sptests/sp42/init.c
@@ -24,19 +24,12 @@ const char rtems_test_name[] = "SP 42";
#define MAX_TASKS 20
-rtems_task Init(rtems_task_argument argument);
-rtems_task Locker_task(rtems_task_argument unused);
-void do_test(
- rtems_attribute attr,
- bool extract /* TRUE if extract, not release */
-);
-
/*
* Carefully chosen to exercise threadq enqueue/dequeue priority logic.
* Somewhat randomly sorted to ensure than if discipline is FIFO, run-time
* behavior won't be the same when released.
*/
-rtems_task_priority Priorities_High[MAX_TASKS] = {
+static const rtems_task_priority Priorities_High[MAX_TASKS] = {
37, 37, 37, 37, /* backward - more 2-n */
2, 2, 2, 2, /* forward - multiple are on 2-n chain */
4, 3, /* forward - search forward arbitrary */
@@ -45,7 +38,7 @@ rtems_task_priority Priorities_High[MAX_TASKS] = {
34, 34, 34, 34, /* backward - multple on 2-n chain */
};
-rtems_task_priority Priorities_Low[MAX_TASKS] = {
+static const rtems_task_priority Priorities_Low[MAX_TASKS] = {
13, 13, 13, 13, /* backward - more 2-n */
2, 2, 2, 2, /* forward - multiple are on 2-n chain */
4, 3, /* forward - search forward arbitrary */
@@ -54,24 +47,37 @@ rtems_task_priority Priorities_Low[MAX_TASKS] = {
12, 12, 12, 12, /* backward - multple on 2-n chain */
};
-rtems_task_priority *Priorities;
+static const int Obtain_order[2][MAX_TASKS] = {
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 },
+ { 4, 5, 6, 7, 9, 10, 11, 12, 13, 8, 16, 17, 18, 19, 0, 1, 2, 3, 15, 14 }
+};
+
+static const rtems_task_priority *Priorities;
+
+static rtems_id Semaphore;
+static rtems_id Master;
+static rtems_id Task_id[ MAX_TASKS ];
+static rtems_name Task_name[ MAX_TASKS ];
+
+static rtems_task_argument Obtain_counter;
-rtems_id Semaphore;
-rtems_id Task_id[ MAX_TASKS ];
-rtems_name Task_name[ MAX_TASKS ];
+static enum {
+ FIFO,
+ PRIORITY
+} Variant;
-rtems_task Locker_task(
- rtems_task_argument unused
+static rtems_task Locker_task(
+ rtems_task_argument task_index
)
{
- rtems_id tid;
- uint32_t task_index;
- rtems_status_code status;
+ rtems_id tid;
+ rtems_status_code status;
+ rtems_task_argument my_obtain_counter;
status = rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &tid );
directive_failed( status, "rtems_task_ident" );
- task_index = task_number( tid ) - 1;
+ rtems_test_assert( task_index == task_number( tid ) - 1 );
status = rtems_semaphore_obtain( Semaphore, RTEMS_DEFAULT_OPTIONS, 0 );
directive_failed( status, "rtems_semaphore_obtain" );
@@ -79,28 +85,45 @@ rtems_task Locker_task(
put_name( Task_name[ task_index ], FALSE );
puts( " - unblocked - OK" );
+ status = rtems_task_wake_after( 10 );
+ directive_failed( status, "rtems_task_wake_after" );
+
+ my_obtain_counter = Obtain_counter;
+ rtems_test_assert( task_index == Obtain_order[ Variant ][ Obtain_counter ] );
+ ++Obtain_counter;
+
+ status = rtems_semaphore_release( Semaphore );
+ directive_failed( status, "rtems_semaphore_release" );
+
+ if ( my_obtain_counter == MAX_TASKS - 1 ) {
+ status = rtems_event_transient_send( Master );
+ directive_failed( status, "rtems_event_transient_send" );
+ }
+
(void) rtems_task_delete( RTEMS_SELF );
}
-void do_test(
+static void do_test(
rtems_attribute attr,
bool extract /* TRUE if extract, not release */
)
{
- rtems_status_code status;
- int i;
+ rtems_status_code status;
+ rtems_task_argument i;
+
+ Variant = ( ( attr & RTEMS_PRIORITY ) != 0 ? PRIORITY : FIFO );
+ Obtain_counter = 0;
status = rtems_semaphore_create(
rtems_build_name( 'S', 'E', 'M', '0' ), /* name = SEM0 */
- 0, /* unlocked */
+ 0, /* locked */
RTEMS_BINARY_SEMAPHORE | attr, /* mutex w/desired discipline */
0, /* IGNORED */
&Semaphore
);
directive_failed( status, "rtems_semaphore_create" );
- for (i=0 ; i< MAX_TASKS ; i++ ) {
-
+ for (i = 0 ; i < MAX_TASKS ; i++ ) {
Task_name[ i ] = rtems_build_name(
'T',
'A',
@@ -118,42 +141,42 @@ void do_test(
);
directive_failed( status, "rtems_task_create" );
- status = rtems_task_start(
- Task_id[ i ], Locker_task, (rtems_task_argument)i );
+ status = rtems_task_start( Task_id[ i ], Locker_task, i );
directive_failed( status, "rtems_task_start" );
-
- status = rtems_task_wake_after( 10 );
- directive_failed( status, "rtems_task_wake_after" );
}
- for (i=0 ; i< MAX_TASKS ; i++ ) {
- if ( extract == FALSE ) {
- status = rtems_semaphore_release( Semaphore );
- directive_failed( status, "rtems_semaphore_release" );
-
- status = rtems_task_wake_after( 100 );
- directive_failed( status, "rtems_task_wake_after" );
- } else {
+ if ( extract ) {
+ for (i = 0 ; i< MAX_TASKS ; i++ ) {
status = rtems_task_delete( Task_id[ i ] );
directive_failed( status, "rtems_task_delete" );
}
}
- /* one extra release for the initial state */
+ /* do the initial release */
status = rtems_semaphore_release( Semaphore );
directive_failed( status, "rtems_semaphore_release" );
+ if ( !extract ) {
+ status = rtems_event_transient_receive( RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+ directive_failed( status, "rtems_event_transient_receive" );
+ }
+
/* now delete the semaphore since no one is waiting and it is unlocked */
status = rtems_semaphore_delete( Semaphore );
directive_failed( status, "rtems_semaphore_delete" );
}
-rtems_task Init(
+static rtems_task Init(
rtems_task_argument argument
)
{
+ rtems_task_priority prio;
+ rtems_status_code status;
+
TEST_BEGIN();
+ Master = rtems_task_self();
+
if (RTEMS_MAXIMUM_PRIORITY == 255)
Priorities = Priorities_High;
else if (RTEMS_MAXIMUM_PRIORITY == 15)
@@ -163,6 +186,10 @@ rtems_task Init(
rtems_test_exit( 0 );
}
+ prio = RTEMS_MAXIMUM_PRIORITY - 1;
+ status = rtems_task_set_priority(RTEMS_SELF, prio, &prio);
+ directive_failed( status, "rtems_task_set_priority" );
+
if ( sizeof(Priorities_Low) / sizeof(rtems_task_priority) != MAX_TASKS ) {
puts( "Priorities_Low table does not have right number of entries" );
rtems_test_exit( 0 );
@@ -201,6 +228,8 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS MAX_TASKS+1
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
diff --git a/testsuites/sptests/sp42/sp42.scn b/testsuites/sptests/sp42/sp42.scn
index 01adcf729d..206d05c40b 100644
--- a/testsuites/sptests/sp42/sp42.scn
+++ b/testsuites/sptests/sp42/sp42.scn
@@ -1,4 +1,4 @@
-*** START OF TEST 42 ***
+*** BEGIN OF TEST SP 42 ***
Exercising blocking discipline w/extract in FIFO order
Exercising blocking discipline w/unblock in FIFO order
TA00 - unblocked - OK
@@ -44,4 +44,4 @@ TA02 - unblocked - OK
TA03 - unblocked - OK
TA15 - unblocked - OK
TA14 - unblocked - OK
-*** END OF TEST 42 ***
+*** END OF TEST SP 42 ***