forked from Imagelibrary/rtems
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:
@@ -6,7 +6,6 @@ if SMPTESTS
|
||||
SUBDIRS += smp01
|
||||
SUBDIRS += smp02
|
||||
SUBDIRS += smp03
|
||||
SUBDIRS += smp04
|
||||
SUBDIRS += smp05
|
||||
SUBDIRS += smp06
|
||||
SUBDIRS += smp07
|
||||
|
||||
@@ -39,7 +39,6 @@ AC_CONFIG_FILES([Makefile
|
||||
smp01/Makefile
|
||||
smp02/Makefile
|
||||
smp03/Makefile
|
||||
smp04/Makefile
|
||||
smp05/Makefile
|
||||
smp06/Makefile
|
||||
smp07/Makefile
|
||||
|
||||
@@ -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
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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 ***
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user