summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2010-06-29 00:34:12 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2010-06-29 00:34:12 +0000
commit11e8bc5f0fa2d9485908874dbfe9cd65c1aec477 (patch)
tree8e21888988f4c1e22aff26478e3f158e60c444c6
parent2010-06-28 Joel Sherrill <joel.sherrill@oarcorp.com> (diff)
downloadrtems-11e8bc5f0fa2d9485908874dbfe9cd65c1aec477.tar.bz2
2010-06-28 Joel Sherrill <joel.sherrill@oarcorp.com>
PR 1573/cpukit * configure.ac, posix/src/killinfo.c, posix/src/psignalclearprocesssignals.c, posix/src/psignalsetprocesssignals.c, posix/src/psignalunblockthread.c, posix/src/pthreadcreate.c, posix/src/pthreadkill.c, posix/src/pthreadsigmask.c, rtems/src/signalsend.c, rtems/src/taskmode.c, score/Makefile.am, score/preinstall.am, score/include/rtems/system.h, score/include/rtems/score/context.h, score/include/rtems/score/isr.h, score/include/rtems/score/thread.h, score/src/isr.c, score/src/isrthreaddispatch.c, score/src/thread.c, score/src/threaddispatch.c, score/src/threadloadenv.c: Add a per cpu data structure which contains the information required by RTEMS for each CPU core. This encapsulates information such as thread executing, heir, idle and dispatch needed. * score/include/rtems/score/percpu.h, score/src/percpu.c: New files.
-rw-r--r--cpukit/ChangeLog19
-rw-r--r--cpukit/configure.ac3
-rw-r--r--cpukit/posix/src/killinfo.c2
-rw-r--r--cpukit/posix/src/psignalclearprocesssignals.c2
-rw-r--r--cpukit/posix/src/psignalsetprocesssignals.c2
-rw-r--r--cpukit/posix/src/psignalunblockthread.c4
-rw-r--r--cpukit/posix/src/pthreadcreate.c8
-rw-r--r--cpukit/posix/src/pthreadkill.c4
-rw-r--r--cpukit/posix/src/pthreadsigmask.c1
-rw-r--r--cpukit/rtems/src/signalsend.c4
-rw-r--r--cpukit/rtems/src/taskmode.c1
-rw-r--r--cpukit/score/Makefile.am21
-rw-r--r--cpukit/score/include/rtems/score/context.h13
-rw-r--r--cpukit/score/include/rtems/score/isr.h17
-rw-r--r--cpukit/score/include/rtems/score/percpu.h166
-rw-r--r--cpukit/score/include/rtems/score/thread.h42
-rw-r--r--cpukit/score/include/rtems/system.h1
-rw-r--r--cpukit/score/preinstall.am4
-rw-r--r--cpukit/score/src/isr.c5
-rw-r--r--cpukit/score/src/isrthreaddispatch.c9
-rw-r--r--cpukit/score/src/percpu.c29
-rw-r--r--cpukit/score/src/thread.c2
-rw-r--r--cpukit/score/src/threaddispatch.c22
-rw-r--r--cpukit/score/src/threadloadenv.c2
24 files changed, 272 insertions, 111 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog
index e654ec3b71..726bf953bf 100644
--- a/cpukit/ChangeLog
+++ b/cpukit/ChangeLog
@@ -1,5 +1,24 @@
2010-06-28 Joel Sherrill <joel.sherrill@oarcorp.com>
+ PR 1573/cpukit
+ * configure.ac, posix/src/killinfo.c,
+ posix/src/psignalclearprocesssignals.c,
+ posix/src/psignalsetprocesssignals.c,
+ posix/src/psignalunblockthread.c, posix/src/pthreadcreate.c,
+ posix/src/pthreadkill.c, posix/src/pthreadsigmask.c,
+ rtems/src/signalsend.c, rtems/src/taskmode.c, score/Makefile.am,
+ score/preinstall.am, score/include/rtems/system.h,
+ score/include/rtems/score/context.h, score/include/rtems/score/isr.h,
+ score/include/rtems/score/thread.h, score/src/isr.c,
+ score/src/isrthreaddispatch.c, score/src/thread.c,
+ score/src/threaddispatch.c, score/src/threadloadenv.c: Add a per cpu
+ data structure which contains the information required by RTEMS for
+ each CPU core. This encapsulates information such as thread
+ executing, heir, idle and dispatch needed.
+ * score/include/rtems/score/percpu.h, score/src/percpu.c: New files.
+
+2010-06-28 Joel Sherrill <joel.sherrill@oarcorp.com>
+
* libcsupport/src/libio_sockets.c: Use
rtems_set_errno_and_return_minus_one() where it was missed before.
diff --git a/cpukit/configure.ac b/cpukit/configure.ac
index 116bc6c791..d74c424210 100644
--- a/cpukit/configure.ac
+++ b/cpukit/configure.ac
@@ -251,6 +251,9 @@ AC_CHECK_DECLS([sbrk],,,[#include <unistd.h>])
## Check if libc provides BSD's strlcpy/strlcat
AC_CHECK_FUNCS(strlcpy strlcat)
+## This is needed to generate the field offsets of the per CPU
+## data structure so they can be accessed from assembly code.
+AC_CHECK_SIZEOF([void *])
# ... far too many conditionals ...
AM_CONDITIONAL(LIBRPC,[test x"$rtems_cv_HAS_NETWORKING" = x"yes"])
diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c
index c02f7807e6..2ae5857a6f 100644
--- a/cpukit/posix/src/killinfo.c
+++ b/cpukit/posix/src/killinfo.c
@@ -314,8 +314,6 @@ int killinfo(
*/
process_it:
- the_thread->do_post_task_switch_extension = true;
-
/*
* Returns true if the signal was synchronously given to a thread
* blocked waiting for the signal.
diff --git a/cpukit/posix/src/psignalclearprocesssignals.c b/cpukit/posix/src/psignalclearprocesssignals.c
index a601fa2406..b11ae0ebc2 100644
--- a/cpukit/posix/src/psignalclearprocesssignals.c
+++ b/cpukit/posix/src/psignalclearprocesssignals.c
@@ -53,8 +53,6 @@ void _POSIX_signals_Clear_process_signals(
}
if ( clear_signal ) {
_POSIX_signals_Pending &= ~mask;
- if ( !_POSIX_signals_Pending )
- _Thread_Do_post_task_switch_extension--;
}
_ISR_Enable( level );
}
diff --git a/cpukit/posix/src/psignalsetprocesssignals.c b/cpukit/posix/src/psignalsetprocesssignals.c
index 25209f3c4d..cb4ad8b241 100644
--- a/cpukit/posix/src/psignalsetprocesssignals.c
+++ b/cpukit/posix/src/psignalsetprocesssignals.c
@@ -41,8 +41,6 @@ void _POSIX_signals_Set_process_signals(
ISR_Level level;
_ISR_Disable( level );
- if ( !_POSIX_signals_Pending )
- _Thread_Do_post_task_switch_extension++;
_POSIX_signals_Pending |= mask;
_ISR_Enable( level );
}
diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c
index fdba79a00c..912ac34694 100644
--- a/cpukit/posix/src/psignalunblockthread.c
+++ b/cpukit/posix/src/psignalunblockthread.c
@@ -98,8 +98,6 @@ bool _POSIX_signals_Unblock_thread(
* + Any other combination, do nothing.
*/
- the_thread->do_post_task_switch_extension = true;
-
if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
the_thread->Wait.return_code = EINTR;
/*
@@ -120,7 +118,7 @@ bool _POSIX_signals_Unblock_thread(
}
} else if ( the_thread->current_state == STATES_READY ) {
if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
- _ISR_Signals_to_thread_executing = true;
+ _Context_Switch_necessary = true;
}
}
return false;
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index c5ca86d52e..d7f08a5527 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -191,14 +191,6 @@ int pthread_create(
api->schedparam = schedparam;
/*
- * This insures we evaluate the process-wide signals pending when we
- * first run.
- *
- * NOTE: Since the thread starts with all unblocked, this is necessary.
- */
- the_thread->do_post_task_switch_extension = true;
-
- /*
* POSIX threads are allocated and started in one operation.
*/
status = _Thread_Start(
diff --git a/cpukit/posix/src/pthreadkill.c b/cpukit/posix/src/pthreadkill.c
index 9b6bd408e0..6d96067049 100644
--- a/cpukit/posix/src/pthreadkill.c
+++ b/cpukit/posix/src/pthreadkill.c
@@ -63,10 +63,8 @@ int pthread_kill(
(void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL );
- the_thread->do_post_task_switch_extension = true;
-
if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
- _ISR_Signals_to_thread_executing = true;
+ _Context_Switch_necessary = true;
}
_Thread_Enable_dispatch();
return 0;
diff --git a/cpukit/posix/src/pthreadsigmask.c b/cpukit/posix/src/pthreadsigmask.c
index 2fdc720282..c97e75a89e 100644
--- a/cpukit/posix/src/pthreadsigmask.c
+++ b/cpukit/posix/src/pthreadsigmask.c
@@ -65,7 +65,6 @@ int pthread_sigmask(
if ( ~api->signals_blocked &
(api->signals_pending | _POSIX_signals_Pending) ) {
- _Thread_Executing->do_post_task_switch_extension = true;
_Thread_Dispatch();
}
diff --git a/cpukit/rtems/src/signalsend.c b/cpukit/rtems/src/signalsend.c
index 038317e55d..f51b168997 100644
--- a/cpukit/rtems/src/signalsend.c
+++ b/cpukit/rtems/src/signalsend.c
@@ -64,10 +64,8 @@ rtems_status_code rtems_signal_send(
if ( asr->is_enabled ) {
_ASR_Post_signals( signal_set, &asr->signals_posted );
- the_thread->do_post_task_switch_extension = true;
-
if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
- _ISR_Signals_to_thread_executing = true;
+ _Context_Switch_necessary = true;
} else {
_ASR_Post_signals( signal_set, &asr->signals_pending );
}
diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c
index 56f707c5e7..57872b11ce 100644
--- a/cpukit/rtems/src/taskmode.c
+++ b/cpukit/rtems/src/taskmode.c
@@ -117,7 +117,6 @@ rtems_status_code rtems_task_mode(
_ASR_Swap_signals( asr );
if ( _ASR_Are_signals_pending( asr ) ) {
needs_asr_dispatching = true;
- executing->do_post_task_switch_extension = true;
}
}
}
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 7dd430fc5a..acf9a77c6e 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -24,15 +24,15 @@ include_rtems_score_HEADERS = include/rtems/score/address.h \
include/rtems/score/coremutex.h include/rtems/score/coresem.h \
include/rtems/score/heap.h include/rtems/score/protectedheap.h \
include/rtems/score/interr.h include/rtems/score/isr.h \
- include/rtems/score/object.h include/rtems/score/priority.h \
- include/rtems/score/stack.h include/rtems/score/states.h \
- include/rtems/score/sysstate.h include/rtems/score/thread.h \
- include/rtems/score/threadq.h include/rtems/score/threadsync.h \
- include/rtems/score/timespec.h include/rtems/score/timestamp.h \
- include/rtems/score/timestamp64.h include/rtems/score/tod.h \
- include/rtems/score/tqdata.h include/rtems/score/userext.h \
- include/rtems/score/watchdog.h include/rtems/score/wkspace.h \
- include/rtems/score/cpuopts.h
+ include/rtems/score/object.h include/rtems/score/percpu.h \
+ include/rtems/score/priority.h include/rtems/score/stack.h \
+ include/rtems/score/states.h include/rtems/score/sysstate.h \
+ include/rtems/score/thread.h include/rtems/score/threadq.h \
+ include/rtems/score/threadsync.h include/rtems/score/timespec.h \
+ include/rtems/score/timestamp.h include/rtems/score/timestamp64.h \
+ include/rtems/score/tod.h include/rtems/score/tqdata.h \
+ include/rtems/score/userext.h include/rtems/score/watchdog.h \
+ include/rtems/score/wkspace.h include/rtems/score/cpuopts.h
if HAS_PTHREADS
include_rtems_score_HEADERS += include/rtems/score/corespinlock.h \
@@ -101,6 +101,9 @@ libscore_a_SOURCES += src/coremutex.c src/coremutexflush.c \
src/coremutexseize.c src/coremutexsurrender.c \
src/coremutexseizeintr.c
+## CORE_PERCPU_C_FILES
+libscore_a_SOURCES += src/percpu.c
+
## CORE_RWLOCK_C_FILES
if HAS_PTHREADS
libscore_a_SOURCES += src/corerwlock.c src/corerwlockobtainread.c \
diff --git a/cpukit/score/include/rtems/score/context.h b/cpukit/score/include/rtems/score/context.h
index 862cf48fcd..8c1a1021e0 100644
--- a/cpukit/score/include/rtems/score/context.h
+++ b/cpukit/score/include/rtems/score/context.h
@@ -23,6 +23,9 @@
*
* This handler encapsulates functionality which abstracts thread context
* management in a portable manner.
+ *
+ * The context switch needed variable is contained in the per cpu
+ * data structure.
*/
/**@{*/
@@ -41,16 +44,6 @@ extern "C" {
#define CONTEXT_FP_SIZE CPU_CONTEXT_FP_SIZE
/**
- * @brief Is Context Switch Needed?
- *
- * This variable is set to true when a reschedule operation
- * has determined that the processor should be taken away from the
- * currently executing thread and given to the heir thread.
- */
-
-SCORE_EXTERN volatile bool _Context_Switch_necessary;
-
-/**
* @brief Initialize Context Area
* This routine initializes @a _the_context such that the stack
* pointer, interrupt level, and entry point are correct for the
diff --git a/cpukit/score/include/rtems/score/isr.h b/cpukit/score/include/rtems/score/isr.h
index 66adbcb943..6f8096a2a9 100644
--- a/cpukit/score/include/rtems/score/isr.h
+++ b/cpukit/score/include/rtems/score/isr.h
@@ -21,11 +21,16 @@
#ifndef _RTEMS_SCORE_ISR_H
#define _RTEMS_SCORE_ISR_H
+#include <rtems/score/percpu.h>
+
/**
* @defgroup ScoreISR ISR Handler
*
* This handler encapsulates functionality which provides the foundation
* ISR services used in all of the APIs supported by RTEMS.
+ *
+ * The ISR Nest level counter variable is maintained as part of the
+ * per cpu data structure.
*/
/**@{*/
@@ -75,18 +80,6 @@ typedef ISR_Handler ( *ISR_Handler_entry )(
*/
#define ISR_INTERRUPT_MAXIMUM_VECTOR_NUMBER CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER
-/**
- * The following is true if signals have been sent to the currently
- * executing thread by an ISR handler.
- */
-SCORE_EXTERN bool _ISR_Signals_to_thread_executing;
-
-/**
- * The following contains the interrupt service routine nest level.
- * When this variable is zero, a thread is executing.
- */
-SCORE_EXTERN volatile uint32_t _ISR_Nest_level;
-
#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
/**
* The following declares the Vector Table. Application
diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h
new file mode 100644
index 0000000000..09f82ad663
--- /dev/null
+++ b/cpukit/score/include/rtems/score/percpu.h
@@ -0,0 +1,166 @@
+/**
+ * @file rtems/score/percpu.h
+ *
+ * This include file defines the per CPU information required
+ * by RTEMS.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2010.
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_PERCPU_H
+#define _RTEMS_PERCPU_H
+
+#ifdef ASM
+ #include <rtems/asm.h>
+#endif
+
+/**
+ * @defgroup PerCPU RTEMS Per CPU Information
+ *
+ * This defines the per CPU state information required by RTEMS
+ * and the BSP. In an SMP configuration, there will be multiple
+ * instances of this data structure -- one per CPU -- and the
+ * current CPU number will be used as the index.
+ */
+
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASM
+
+/**
+ * This forward defines the Thread Control Block structure.
+ */
+typedef struct Thread_Control_struct Thread_Control;
+
+/**
+ * @brief Per CPU Core Structure
+ *
+ * This structure is used to hold per core state information.
+ */
+typedef struct {
+#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
+ (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ /**
+ * This contains a pointer to the lower range of the interrupt stack for
+ * this CPU. This is the address allocated and freed.
+ */
+ void *interrupt_stack_low;
+
+ /**
+ * This contains a pointer to the interrupt stack pointer for this CPU.
+ * It will be loaded at the beginning on an ISR.
+ */
+ void *interrupt_stack_high;
+#endif
+
+ /**
+ *
+ * This contains the current interrupt nesting level on this
+ * CPU.
+ */
+ uint32_t isr_nest_level;
+
+ /** This is the thread executing on this CPU. */
+ Thread_Control *executing;
+
+ /** This is the heir thread for this this CPU. */
+ Thread_Control *heir;
+
+ /** This is the idle thread for this CPU. */
+ Thread_Control *idle;
+
+ /** This is set to true when this CPU needs to run the dispatcher. */
+ volatile bool dispatch_needed;
+
+} Per_CPU_Control;
+#endif
+
+#ifdef ASM
+
+#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
+ (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ /*
+ * If this CPU target lets RTEMS allocates the interrupt stack, then
+ * we need to have places in the per cpu table to hold them.
+ */
+ #define PER_CPU_INTERRUPT_STACK_LOW 0
+ #define PER_CPU_INTERRUPT_STACK_HIGH (1 * SIZEOF_VOID_P)
+ #define PER_CPU_END_STACK (2 * SIZEOF_VOID_P)
+#else
+ /*
+ * Otherwise, there are no interrupt stack addresses in the per CPU table.
+ */
+ #define PER_CPU_END_STACK 0
+#endif
+
+/*
+ * These are the offsets of the required elements in the per CPU table.
+ */
+#define PER_CPU_ISR_NEST_LEVEL PER_CPU_END_STACK + 0
+#define PER_CPU_EXECUTING PER_CPU_END_STACK + (1 * SIZEOF_VOID_P)
+#define PER_CPU_HEIR PER_CPU_END_STACK + (2 * SIZEOF_VOID_P)
+#define PER_CPU_IDLE PER_CPU_END_STACK + (3 * SIZEOF_VOID_P)
+#define PER_CPU_DISPATCH_NEEDED PER_CPU_END_STACK + (4 * SIZEOF_VOID_P)
+#define ISR_NEST_LEVEL \
+ (SYM(_Per_CPU_Information) + PER_CPU_ISR_NEST_LEVEL)
+#define DISPATCH_NEEDED \
+ (SYM(_Per_CPU_Information) + PER_CPU_DISPATCH_NEEDED)
+
+/*
+ * Do not define these offsets if they are not in the table.
+ */
+#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
+ (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ #define INTERRUPT_STACK_LOW \
+ (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_LOW)
+ #define INTERRUPT_STACK_HIGH \
+ (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_HIGH)
+#endif
+
+#endif
+
+#ifndef ASM
+
+/**
+ * @brief Set of Per CPU Core Information
+ *
+ * This is an array of per CPU core information.
+ */
+extern Per_CPU_Control _Per_CPU_Information;
+
+/*
+ * On an SMP system, these macros dereference the CPU core number.
+ * But on a non-SMP system, these macros are simple references.
+ * Thus when built for non-SMP, there should be no performance penalty.
+ */
+#define _Thread_Heir _Per_CPU_Information.heir
+#define _Thread_Executing _Per_CPU_Information.executing
+#define _Thread_Idle _Per_CPU_Information.idle
+#define _ISR_Nest_level _Per_CPU_Information.isr_nest_level
+#define _CPU_Interrupt_stack_low _Per_CPU_Information.interrupt_stack_low
+#define _CPU_Interrupt_stack_high _Per_CPU_Information.interrupt_stack_high
+#define _Context_Switch_necessary _Per_CPU_Information.dispatch_needed
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 1e05df8ed0..ca4b04fa22 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -24,6 +24,13 @@
*
* This handler encapsulates functionality related to the management of
* threads. This includes the creation, deletion, and scheduling of threads.
+ *
+ * The following variables are maintained as part of the per cpu data
+ * structure.
+ *
+ * + Idle thread pointer
+ * + Executing thread pointer
+ * + Heir thread pointer
*/
/**@{*/
@@ -55,6 +62,7 @@ extern "C" {
typedef uint32_t Thread_CPU_usage_t;
#endif
+#include <rtems/score/percpu.h>
#include <rtems/score/context.h>
#include <rtems/score/cpu.h>
#if defined(RTEMS_MULTIPROCESSING)
@@ -147,10 +155,6 @@ typedef enum {
#endif
} Thread_CPU_budget_algorithms;
-/** This type defines the Thread Control Block structure.
- */
-typedef struct Thread_Control_struct Thread_Control;
-
/** This defines thes the entry point for the thread specific timeslice
* budget management algorithm.
*/
@@ -363,10 +367,6 @@ struct Thread_Control_struct {
/** This field is true if the thread is offered globally */
bool is_global;
#endif
- /** This field is is true if the post task context switch should be
- * executed for this thread at the next context switch.
- */
- bool do_post_task_switch_extension;
/** This field is true if the thread is preemptible. */
bool is_preemptible;
#if __RTEMS_ADA__
@@ -427,12 +427,6 @@ SCORE_EXTERN void *rtems_ada_self;
SCORE_EXTERN Objects_Information _Thread_Internal_information;
/**
- * The following define the thread control pointers used to access
- * and manipulate the idle thread.
- */
-SCORE_EXTERN Thread_Control *_Thread_Idle;
-
-/**
* The following context area contains the context of the "thread"
* which invoked the start multitasking routine. This context is
* restored as the last action of the stop multitasking routine. Thus
@@ -449,12 +443,6 @@ SCORE_EXTERN Context_Control _Thread_BSP_context;
SCORE_EXTERN volatile uint32_t _Thread_Dispatch_disable_level;
/**
- * If this is non-zero, then the post-task switch extension
- * is run regardless of the state of the per thread flag.
- */
-SCORE_EXTERN uint32_t _Thread_Do_post_task_switch_extension;
-
-/**
* The following holds how many user extensions are in the system. This
* is used to determine how many user extension data areas to allocate
* per thread.
@@ -473,20 +461,6 @@ SCORE_EXTERN uint32_t _Thread_Ticks_per_timeslice;
SCORE_EXTERN Chain_Control *_Thread_Ready_chain;
/**
- * The following points to the thread which is currently executing.
- * This thread is implicitly manipulated by numerous directives.
- */
-SCORE_EXTERN Thread_Control *_Thread_Executing;
-
-/**
- * The following points to the highest priority ready thread
- * in the system. Unless the current thread is not preemptibl,
- * then this thread will be context switched to when the next
- * dispatch occurs.
- */
-SCORE_EXTERN Thread_Control *_Thread_Heir;
-
-/**
* The following points to the thread whose floating point
* context is currently loaded.
*/
diff --git a/cpukit/score/include/rtems/system.h b/cpukit/score/include/rtems/system.h
index ad6e77f125..2bb55d7c8e 100644
--- a/cpukit/score/include/rtems/system.h
+++ b/cpukit/score/include/rtems/system.h
@@ -169,6 +169,7 @@ typedef void * proc_ptr;
#include <stdint.h>
#endif
#include <rtems/score/cpu.h> /* processor specific information */
+#include <rtems/score/percpu.h>
#ifndef ASM
/**
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index da6f308f63..617272b28a 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -99,6 +99,10 @@ $(PROJECT_INCLUDE)/rtems/score/object.h: include/rtems/score/object.h $(PROJECT_
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/object.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/object.h
+$(PROJECT_INCLUDE)/rtems/score/percpu.h: include/rtems/score/percpu.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/percpu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/percpu.h
+
$(PROJECT_INCLUDE)/rtems/score/priority.h: include/rtems/score/priority.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/priority.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/priority.h
diff --git a/cpukit/score/src/isr.c b/cpukit/score/src/isr.c
index 0c6956fb19..4925ee9117 100644
--- a/cpukit/score/src/isr.c
+++ b/cpukit/score/src/isr.c
@@ -34,8 +34,6 @@
void _ISR_Handler_initialization( void )
{
- _ISR_Signals_to_thread_executing = false;
-
_ISR_Nest_level = 0;
#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
@@ -64,6 +62,9 @@ void _ISR_Handler_initialization( void )
Configuration.interrupt_stack_size
);
+ _CPU_Interrupt_stack_high = (void *)
+ ((uintptr_t) _CPU_Interrupt_stack_high & ~CPU_STACK_ALIGNMENT);
+
/* Interrupt stack might have to be aligned and/or setup
* in a specific way.
*/
diff --git a/cpukit/score/src/isrthreaddispatch.c b/cpukit/score/src/isrthreaddispatch.c
index 229c1fa70e..d0b499b210 100644
--- a/cpukit/score/src/isrthreaddispatch.c
+++ b/cpukit/score/src/isrthreaddispatch.c
@@ -33,15 +33,6 @@ void _ISR_Thread_dispatch( void )
{
if ( _Context_Switch_necessary ) {
_Thread_Dispatch();
- } else if ( _ISR_Signals_to_thread_executing ) {
- _ISR_Signals_to_thread_executing = false;
- if (
- _Thread_Do_post_task_switch_extension
- || _Thread_Executing->do_post_task_switch_extension
- ) {
- _Thread_Executing->do_post_task_switch_extension = false;
- _API_extensions_Run_postswitch();
- }
}
}
diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c
new file mode 100644
index 0000000000..4c719af6db
--- /dev/null
+++ b/cpukit/score/src/percpu.c
@@ -0,0 +1,29 @@
+/*
+ * COPYRIGHT (c) 1989-2010.
+ * 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.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/config.h>
+#include <string.h>
+
+/*
+ * On single core systems, we can efficiently directly access a single
+ * statically allocated per cpu structure. And the fields are initialized
+ * as individual elements just like it has always been done.
+ */
+Per_CPU_Control _Per_CPU_Information;
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
index cc99bf668b..e96770acf1 100644
--- a/cpukit/score/src/thread.c
+++ b/cpukit/score/src/thread.c
@@ -76,8 +76,6 @@ void _Thread_Handler_initialization(void)
_Thread_Allocated_fp = NULL;
#endif
- _Thread_Do_post_task_switch_extension = 0;
-
_Thread_Maximum_extensions = maximum_extensions;
_Thread_Ticks_per_timeslice = ticks_per_timeslice;
diff --git a/cpukit/score/src/threaddispatch.c b/cpukit/score/src/threaddispatch.c
index e0d0f5cdf7..3d7fe24947 100644
--- a/cpukit/score/src/threaddispatch.c
+++ b/cpukit/score/src/threaddispatch.c
@@ -94,12 +94,26 @@ void _Thread_Dispatch( void )
_Thread_Dispatch_disable_level = 1;
_Context_Switch_necessary = false;
_Thread_Executing = heir;
+
+ /*
+ * When the heir and executing are the same, then we are being
+ * requested to do the post switch dispatching. This is normally
+ * done to dispatch signals.
+ */
+ if ( heir == executing )
+ goto post_switch;
+
+ /*
+ * Since heir and executing are not the same, we need to do a real
+ * context switch.
+ */
#if __RTEMS_ADA__
executing->rtems_ada_self = rtems_ada_self;
rtems_ada_self = heir->rtems_ada_self;
#endif
if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
heir->cpu_time_budget = _Thread_Ticks_per_timeslice;
+
_ISR_Enable( level );
#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
@@ -170,14 +184,10 @@ void _Thread_Dispatch( void )
_ISR_Disable( level );
}
+post_switch:
_Thread_Dispatch_disable_level = 0;
_ISR_Enable( level );
- if ( _Thread_Do_post_task_switch_extension ||
- executing->do_post_task_switch_extension ) {
- executing->do_post_task_switch_extension = false;
- _API_extensions_Run_postswitch();
- }
-
+ _API_extensions_Run_postswitch();
}
diff --git a/cpukit/score/src/threadloadenv.c b/cpukit/score/src/threadloadenv.c
index 6a30adbdde..164db0115a 100644
--- a/cpukit/score/src/threadloadenv.c
+++ b/cpukit/score/src/threadloadenv.c
@@ -58,8 +58,6 @@ void _Thread_Load_environment(
#endif
is_fp = false;
-
- the_thread->do_post_task_switch_extension = false;
the_thread->is_preemptible = the_thread->Start.is_preemptible;
the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
the_thread->budget_callout = the_thread->Start.budget_callout;