forked from Imagelibrary/rtems
2011-05-26 Jennifer Averett <Jennifer.Averett@OARcorp.com>
PR 1796/cpukit * sapi/src/exshutdown.c, score/include/rtems/score/percpu.h, score/include/rtems/score/smp.h, score/src/smp.c, score/src/threaddispatch.c, score/src/threadhandler.c: Added SMP interprocess communications.
This commit is contained in:
@@ -1,3 +1,11 @@
|
|||||||
|
2011-05-26 Jennifer Averett <Jennifer.Averett@OARcorp.com>
|
||||||
|
|
||||||
|
PR 1796/cpukit
|
||||||
|
* sapi/src/exshutdown.c, score/include/rtems/score/percpu.h,
|
||||||
|
score/include/rtems/score/smp.h, score/src/smp.c,
|
||||||
|
score/src/threaddispatch.c, score/src/threadhandler.c: Added SMP
|
||||||
|
interprocess communications.
|
||||||
|
|
||||||
2011-05-24 Ralf Corsépius <ralf.corsepius@rtems.org>
|
2011-05-24 Ralf Corsépius <ralf.corsepius@rtems.org>
|
||||||
|
|
||||||
* score/include/rtems/score/percpu.h,
|
* score/include/rtems/score/percpu.h,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Initialization Manager
|
* Initialization Manager
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 1989-1999.
|
* COPYRIGHT (c) 1989-2011.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
@@ -20,6 +20,10 @@
|
|||||||
#include <rtems/score/thread.h>
|
#include <rtems/score/thread.h>
|
||||||
#include <rtems/score/interr.h>
|
#include <rtems/score/interr.h>
|
||||||
|
|
||||||
|
#if defined(RTEMS_SMP)
|
||||||
|
#include <rtems/score/smp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rtems_shutdown_executive
|
* rtems_shutdown_executive
|
||||||
*
|
*
|
||||||
@@ -37,6 +41,9 @@ void rtems_shutdown_executive(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
if ( _System_state_Is_up( _System_state_Get() ) ) {
|
if ( _System_state_Is_up( _System_state_Get() ) ) {
|
||||||
|
#if defined(RTEMS_SMP)
|
||||||
|
_SMP_Request_other_cores_to_shutdown();
|
||||||
|
#endif
|
||||||
_System_state_Set( SYSTEM_STATE_SHUTDOWN );
|
_System_state_Set( SYSTEM_STATE_SHUTDOWN );
|
||||||
_Thread_Stop_multitasking();
|
_Thread_Stop_multitasking();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,11 +77,17 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
RTEMS_BSP_SMP_CPU_INITIALIZED = 2,
|
RTEMS_BSP_SMP_CPU_INITIALIZED = 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This defines the constant used to indicate that the cpu code has
|
||||||
|
* completed basic initialization and awaits further commands.
|
||||||
|
*/
|
||||||
|
RTEMS_BSP_SMP_CPU_UP = 3,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This defines the constant used to indicate that the cpu code has
|
* This defines the constant used to indicate that the cpu code has
|
||||||
* shut itself down.
|
* shut itself down.
|
||||||
*/
|
*/
|
||||||
RTEMS_BSP_SMP_CPU_SHUTDOWN = 3
|
RTEMS_BSP_SMP_CPU_SHUTDOWN = 4
|
||||||
} bsp_smp_cpu_state;
|
} bsp_smp_cpu_state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -86,6 +86,14 @@ void _SMP_Broadcast_message(
|
|||||||
uint32_t message
|
uint32_t message
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Request Other Cores to Perform First Context Switch
|
||||||
|
*
|
||||||
|
* Send message to other cores requesting them to perform
|
||||||
|
* their first context switch operation.
|
||||||
|
*/
|
||||||
|
void _SMP_Request_other_cores_to_perform_first_context_switch(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Request Dispatch on Other Cores
|
* @brief Request Dispatch on Other Cores
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,30 +19,35 @@
|
|||||||
#include <rtems/score/thread.h>
|
#include <rtems/score/thread.h>
|
||||||
|
|
||||||
#if defined(RTEMS_SMP)
|
#if defined(RTEMS_SMP)
|
||||||
#define SMP_DEBUG
|
#define RTEMS_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SMP_DEBUG)
|
#if defined(RTEMS_DEBUG)
|
||||||
#include <rtems/bspIo.h>
|
#include <rtems/bspIo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process request to switch to the first task on a secondary core.
|
||||||
|
*/
|
||||||
void rtems_smp_run_first_task(int cpu)
|
void rtems_smp_run_first_task(int cpu)
|
||||||
{
|
{
|
||||||
Thread_Control *heir;
|
Thread_Control *heir;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This CPU has an heir thread so we need to dispatch it.
|
* The Scheduler will have selected the heir thread for each CPU core.
|
||||||
|
* Now we have been requested to perform the first context switch. So
|
||||||
|
* force a switch to the designated heir and make it executing on
|
||||||
|
* THIS core.
|
||||||
*/
|
*/
|
||||||
heir = _Thread_Heir;
|
heir = _Thread_Heir;
|
||||||
|
|
||||||
/*
|
|
||||||
* This is definitely a hack until we have SMP scheduling. Since there
|
|
||||||
* is only one executing and heir right now, we have to fake this out.
|
|
||||||
*/
|
|
||||||
_Thread_Dispatch_set_disable_level(1);
|
|
||||||
_Thread_Executing = heir;
|
_Thread_Executing = heir;
|
||||||
|
|
||||||
_CPU_Context_switch_to_first_task_smp( &heir->Registers );
|
_CPU_Context_switch_to_first_task_smp( &heir->Registers );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process request to initialize this secondary core.
|
||||||
|
*/
|
||||||
void rtems_smp_secondary_cpu_initialize(void)
|
void rtems_smp_secondary_cpu_initialize(void)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
@@ -51,7 +56,7 @@ void rtems_smp_secondary_cpu_initialize(void)
|
|||||||
|
|
||||||
bsp_smp_secondary_cpu_initialize(cpu);
|
bsp_smp_secondary_cpu_initialize(cpu);
|
||||||
|
|
||||||
#if defined(SMP_DEBUG)
|
#if defined(RTEMS_DEBUG)
|
||||||
printk( "Made it to %d -- ", cpu );
|
printk( "Made it to %d -- ", cpu );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -63,15 +68,26 @@ void rtems_smp_secondary_cpu_initialize(void)
|
|||||||
_Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_INITIALIZED;
|
_Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_INITIALIZED;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HACK: Should not have to enable interrupts in real system here.
|
* With this secondary core out of reset, we can wait for the
|
||||||
* It should happen as part of switching to the first task.
|
* request to switch to the first task.
|
||||||
|
*
|
||||||
|
* XXX When SMP ISR code is complete, do we want interrupts on
|
||||||
|
* XXX or off at this point?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_Per_CPU_Information[cpu].isr_nest_level = 1;
|
|
||||||
_ISR_Set_level( 0 );
|
_ISR_Set_level( 0 );
|
||||||
while(1) ;
|
while(1) {
|
||||||
|
bsp_smp_wait_for(
|
||||||
|
(volatile unsigned int *)&_Per_CPU_Information[cpu].message,
|
||||||
|
RTEMS_BSP_SMP_FIRST_TASK,
|
||||||
|
10000
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process an interrupt processor interrupt which indicates a request
|
||||||
|
* from another core.
|
||||||
|
*/
|
||||||
void rtems_smp_process_interrupt(void)
|
void rtems_smp_process_interrupt(void)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
@@ -80,31 +96,53 @@ void rtems_smp_process_interrupt(void)
|
|||||||
|
|
||||||
cpu = bsp_smp_processor_id();
|
cpu = bsp_smp_processor_id();
|
||||||
|
|
||||||
level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
|
level = _SMP_lock_Simple_Spinlock_Obtain( &_Per_CPU_Information[cpu].lock );
|
||||||
message = _Per_CPU_Information[cpu].message;
|
message = _Per_CPU_Information[cpu].message;
|
||||||
_Per_CPU_Information[cpu].message &= ~message;
|
|
||||||
_SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
|
|
||||||
|
|
||||||
#if defined(SMP_DEBUG)
|
#if defined(RTEMS_DEBUG)
|
||||||
{
|
{
|
||||||
void *sp = __builtin_frame_address(0);
|
void *sp = __builtin_frame_address(0);
|
||||||
if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) )
|
if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) ) {
|
||||||
printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", cpu, message, sp );
|
printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", cpu, message, sp );
|
||||||
printk( "Dispatch level %d\n", _Thread_Dispatch_disable_level );
|
if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY )
|
||||||
|
printk( "context switch necessary\n" );
|
||||||
|
if ( message & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
|
||||||
|
printk( "signal to self\n" );
|
||||||
|
if ( message & RTEMS_BSP_SMP_SHUTDOWN )
|
||||||
|
printk( "shutdown\n" );
|
||||||
|
if ( message & RTEMS_BSP_SMP_FIRST_TASK )
|
||||||
|
printk( "switch to first task\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
printk( "Dispatch level %d\n", _Thread_Dispatch_get_disable_level() );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
|
if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
|
||||||
|
/*
|
||||||
|
* XXX Thread dispatch disable level at this point will have to be
|
||||||
|
* XXX revisited when Interrupts on SMP is addressed.
|
||||||
|
*/
|
||||||
|
_Thread_Dispatch_disable_level--; /* undo ISR code */
|
||||||
_Per_CPU_Information[cpu].isr_nest_level = 0;
|
_Per_CPU_Information[cpu].isr_nest_level = 0;
|
||||||
_Per_CPU_Information[cpu].message = 0;
|
_Per_CPU_Information[cpu].message &= ~message;
|
||||||
_Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_INITIALIZED;
|
_Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_UP;
|
||||||
|
|
||||||
|
_SMP_lock_Simple_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
|
||||||
|
_Thread_Disable_dispatch();
|
||||||
rtems_smp_run_first_task(cpu);
|
rtems_smp_run_first_task(cpu);
|
||||||
/* does not return */
|
/* does not return */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
|
if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
|
||||||
ISR_Level level;
|
/*
|
||||||
_Thread_Dispatch_set_disable_level(0);
|
* XXX Thread dispatch disable level at this point will have to be
|
||||||
|
* XXX revisited when Interrupts on SMP is addressed.
|
||||||
|
*/
|
||||||
|
_Per_CPU_Information[cpu].message &= ~message;
|
||||||
|
_SMP_lock_Simple_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
|
||||||
|
|
||||||
|
_Thread_Dispatch_disable_level--; /* undo ISR code */
|
||||||
_Per_CPU_Information[cpu].isr_nest_level = 0;
|
_Per_CPU_Information[cpu].isr_nest_level = 0;
|
||||||
_Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_SHUTDOWN;
|
_Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_SHUTDOWN;
|
||||||
_ISR_Disable( level );
|
_ISR_Disable( level );
|
||||||
@@ -114,12 +152,22 @@ void rtems_smp_process_interrupt(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY ) {
|
if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY ) {
|
||||||
printk( "switch needed\n" );
|
#if defined(RTEMS_DEBUG)
|
||||||
_Per_CPU_Information[cpu].dispatch_necessary = true;
|
printk( "switch needed\n" );
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* XXX Thread dispatch disable level at this point will have to be
|
||||||
|
* XXX revisited when Interrupts on SMP is addressed.
|
||||||
|
*/
|
||||||
|
_Per_CPU_Information[cpu].message &= ~message;
|
||||||
|
_SMP_lock_Simple_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtems_smp_send_message(
|
/*
|
||||||
|
* Send an interrupt processor request to another cpu.
|
||||||
|
*/
|
||||||
|
void _SMP_Send_message(
|
||||||
int cpu,
|
int cpu,
|
||||||
uint32_t message
|
uint32_t message
|
||||||
)
|
)
|
||||||
@@ -132,7 +180,10 @@ void rtems_smp_send_message(
|
|||||||
bsp_smp_interrupt_cpu( cpu );
|
bsp_smp_interrupt_cpu( cpu );
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtems_smp_broadcast_message(
|
/*
|
||||||
|
* Send interrupt processor request to all other nodes
|
||||||
|
*/
|
||||||
|
void _SMP_Broadcast_message(
|
||||||
uint32_t message
|
uint32_t message
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -151,4 +202,82 @@ void rtems_smp_broadcast_message(
|
|||||||
}
|
}
|
||||||
bsp_smp_broadcast_interrupt();
|
bsp_smp_broadcast_interrupt();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
/*
|
||||||
|
* Send interrupt processor requests to perform first context switch
|
||||||
|
*/
|
||||||
|
void _SMP_Request_other_cores_to_perform_first_context_switch(void)
|
||||||
|
{
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for (cpu=1 ; cpu < _SMP_Processor_count ; cpu++ ) {
|
||||||
|
_SMP_Send_message( cpu, RTEMS_BSP_SMP_FIRST_TASK );
|
||||||
|
while (_Per_CPU_Information[cpu].state != RTEMS_BSP_SMP_CPU_UP ) {
|
||||||
|
bsp_smp_wait_for(
|
||||||
|
(volatile unsigned int *)&_Per_CPU_Information[cpu].state,
|
||||||
|
RTEMS_BSP_SMP_CPU_UP,
|
||||||
|
10000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send message to other cores requesting them to perform
|
||||||
|
* a thread dispatch operation.
|
||||||
|
*/
|
||||||
|
void _SMP_Request_other_cores_to_dispatch(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
cpu = bsp_smp_processor_id();
|
||||||
|
|
||||||
|
if ( !_System_state_Is_up (_System_state_Current) )
|
||||||
|
return;
|
||||||
|
for (i=1 ; i < _SMP_Processor_count ; i++ ) {
|
||||||
|
if ( cpu == i )
|
||||||
|
continue;
|
||||||
|
if ( _Per_CPU_Information[i].state != RTEMS_BSP_SMP_CPU_UP )
|
||||||
|
continue;
|
||||||
|
if ( !_Per_CPU_Information[i].dispatch_necessary )
|
||||||
|
continue;
|
||||||
|
_SMP_Send_message( i, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
|
||||||
|
bsp_smp_wait_for(
|
||||||
|
(volatile unsigned int *)&_Per_CPU_Information[i].message,
|
||||||
|
0,
|
||||||
|
10000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send message to other cores requesting them to shutdown.
|
||||||
|
*/
|
||||||
|
void _SMP_Request_other_cores_to_shutdown(void)
|
||||||
|
{
|
||||||
|
bool allDown;
|
||||||
|
int ncpus;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
ncpus = _SMP_Processor_count;
|
||||||
|
|
||||||
|
_SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
|
||||||
|
|
||||||
|
allDown = true;
|
||||||
|
for (cpu=1 ; cpu<ncpus ; cpu++ ) {
|
||||||
|
bsp_smp_wait_for(
|
||||||
|
(unsigned int *)&_Per_CPU_Information[cpu].state,
|
||||||
|
RTEMS_BSP_SMP_CPU_SHUTDOWN,
|
||||||
|
10000
|
||||||
|
);
|
||||||
|
if ( _Per_CPU_Information[cpu].state != RTEMS_BSP_SMP_CPU_SHUTDOWN )
|
||||||
|
allDown = false;
|
||||||
|
}
|
||||||
|
if ( !allDown )
|
||||||
|
printk( "All CPUs not successfully shutdown -- timed out\n" );
|
||||||
|
#if (RTEMS_DEBUG)
|
||||||
|
else
|
||||||
|
printk( "All CPUs shutdown successfully\n" );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@
|
|||||||
#include <rtems/score/timestamp.h>
|
#include <rtems/score/timestamp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(RTEMS_SMP)
|
||||||
|
#include <rtems/score/smp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _Thread_Dispatch
|
* _Thread_Dispatch
|
||||||
*
|
*
|
||||||
@@ -47,18 +51,28 @@
|
|||||||
* dispatch thread
|
* dispatch thread
|
||||||
* no dispatch thread
|
* no dispatch thread
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void _Thread_Dispatch( void )
|
void _Thread_Dispatch( void )
|
||||||
{
|
{
|
||||||
Thread_Control *executing;
|
Thread_Control *executing;
|
||||||
Thread_Control *heir;
|
Thread_Control *heir;
|
||||||
ISR_Level level;
|
ISR_Level level;
|
||||||
|
|
||||||
|
_Thread_Disable_dispatch();
|
||||||
|
#if defined(RTEMS_SMP)
|
||||||
|
/*
|
||||||
|
* If necessary, send dispatch request to other cores.
|
||||||
|
*/
|
||||||
|
_SMP_Request_other_cores_to_dispatch();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now determine if we need to perform a dispatch on the current CPU.
|
||||||
|
*/
|
||||||
executing = _Thread_Executing;
|
executing = _Thread_Executing;
|
||||||
_ISR_Disable( level );
|
_ISR_Disable( level );
|
||||||
while ( _Thread_Dispatch_necessary == true ) {
|
while ( _Thread_Dispatch_necessary == true ) {
|
||||||
|
|
||||||
heir = _Thread_Heir;
|
heir = _Thread_Heir;
|
||||||
_Thread_Dispatch_set_disable_level( 1 );
|
|
||||||
_Thread_Dispatch_necessary = false;
|
_Thread_Dispatch_necessary = false;
|
||||||
_Thread_Executing = heir;
|
_Thread_Executing = heir;
|
||||||
|
|
||||||
@@ -96,7 +110,10 @@ void _Thread_Dispatch( void )
|
|||||||
_Thread_Time_of_last_context_switch = uptime;
|
_Thread_Time_of_last_context_switch = uptime;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
heir->cpu_time_used++;
|
{
|
||||||
|
TOD_Get_uptime( &_Thread_Time_of_last_context_switch );
|
||||||
|
heir->cpu_time_used++;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Thread Handler
|
* Thread Handler
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 1989-2009.
|
* COPYRIGHT (c) 1989-2011.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
@@ -51,6 +51,11 @@
|
|||||||
#define EXECUTE_GLOBAL_CONSTRUCTORS
|
#define EXECUTE_GLOBAL_CONSTRUCTORS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(RTEMS_SMP)
|
||||||
|
#include <rtems/score/smp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*PAGE
|
/*PAGE
|
||||||
*
|
*
|
||||||
* _Thread_Handler
|
* _Thread_Handler
|
||||||
@@ -138,8 +143,15 @@ void _Thread_Handler( void )
|
|||||||
*/
|
*/
|
||||||
if (!doneCons) /* && (volatile void *)_init) */ {
|
if (!doneCons) /* && (volatile void *)_init) */ {
|
||||||
INIT_NAME ();
|
INIT_NAME ();
|
||||||
|
|
||||||
|
#if defined(RTEMS_SMP)
|
||||||
|
_Thread_Disable_dispatch();
|
||||||
|
_SMP_Request_other_cores_to_perform_first_context_switch();
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
|
if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
|
||||||
executing->Wait.return_argument =
|
executing->Wait.return_argument =
|
||||||
|
|||||||
Reference in New Issue
Block a user