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.
This commit is contained in:
Joel Sherrill
2010-06-29 00:34:12 +00:00
parent 6d42b4c60a
commit 11e8bc5f0f
24 changed files with 272 additions and 111 deletions
+19
View File
@@ -1,3 +1,22 @@
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
+3
View File
@@ -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"])
-2
View File
@@ -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.
@@ -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 );
}
@@ -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 );
}
+1 -3
View File
@@ -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;
-8
View File
@@ -190,14 +190,6 @@ int pthread_create(
api->schedpolicy = schedpolicy;
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.
*/
+1 -3
View File
@@ -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;
-1
View File
@@ -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();
}
+1 -3
View File
@@ -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 );
}
-1
View File
@@ -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;
}
}
}
+12 -9
View File
@@ -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 \
+3 -10
View File
@@ -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.
*/
/**@{*/
@@ -40,16 +43,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
+5 -12
View File
@@ -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
+166
View File
@@ -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 */
+8 -34
View File
@@ -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__
@@ -426,12 +426,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
@@ -448,12 +442,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
@@ -472,20 +460,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.
+1
View File
@@ -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
/**
+4
View File
@@ -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
+3 -2
View File
@@ -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.
*/
-9
View File
@@ -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();
}
}
}
+29
View File
@@ -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;
-2
View File
@@ -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;
+16 -6
View File
@@ -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();
}
-2
View File
@@ -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;