score: Error for non-preemptible tasks on SMP

A common use case for disabled preemption was to ensure mutual exclusion
on single-processor configurations.  On SMP this does not work.

To abandon non-preemptible tasks simplifies the scheduler.
This commit is contained in:
Sebastian Huber
2013-07-18 11:53:48 +02:00
parent 79d9523f19
commit 05e82bd76b
12 changed files with 41 additions and 268 deletions

View File

@@ -6,7 +6,6 @@ if SMPTESTS
SUBDIRS += smp01
SUBDIRS += smp02
SUBDIRS += smp03
SUBDIRS += smp04
SUBDIRS += smp05
SUBDIRS += smp06
SUBDIRS += smp07

View File

@@ -39,7 +39,6 @@ AC_CONFIG_FILES([Makefile
smp01/Makefile
smp02/Makefile
smp03/Makefile
smp04/Makefile
smp05/Makefile
smp06/Makefile
smp07/Makefile

View File

@@ -1,23 +0,0 @@
rtems_tests_PROGRAMS = smp04
smp04_SOURCES = init.c system.h ../../support/src/locked_print.c
dist_rtems_tests_DATA = smp04.scn
dist_rtems_tests_DATA += smp04.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
AM_CPPFLAGS += -DSMPTEST
LINK_OBJS = $(smp04_OBJECTS)
LINK_LIBS = $(smp04_LDLIBS)
smp04$(EXEEXT): $(smp04_OBJECTS) $(smp04_DEPENDENCIES)
@rm -f smp04$(EXEEXT)
$(make-exe)
include $(top_srcdir)/../automake/local.am

View File

@@ -1,150 +0,0 @@
/*
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CONFIGURE_INIT
#include "system.h"
#include <stdio.h>
#include <inttypes.h>
void Loop() {
volatile int i;
for (i=0; i<500000; i++);
}
rtems_task Test_task(
rtems_task_argument task_index
)
{
uint32_t cpu_num;
cpu_num = rtems_smp_get_current_processor();
locked_printf(" CPU %d running task TA%" PRIu32 "\n", cpu_num, task_index );
Loop();
TaskRan[task_index] = true;
while(1);
}
rtems_task Init(
rtems_task_argument argument
)
{
uint32_t i;
char ch;
rtems_id id;
rtems_status_code status;
bool allDone;
uint32_t cpu_num;
Loop();
locked_print_initialize();
locked_printf( "\n\n*** SMP04 TEST ***\n" );
/* Display which cpu is running this init thread. */
cpu_num = rtems_smp_get_current_processor();
locked_printf(" CPU %" PRIu32 " running task Init\n", cpu_num );
/* Set all Tasks to not ran except for the init task */
TaskRan[0] = true;
for ( i=1; i <= rtems_smp_get_processor_count() ; i++ )
TaskRan[i] = false;
/*
* For each processor create and start a task alternating
* between RTEMS_PREEMPT and RTEMS_NO_PREEMPT.
*/
for ( i=1; i < rtems_smp_get_processor_count() ; i++ ){
/* Create and start tasks for each CPU */
ch = '0' + i;
locked_printf(
"Create a TA%c a %s task\n",
ch,
((i%2) ? "RTEMS_PREEMPT" : "RTEMS_NO_PREEMPT" )
);
status = rtems_task_create(
rtems_build_name( 'T', 'A', ch, ' ' ),
CONFIGURE_INIT_TASK_PRIORITY +
(2*rtems_smp_get_processor_count()) - (2*i),
RTEMS_MINIMUM_STACK_SIZE,
((i%2) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT),
RTEMS_DEFAULT_ATTRIBUTES,
&id
);
locked_printf(
"Start TA%c a %s task\n",
ch,
((i%2) ? "RTEMS_PREEMPT" : "RTEMS_NO_PREEMPT" )
);
status = rtems_task_start( id, Test_task, i );
/*
* Force a wait on the task to run in order to synchronize on
* simulated systems.
*/
while (TaskRan[i] == false)
;
}
/*
* Create and start one more task. This task
* should preempt the longest running PREEMPTABLE
* task and run on that cpu.
*/
ch = '0' + rtems_smp_get_processor_count() ;
locked_printf(
"Create a TA%c a %s task\n",
ch,
"RTEMS_PREEMPT"
);
status = rtems_task_create(
rtems_build_name( 'T', 'A', ch, ' ' ),
3,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_PREEMPT,
RTEMS_DEFAULT_ATTRIBUTES,
&id
);
locked_printf(
"Start TA%c a %s task\n",
ch,
"RTEMS_PREEMPT"
);
status = rtems_task_start(
id,
Test_task,
rtems_smp_get_processor_count()
);
/*
* Wait on the all tasks to run
*/
while (1) {
allDone = true;
for ( i=1; i<=rtems_smp_get_processor_count() ; i++ ) {
if (TaskRan[i] == false)
allDone = false;
}
if (allDone) {
Loop();
locked_printf( "*** END OF TEST SMP04 ***\n" );
rtems_test_exit( 0 );
}
}
}

View File

@@ -1,14 +0,0 @@
# COPYRIGHT (c) 1989-2011.
# On-Line Applications Research Corporation (OAR).
#
# The license and distribution terms for this file may be
# found in the file LICENSE in this distribution or at
# http://www.rtems.com/license/LICENSE.
#
This test startst Init task with priority 5 and preemption on which
runs on CPU 0. The init task alternates preemption off and preemtion
on as it creates tasks for every other cpu in the system. The priority
of task N will be 5 + 2; task N-1 will be 5 + 4 .....
Another task will be created after tasks are running on all cpus. This
task will be of a priority 3. For a 4 cpu system this task should run
on cpu 2. For a 2 cpu system the task should preempt the Init task.

View File

@@ -1,8 +0,0 @@
*** SMP04 TEST ***
CPU 0 running task Init
CPU 1 running task TA1
CPU 2 running task TA2
CPU 3 running task TA3
CPU 2 running task TA4
*** END OF SMP 04 TEST ***

View File

@@ -1,68 +0,0 @@
/*
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include "tmacros.h"
#include "test_support.h"
/* functions */
rtems_task Init(
rtems_task_argument argument
);
rtems_task Test_task(
rtems_task_argument argument
);
/* configuration information */
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_SMP_APPLICATION
#define CONFIGURE_SMP_MAXIMUM_PROCESSORS 4
#define CONFIGURE_MAXIMUM_TASKS \
(1 + CONFIGURE_SMP_MAXIMUM_PROCESSORS)
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT_TASK_STACK_SIZE \
(3 * CONFIGURE_MINIMUM_TASK_STACK_SIZE)
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT_TASK_PRIORITY 5
#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_NO_PREEMPT
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
#include <rtems/confdefs.h>
/* global variables */
/*
* Keep the names and IDs in global variables so another task can use them.
*/
void Loop(void);
void PrintTaskInfo(
const char *task_name
);
TEST_EXTERN volatile bool TaskRan[ CONFIGURE_SMP_MAXIMUM_PROCESSORS ];
/*
* Handy macros and static inline functions
*/
/*
* Macro to hide the ugliness of printing the time.
*/
/* end of include file */

View File

@@ -21,6 +21,8 @@
static void test(void)
{
rtems_status_code sc;
rtems_mode mode;
rtems_id id;
rtems_test_assert(rtems_configuration_is_smp_enabled());
@@ -35,6 +37,19 @@ static void test(void)
sc = rtems_task_variable_get(RTEMS_SELF, NULL, NULL);
rtems_test_assert(sc == RTEMS_NOT_IMPLEMENTED);
sc = rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &mode);
rtems_test_assert(sc == RTEMS_NOT_IMPLEMENTED);
sc = rtems_task_create(
rtems_build_name('T', 'A', 'S', 'K'),
RTEMS_MINIMUM_PRIORITY,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_NO_PREEMPT,
RTEMS_DEFAULT_ATTRIBUTES,
&id
);
rtems_test_assert(sc == RTEMS_UNSATISFIED);
}
static void Init(rtems_task_argument arg)
@@ -55,7 +70,7 @@ static void Init(rtems_task_argument arg)
#define CONFIGURE_SMP_MAXIMUM_PROCESSORS 1
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE