forked from Imagelibrary/rtems
Removed the internal thread objects and dispersed its contents to
the thread handler (IDLE), MPCI object (SYSI now MP Receive) and initialize_executive_early (IO initialization). The SYSI task no longer exists in a single processor configuration. This reduces single processor Workspace requirements by a TCB and a stack which is often larger than the minimum stack size. Moving the IO initialization plus accompanying BSP hooks eliminated an initialization ordering problem in which a global task could be created before the MPCI was initialized.
This commit is contained in:
@@ -29,6 +29,17 @@ extern "C" {
|
||||
#include <rtems/score/watchdog.h>
|
||||
#include <rtems/score/coresem.h>
|
||||
|
||||
/*
|
||||
* The following constants define the stack size requirements for
|
||||
* the system threads.
|
||||
*/
|
||||
|
||||
#define MPCI_RECEIVE_SERVER_STACK_SIZE \
|
||||
( STACK_MINIMUM_SIZE + \
|
||||
CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK + \
|
||||
_CPU_Table.extra_mpci_receive_server_stack \
|
||||
)
|
||||
|
||||
/*
|
||||
* The following defines the node number used when a broadcast is desired.
|
||||
*/
|
||||
@@ -91,6 +102,27 @@ typedef struct {
|
||||
|
||||
typedef void (*MPCI_Packet_processor)( MP_packet_Prefix * );
|
||||
|
||||
/*
|
||||
* The following enumerated type defines the list of
|
||||
* internal MP operations.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MPCI_PACKETS_SYSTEM_VERIFY = 0
|
||||
} MPCI_Internal_Remote_operations;
|
||||
|
||||
/*
|
||||
* The following data structure defines the packet used to perform
|
||||
* remote event operations.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
MP_packet_Prefix Prefix;
|
||||
MPCI_Internal_Remote_operations operation;
|
||||
unsigned32 maximum_nodes;
|
||||
unsigned32 maximum_global_objects;
|
||||
} MPCI_Internal_packet;
|
||||
|
||||
/*
|
||||
* This is the core semaphore which the MPCI Receive Server blocks on.
|
||||
*/
|
||||
@@ -136,6 +168,16 @@ void _MPCI_Handler_initialization(
|
||||
unsigned32 timeout_status
|
||||
);
|
||||
|
||||
/*
|
||||
* _MPCI_Create_server
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine creates the packet receive server used in MP systems.
|
||||
*/
|
||||
|
||||
void _MPCI_Create_server( void );
|
||||
|
||||
/*
|
||||
* _MPCI_Initialization
|
||||
*
|
||||
@@ -259,7 +301,9 @@ Thread_Control *_MPCI_Process_response (
|
||||
*
|
||||
*/
|
||||
|
||||
void _MPCI_Receive_server( void );
|
||||
Thread _MPCI_Receive_server(
|
||||
unsigned32 ignored
|
||||
);
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
@@ -272,6 +316,93 @@ void _MPCI_Receive_server( void );
|
||||
|
||||
void _MPCI_Announce ( void );
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_process_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs a remote procedure call so that a
|
||||
* process operation can be performed on another node.
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Send_process_packet (
|
||||
MPCI_Internal_Remote_operations operation
|
||||
);
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_request_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs a remote procedure call so that a
|
||||
* directive operation can be initiated on another node.
|
||||
*
|
||||
* This routine is not needed since there are no request
|
||||
* packets to be sent by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_response_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs a remote procedure call so that a
|
||||
* directive can be performed on another node.
|
||||
*
|
||||
* This routine is not needed since there are no response
|
||||
* packets to be sent by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* _MPCI_Internal_packets_Process_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs the actions specific to this package for
|
||||
* the request from another node.
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Process_packet (
|
||||
MP_packet_Prefix *the_packet_prefix
|
||||
);
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_object_was_deleted
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is invoked indirectly by the thread queue
|
||||
* when a proxy has been removed from the thread queue and
|
||||
* the remote node must be informed of this.
|
||||
*
|
||||
* This routine is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_extract_proxy
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is invoked when a task is deleted and it
|
||||
* has a proxy which must be removed from a thread queue and
|
||||
* the remote node must be informed of this.
|
||||
*
|
||||
* This routine is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Get_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is used to obtain a internal threads mp packet.
|
||||
*/
|
||||
|
||||
MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MP_PACKET_INTERNAL_THREADS = 0,
|
||||
MP_PACKET_MPCI_INTERNAL = 0,
|
||||
MP_PACKET_TASKS = 1,
|
||||
MP_PACKET_MESSAGE_QUEUE = 2,
|
||||
MP_PACKET_SEMAPHORE = 3,
|
||||
@@ -48,7 +48,7 @@ typedef enum {
|
||||
MP_PACKET_SIGNAL = 7
|
||||
} MP_packet_Classes;
|
||||
|
||||
#define MP_PACKET_CLASSES_FIRST MP_PACKET_INTERNAL_THREADS
|
||||
#define MP_PACKET_CLASSES_FIRST MP_PACKET_MPCI_INTERNAL
|
||||
#define MP_PACKET_CLASSES_LAST MP_PACKET_SIGNAL
|
||||
|
||||
/*
|
||||
|
||||
@@ -100,7 +100,7 @@ typedef enum {
|
||||
|
||||
#define OBJECTS_CLASSES_FIRST OBJECTS_NO_CLASS
|
||||
#define OBJECTS_CLASSES_LAST OBJECTS_POSIX_CONDITION_VARIABLES
|
||||
#define OBJECTS_CLASSES_FIRST_THREAD_CLASS OBJECTS_INTERNAL_THREADS
|
||||
#define OBJECTS_CLASSES_FIRST_THREAD_CLASS OBJECTS_MPCI_PACKETS
|
||||
#define OBJECTS_CLASSES_LAST_THREAD_CLASS OBJECTS_POSIX_THREADS
|
||||
|
||||
/*
|
||||
|
||||
@@ -31,7 +31,7 @@ extern "C" {
|
||||
typedef enum {
|
||||
SYSTEM_STATE_BEFORE_INITIALIZATION, /* start -> end of 1st init part */
|
||||
SYSTEM_STATE_BEFORE_MULTITASKING, /* end of 1st -> beginning of 2nd */
|
||||
SYSTEM_STATE_BEGIN_MULTITASKING, /* beginning of 2nd -> end of SYSI */
|
||||
SYSTEM_STATE_BEGIN_MULTITASKING, /* just before multitasking starts */
|
||||
SYSTEM_STATE_UP, /* normal operation */
|
||||
SYSTEM_STATE_FAILED /* fatal error occurred */
|
||||
} System_state_Codes;
|
||||
|
||||
@@ -160,6 +160,28 @@ typedef struct {
|
||||
void **extensions;
|
||||
} Thread_Control;
|
||||
|
||||
/*
|
||||
* The following constants define the stack size requirements for
|
||||
* the idle thread.
|
||||
*/
|
||||
|
||||
|
||||
#define THREAD_IDLE_STACK_SIZE STACK_MINIMUM_SIZE
|
||||
|
||||
/*
|
||||
* The following defines the information control block used to
|
||||
* manage this class of objects.
|
||||
*/
|
||||
|
||||
EXTERN Objects_Information _Thread_Internal_information;
|
||||
|
||||
/*
|
||||
* The following define the thread control pointers used to access
|
||||
* and manipulate the idle thread.
|
||||
*/
|
||||
|
||||
EXTERN Thread_Control *_Thread_Idle;
|
||||
|
||||
/*
|
||||
* The following context area contains the context of the "thread"
|
||||
* which invoked the start multitasking routine. This context is
|
||||
@@ -237,6 +259,18 @@ void _Thread_Handler_initialization (
|
||||
unsigned32 maximum_proxies
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Create_idle
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine creates the idle thread.
|
||||
*
|
||||
* WARNING!! No thread should be created before this one.
|
||||
*/
|
||||
|
||||
void _Thread_Create_idle( void );
|
||||
|
||||
/*
|
||||
* _Thread_Start_multitasking
|
||||
*
|
||||
@@ -756,6 +790,42 @@ STATIC INLINE boolean _Thread_Is_proxy_blocking (
|
||||
unsigned32 code
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Internal_allocate
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine allocates an internal thread.
|
||||
*/
|
||||
|
||||
STATIC INLINE Thread_Control *_Thread_Internal_allocate( void );
|
||||
|
||||
/*
|
||||
* _Thread_Internal_free
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine frees an internal thread.
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Thread_Internal_free (
|
||||
Thread_Control *the_task
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Idle_body
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is the body of the system idle thread.
|
||||
*/
|
||||
|
||||
#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
|
||||
Thread _Thread_Idle_body(
|
||||
unsigned32 ignored
|
||||
);
|
||||
#endif
|
||||
|
||||
#include <rtems/score/thread.inl>
|
||||
#include <rtems/score/threadmp.h>
|
||||
|
||||
|
||||
@@ -29,6 +29,17 @@ extern "C" {
|
||||
#include <rtems/score/watchdog.h>
|
||||
#include <rtems/score/coresem.h>
|
||||
|
||||
/*
|
||||
* The following constants define the stack size requirements for
|
||||
* the system threads.
|
||||
*/
|
||||
|
||||
#define MPCI_RECEIVE_SERVER_STACK_SIZE \
|
||||
( STACK_MINIMUM_SIZE + \
|
||||
CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK + \
|
||||
_CPU_Table.extra_mpci_receive_server_stack \
|
||||
)
|
||||
|
||||
/*
|
||||
* The following defines the node number used when a broadcast is desired.
|
||||
*/
|
||||
@@ -91,6 +102,27 @@ typedef struct {
|
||||
|
||||
typedef void (*MPCI_Packet_processor)( MP_packet_Prefix * );
|
||||
|
||||
/*
|
||||
* The following enumerated type defines the list of
|
||||
* internal MP operations.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MPCI_PACKETS_SYSTEM_VERIFY = 0
|
||||
} MPCI_Internal_Remote_operations;
|
||||
|
||||
/*
|
||||
* The following data structure defines the packet used to perform
|
||||
* remote event operations.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
MP_packet_Prefix Prefix;
|
||||
MPCI_Internal_Remote_operations operation;
|
||||
unsigned32 maximum_nodes;
|
||||
unsigned32 maximum_global_objects;
|
||||
} MPCI_Internal_packet;
|
||||
|
||||
/*
|
||||
* This is the core semaphore which the MPCI Receive Server blocks on.
|
||||
*/
|
||||
@@ -136,6 +168,16 @@ void _MPCI_Handler_initialization(
|
||||
unsigned32 timeout_status
|
||||
);
|
||||
|
||||
/*
|
||||
* _MPCI_Create_server
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine creates the packet receive server used in MP systems.
|
||||
*/
|
||||
|
||||
void _MPCI_Create_server( void );
|
||||
|
||||
/*
|
||||
* _MPCI_Initialization
|
||||
*
|
||||
@@ -259,7 +301,9 @@ Thread_Control *_MPCI_Process_response (
|
||||
*
|
||||
*/
|
||||
|
||||
void _MPCI_Receive_server( void );
|
||||
Thread _MPCI_Receive_server(
|
||||
unsigned32 ignored
|
||||
);
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
@@ -272,6 +316,93 @@ void _MPCI_Receive_server( void );
|
||||
|
||||
void _MPCI_Announce ( void );
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_process_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs a remote procedure call so that a
|
||||
* process operation can be performed on another node.
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Send_process_packet (
|
||||
MPCI_Internal_Remote_operations operation
|
||||
);
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_request_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs a remote procedure call so that a
|
||||
* directive operation can be initiated on another node.
|
||||
*
|
||||
* This routine is not needed since there are no request
|
||||
* packets to be sent by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_response_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs a remote procedure call so that a
|
||||
* directive can be performed on another node.
|
||||
*
|
||||
* This routine is not needed since there are no response
|
||||
* packets to be sent by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* _MPCI_Internal_packets_Process_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs the actions specific to this package for
|
||||
* the request from another node.
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Process_packet (
|
||||
MP_packet_Prefix *the_packet_prefix
|
||||
);
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_object_was_deleted
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is invoked indirectly by the thread queue
|
||||
* when a proxy has been removed from the thread queue and
|
||||
* the remote node must be informed of this.
|
||||
*
|
||||
* This routine is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_extract_proxy
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is invoked when a task is deleted and it
|
||||
* has a proxy which must be removed from a thread queue and
|
||||
* the remote node must be informed of this.
|
||||
*
|
||||
* This routine is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Get_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is used to obtain a internal threads mp packet.
|
||||
*/
|
||||
|
||||
MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MP_PACKET_INTERNAL_THREADS = 0,
|
||||
MP_PACKET_MPCI_INTERNAL = 0,
|
||||
MP_PACKET_TASKS = 1,
|
||||
MP_PACKET_MESSAGE_QUEUE = 2,
|
||||
MP_PACKET_SEMAPHORE = 3,
|
||||
@@ -48,7 +48,7 @@ typedef enum {
|
||||
MP_PACKET_SIGNAL = 7
|
||||
} MP_packet_Classes;
|
||||
|
||||
#define MP_PACKET_CLASSES_FIRST MP_PACKET_INTERNAL_THREADS
|
||||
#define MP_PACKET_CLASSES_FIRST MP_PACKET_MPCI_INTERNAL
|
||||
#define MP_PACKET_CLASSES_LAST MP_PACKET_SIGNAL
|
||||
|
||||
/*
|
||||
|
||||
@@ -100,7 +100,7 @@ typedef enum {
|
||||
|
||||
#define OBJECTS_CLASSES_FIRST OBJECTS_NO_CLASS
|
||||
#define OBJECTS_CLASSES_LAST OBJECTS_POSIX_CONDITION_VARIABLES
|
||||
#define OBJECTS_CLASSES_FIRST_THREAD_CLASS OBJECTS_INTERNAL_THREADS
|
||||
#define OBJECTS_CLASSES_FIRST_THREAD_CLASS OBJECTS_MPCI_PACKETS
|
||||
#define OBJECTS_CLASSES_LAST_THREAD_CLASS OBJECTS_POSIX_THREADS
|
||||
|
||||
/*
|
||||
|
||||
@@ -31,7 +31,7 @@ extern "C" {
|
||||
typedef enum {
|
||||
SYSTEM_STATE_BEFORE_INITIALIZATION, /* start -> end of 1st init part */
|
||||
SYSTEM_STATE_BEFORE_MULTITASKING, /* end of 1st -> beginning of 2nd */
|
||||
SYSTEM_STATE_BEGIN_MULTITASKING, /* beginning of 2nd -> end of SYSI */
|
||||
SYSTEM_STATE_BEGIN_MULTITASKING, /* just before multitasking starts */
|
||||
SYSTEM_STATE_UP, /* normal operation */
|
||||
SYSTEM_STATE_FAILED /* fatal error occurred */
|
||||
} System_state_Codes;
|
||||
|
||||
@@ -160,6 +160,28 @@ typedef struct {
|
||||
void **extensions;
|
||||
} Thread_Control;
|
||||
|
||||
/*
|
||||
* The following constants define the stack size requirements for
|
||||
* the idle thread.
|
||||
*/
|
||||
|
||||
|
||||
#define THREAD_IDLE_STACK_SIZE STACK_MINIMUM_SIZE
|
||||
|
||||
/*
|
||||
* The following defines the information control block used to
|
||||
* manage this class of objects.
|
||||
*/
|
||||
|
||||
EXTERN Objects_Information _Thread_Internal_information;
|
||||
|
||||
/*
|
||||
* The following define the thread control pointers used to access
|
||||
* and manipulate the idle thread.
|
||||
*/
|
||||
|
||||
EXTERN Thread_Control *_Thread_Idle;
|
||||
|
||||
/*
|
||||
* The following context area contains the context of the "thread"
|
||||
* which invoked the start multitasking routine. This context is
|
||||
@@ -237,6 +259,18 @@ void _Thread_Handler_initialization (
|
||||
unsigned32 maximum_proxies
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Create_idle
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine creates the idle thread.
|
||||
*
|
||||
* WARNING!! No thread should be created before this one.
|
||||
*/
|
||||
|
||||
void _Thread_Create_idle( void );
|
||||
|
||||
/*
|
||||
* _Thread_Start_multitasking
|
||||
*
|
||||
@@ -756,6 +790,42 @@ STATIC INLINE boolean _Thread_Is_proxy_blocking (
|
||||
unsigned32 code
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Internal_allocate
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine allocates an internal thread.
|
||||
*/
|
||||
|
||||
STATIC INLINE Thread_Control *_Thread_Internal_allocate( void );
|
||||
|
||||
/*
|
||||
* _Thread_Internal_free
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine frees an internal thread.
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Thread_Internal_free (
|
||||
Thread_Control *the_task
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Idle_body
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is the body of the system idle thread.
|
||||
*/
|
||||
|
||||
#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
|
||||
Thread _Thread_Idle_body(
|
||||
unsigned32 ignored
|
||||
);
|
||||
#endif
|
||||
|
||||
#include <rtems/score/thread.inl>
|
||||
#include <rtems/score/threadmp.h>
|
||||
|
||||
|
||||
@@ -283,5 +283,29 @@ STATIC INLINE boolean _Thread_Is_proxy_blocking (
|
||||
return (code == THREAD_STATUS_PROXY_BLOCKING);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Internal_allocate
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE Thread_Control *_Thread_Internal_allocate( void )
|
||||
{
|
||||
return (Thread_Control *) _Objects_Allocate( &_Thread_Internal_information );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Internal_free
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Thread_Internal_free (
|
||||
Thread_Control *the_task
|
||||
)
|
||||
{
|
||||
_Objects_Free( &_Thread_Internal_information, &the_task->Object );
|
||||
}
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
|
||||
@@ -283,5 +283,29 @@ STATIC INLINE boolean _Thread_Is_proxy_blocking (
|
||||
return (code == THREAD_STATUS_PROXY_BLOCKING);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Internal_allocate
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE Thread_Control *_Thread_Internal_allocate( void )
|
||||
{
|
||||
return (Thread_Control *) _Objects_Allocate( &_Thread_Internal_information );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Internal_free
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Thread_Internal_free (
|
||||
Thread_Control *the_task
|
||||
)
|
||||
{
|
||||
_Objects_Free( &_Thread_Internal_information, &the_task->Object );
|
||||
}
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
|
||||
@@ -197,5 +197,21 @@ void _Thread_Enable_dispatch( void );
|
||||
#define _Thread_Is_proxy_blocking( _code ) \
|
||||
( (_code) == THREAD_STATUS_PROXY_BLOCKING )
|
||||
|
||||
/*
|
||||
* _Thread_Internal_allocate
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Thread_Internal_allocate() \
|
||||
((Thread_Control *) _Objects_Allocate( &_Thread_Internal_information ))
|
||||
|
||||
/*
|
||||
* _Thread_Internal_free
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Thread_Internal_free( _the_task ) \
|
||||
_Objects_Free( &_Thread_Internal_information, &(_the_task)->Object )
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
|
||||
@@ -197,5 +197,21 @@ void _Thread_Enable_dispatch( void );
|
||||
#define _Thread_Is_proxy_blocking( _code ) \
|
||||
( (_code) == THREAD_STATUS_PROXY_BLOCKING )
|
||||
|
||||
/*
|
||||
* _Thread_Internal_allocate
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Thread_Internal_allocate() \
|
||||
((Thread_Control *) _Objects_Allocate( &_Thread_Internal_information ))
|
||||
|
||||
/*
|
||||
* _Thread_Internal_free
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Thread_Internal_free( _the_task ) \
|
||||
_Objects_Free( &_Thread_Internal_information, &(_the_task)->Object )
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
|
||||
@@ -50,6 +50,22 @@ void _MPCI_Handler_initialization(
|
||||
|
||||
_MPCI_table = users_mpci_table;
|
||||
|
||||
if ( !_System_state_Is_multiprocessing )
|
||||
return;
|
||||
|
||||
/*
|
||||
* Register the MP Process Packet routine.
|
||||
*/
|
||||
|
||||
_MPCI_Register_packet_processor(
|
||||
MP_PACKET_MPCI_INTERNAL,
|
||||
_MPCI_Internal_packets_Process_packet
|
||||
);
|
||||
|
||||
/*
|
||||
* Create the counting semaphore used by the MPCI Receive Server.
|
||||
*/
|
||||
|
||||
attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
|
||||
|
||||
_CORE_semaphore_Initialize(
|
||||
@@ -70,6 +86,49 @@ void _MPCI_Handler_initialization(
|
||||
);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Create_server
|
||||
*
|
||||
* This subprogram creates the MPCI receive server.
|
||||
*/
|
||||
|
||||
char *_MPCI_Internal_name = "MPCI";
|
||||
|
||||
void _MPCI_Create_server( void )
|
||||
{
|
||||
|
||||
if ( !_System_state_Is_multiprocessing )
|
||||
return;
|
||||
|
||||
/*
|
||||
* Initialize the MPCI Receive Server
|
||||
*/
|
||||
|
||||
_MPCI_Receive_server_tcb = _Thread_Internal_allocate();
|
||||
|
||||
_Thread_Initialize(
|
||||
&_Thread_Internal_information,
|
||||
_MPCI_Receive_server_tcb,
|
||||
NULL, /* allocate the stack */
|
||||
MPCI_RECEIVE_SERVER_STACK_SIZE,
|
||||
CPU_ALL_TASKS_ARE_FP,
|
||||
PRIORITY_MINIMUM,
|
||||
FALSE, /* no preempt */
|
||||
FALSE, /* not timesliced */
|
||||
0, /* all interrupts enabled */
|
||||
_MPCI_Internal_name
|
||||
);
|
||||
|
||||
_Thread_Start(
|
||||
_MPCI_Receive_server_tcb,
|
||||
THREAD_START_NUMERIC,
|
||||
_MPCI_Receive_server,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Initialization
|
||||
@@ -286,7 +345,9 @@ Thread_Control *_MPCI_Process_response (
|
||||
*
|
||||
*/
|
||||
|
||||
void _MPCI_Receive_server( void )
|
||||
Thread _MPCI_Receive_server(
|
||||
unsigned32 ignored
|
||||
)
|
||||
{
|
||||
|
||||
MP_packet_Prefix *the_packet;
|
||||
@@ -294,7 +355,6 @@ void _MPCI_Receive_server( void )
|
||||
Thread_Control *executing;
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_MPCI_Receive_server_tcb = executing;
|
||||
|
||||
for ( ; ; ) {
|
||||
|
||||
@@ -342,4 +402,123 @@ void _MPCI_Announce ( void )
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_process_packet
|
||||
*
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Send_process_packet (
|
||||
MPCI_Internal_Remote_operations operation
|
||||
)
|
||||
{
|
||||
MPCI_Internal_packet *the_packet;
|
||||
|
||||
switch ( operation ) {
|
||||
|
||||
case MPCI_PACKETS_SYSTEM_VERIFY:
|
||||
|
||||
the_packet = _MPCI_Internal_packets_Get_packet();
|
||||
the_packet->Prefix.the_class = MP_PACKET_MPCI_INTERNAL;
|
||||
the_packet->Prefix.length = sizeof ( MPCI_Internal_packet );
|
||||
the_packet->Prefix.to_convert = sizeof ( MPCI_Internal_packet );
|
||||
the_packet->operation = operation;
|
||||
|
||||
the_packet->maximum_nodes = _Objects_Maximum_nodes;
|
||||
|
||||
the_packet->maximum_global_objects = _Objects_MP_Maximum_global_objects;
|
||||
|
||||
_MPCI_Send_process_packet( MPCI_ALL_NODES, &the_packet->Prefix );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_request_packet
|
||||
*
|
||||
* This subprogram is not needed since there are no request
|
||||
* packets to be sent by this manager.
|
||||
*
|
||||
*/
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_response_packet
|
||||
*
|
||||
* This subprogram is not needed since there are no response
|
||||
* packets to be sent by this manager.
|
||||
*
|
||||
*/
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
*
|
||||
* _MPCI_Internal_packets_Process_packet
|
||||
*
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Process_packet (
|
||||
MP_packet_Prefix *the_packet_prefix
|
||||
)
|
||||
{
|
||||
MPCI_Internal_packet *the_packet;
|
||||
unsigned32 maximum_nodes;
|
||||
unsigned32 maximum_global_objects;
|
||||
|
||||
the_packet = (MPCI_Internal_packet *) the_packet_prefix;
|
||||
|
||||
switch ( the_packet->operation ) {
|
||||
|
||||
case MPCI_PACKETS_SYSTEM_VERIFY:
|
||||
|
||||
maximum_nodes = the_packet->maximum_nodes;
|
||||
maximum_global_objects = the_packet->maximum_global_objects;
|
||||
if ( maximum_nodes != _Objects_Maximum_nodes ||
|
||||
maximum_global_objects != _Objects_MP_Maximum_global_objects ) {
|
||||
|
||||
_MPCI_Return_packet( the_packet_prefix );
|
||||
|
||||
_Internal_error_Occurred(
|
||||
INTERNAL_ERROR_CORE,
|
||||
TRUE,
|
||||
INTERNAL_ERROR_INCONSISTENT_MP_INFORMATION
|
||||
);
|
||||
}
|
||||
|
||||
_MPCI_Return_packet( the_packet_prefix );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_object_was_deleted
|
||||
*
|
||||
* This subprogram is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*
|
||||
*/
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_extract_proxy
|
||||
*
|
||||
* This subprogram is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*
|
||||
*/
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Get_packet
|
||||
*
|
||||
*/
|
||||
|
||||
MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void )
|
||||
{
|
||||
return ( (MPCI_Internal_packet *) _MPCI_Get_packet() );
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -40,13 +40,15 @@
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
char *_Thread_Idle_name = "IDLE";
|
||||
|
||||
void _Thread_Handler_initialization(
|
||||
unsigned32 ticks_per_timeslice,
|
||||
unsigned32 maximum_extensions,
|
||||
unsigned32 maximum_proxies
|
||||
)
|
||||
{
|
||||
unsigned32 index;
|
||||
unsigned32 index;
|
||||
|
||||
_Context_Switch_necessary = FALSE;
|
||||
_Thread_Executing = NULL;
|
||||
@@ -66,6 +68,83 @@ void _Thread_Handler_initialization(
|
||||
_Chain_Initialize_empty( &_Thread_Ready_chain[ index ] );
|
||||
|
||||
_Thread_MP_Handler_initialization( maximum_proxies );
|
||||
|
||||
/*
|
||||
* Initialize this class of objects.
|
||||
*/
|
||||
|
||||
_Objects_Initialize_information(
|
||||
&_Thread_Internal_information,
|
||||
OBJECTS_INTERNAL_THREADS,
|
||||
FALSE,
|
||||
( _System_state_Is_multiprocessing ) ? 2 : 1,
|
||||
sizeof( Thread_Control ),
|
||||
TRUE,
|
||||
8,
|
||||
TRUE
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Create_idle
|
||||
*/
|
||||
|
||||
void _Thread_Create_idle( void )
|
||||
{
|
||||
Thread (*idle);
|
||||
|
||||
/*
|
||||
* The entire workspace is zeroed during its initialization. Thus, all
|
||||
* fields not explicitly assigned were explicitly zeroed by
|
||||
* _Workspace_Initialization.
|
||||
*/
|
||||
|
||||
_Thread_Idle = _Thread_Internal_allocate();
|
||||
|
||||
/*
|
||||
* Initialize the IDLE task.
|
||||
*/
|
||||
|
||||
#if (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE)
|
||||
idle = _CPU_Thread_Idle_body;
|
||||
#else
|
||||
idle = _Thread_Idle_body;
|
||||
#endif
|
||||
|
||||
if ( _CPU_Table.idle_task )
|
||||
idle = _CPU_Table.idle_task;
|
||||
|
||||
_Thread_Initialize(
|
||||
&_Thread_Internal_information,
|
||||
_Thread_Idle,
|
||||
NULL, /* allocate the stack */
|
||||
THREAD_IDLE_STACK_SIZE,
|
||||
CPU_IDLE_TASK_IS_FP,
|
||||
PRIORITY_MAXIMUM,
|
||||
TRUE, /* preemptable */
|
||||
FALSE, /* not timesliced */
|
||||
0, /* all interrupts enabled */
|
||||
_Thread_Idle_name
|
||||
);
|
||||
|
||||
/*
|
||||
* WARNING!!! This is necessary to "kick" start the system and
|
||||
* MUST be done before _Thread_Start is invoked.
|
||||
*/
|
||||
|
||||
_Thread_Heir =
|
||||
_Thread_Executing = _Thread_Idle;
|
||||
|
||||
_Thread_Start(
|
||||
_Thread_Idle,
|
||||
THREAD_START_NUMERIC,
|
||||
idle,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -89,10 +168,7 @@ void _Thread_Handler_initialization(
|
||||
* select heir
|
||||
*/
|
||||
|
||||
void _Thread_Start_multitasking(
|
||||
Thread_Control *system_thread,
|
||||
Thread_Control *idle_thread
|
||||
)
|
||||
void _Thread_Start_multitasking( void )
|
||||
{
|
||||
/*
|
||||
* The system is now multitasking and completely initialized.
|
||||
@@ -1068,4 +1144,28 @@ STATIC INLINE Thread_Control *_Thread_Get (
|
||||
|
||||
return (Thread_Control *) _Objects_Get( information, id, location );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Idle_body
|
||||
*
|
||||
* This kernel routine is the idle thread. The idle thread runs any time
|
||||
* no other thread is ready to run. This thread loops forever with
|
||||
* interrupts enabled.
|
||||
*
|
||||
* Input parameters:
|
||||
* ignored - this parameter is ignored
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
|
||||
Thread _Thread_Idle_body(
|
||||
unsigned32 ignored
|
||||
)
|
||||
{
|
||||
for( ; ; ) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,6 +29,17 @@ extern "C" {
|
||||
#include <rtems/score/watchdog.h>
|
||||
#include <rtems/score/coresem.h>
|
||||
|
||||
/*
|
||||
* The following constants define the stack size requirements for
|
||||
* the system threads.
|
||||
*/
|
||||
|
||||
#define MPCI_RECEIVE_SERVER_STACK_SIZE \
|
||||
( STACK_MINIMUM_SIZE + \
|
||||
CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK + \
|
||||
_CPU_Table.extra_mpci_receive_server_stack \
|
||||
)
|
||||
|
||||
/*
|
||||
* The following defines the node number used when a broadcast is desired.
|
||||
*/
|
||||
@@ -91,6 +102,27 @@ typedef struct {
|
||||
|
||||
typedef void (*MPCI_Packet_processor)( MP_packet_Prefix * );
|
||||
|
||||
/*
|
||||
* The following enumerated type defines the list of
|
||||
* internal MP operations.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MPCI_PACKETS_SYSTEM_VERIFY = 0
|
||||
} MPCI_Internal_Remote_operations;
|
||||
|
||||
/*
|
||||
* The following data structure defines the packet used to perform
|
||||
* remote event operations.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
MP_packet_Prefix Prefix;
|
||||
MPCI_Internal_Remote_operations operation;
|
||||
unsigned32 maximum_nodes;
|
||||
unsigned32 maximum_global_objects;
|
||||
} MPCI_Internal_packet;
|
||||
|
||||
/*
|
||||
* This is the core semaphore which the MPCI Receive Server blocks on.
|
||||
*/
|
||||
@@ -136,6 +168,16 @@ void _MPCI_Handler_initialization(
|
||||
unsigned32 timeout_status
|
||||
);
|
||||
|
||||
/*
|
||||
* _MPCI_Create_server
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine creates the packet receive server used in MP systems.
|
||||
*/
|
||||
|
||||
void _MPCI_Create_server( void );
|
||||
|
||||
/*
|
||||
* _MPCI_Initialization
|
||||
*
|
||||
@@ -259,7 +301,9 @@ Thread_Control *_MPCI_Process_response (
|
||||
*
|
||||
*/
|
||||
|
||||
void _MPCI_Receive_server( void );
|
||||
Thread _MPCI_Receive_server(
|
||||
unsigned32 ignored
|
||||
);
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
@@ -272,6 +316,93 @@ void _MPCI_Receive_server( void );
|
||||
|
||||
void _MPCI_Announce ( void );
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_process_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs a remote procedure call so that a
|
||||
* process operation can be performed on another node.
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Send_process_packet (
|
||||
MPCI_Internal_Remote_operations operation
|
||||
);
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_request_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs a remote procedure call so that a
|
||||
* directive operation can be initiated on another node.
|
||||
*
|
||||
* This routine is not needed since there are no request
|
||||
* packets to be sent by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_response_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs a remote procedure call so that a
|
||||
* directive can be performed on another node.
|
||||
*
|
||||
* This routine is not needed since there are no response
|
||||
* packets to be sent by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* _MPCI_Internal_packets_Process_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine performs the actions specific to this package for
|
||||
* the request from another node.
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Process_packet (
|
||||
MP_packet_Prefix *the_packet_prefix
|
||||
);
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_object_was_deleted
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is invoked indirectly by the thread queue
|
||||
* when a proxy has been removed from the thread queue and
|
||||
* the remote node must be informed of this.
|
||||
*
|
||||
* This routine is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Send_extract_proxy
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is invoked when a task is deleted and it
|
||||
* has a proxy which must be removed from a thread queue and
|
||||
* the remote node must be informed of this.
|
||||
*
|
||||
* This routine is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _MPCI_Internal_packets_Get_packet
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is used to obtain a internal threads mp packet.
|
||||
*/
|
||||
|
||||
MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MP_PACKET_INTERNAL_THREADS = 0,
|
||||
MP_PACKET_MPCI_INTERNAL = 0,
|
||||
MP_PACKET_TASKS = 1,
|
||||
MP_PACKET_MESSAGE_QUEUE = 2,
|
||||
MP_PACKET_SEMAPHORE = 3,
|
||||
@@ -48,7 +48,7 @@ typedef enum {
|
||||
MP_PACKET_SIGNAL = 7
|
||||
} MP_packet_Classes;
|
||||
|
||||
#define MP_PACKET_CLASSES_FIRST MP_PACKET_INTERNAL_THREADS
|
||||
#define MP_PACKET_CLASSES_FIRST MP_PACKET_MPCI_INTERNAL
|
||||
#define MP_PACKET_CLASSES_LAST MP_PACKET_SIGNAL
|
||||
|
||||
/*
|
||||
|
||||
@@ -100,7 +100,7 @@ typedef enum {
|
||||
|
||||
#define OBJECTS_CLASSES_FIRST OBJECTS_NO_CLASS
|
||||
#define OBJECTS_CLASSES_LAST OBJECTS_POSIX_CONDITION_VARIABLES
|
||||
#define OBJECTS_CLASSES_FIRST_THREAD_CLASS OBJECTS_INTERNAL_THREADS
|
||||
#define OBJECTS_CLASSES_FIRST_THREAD_CLASS OBJECTS_MPCI_PACKETS
|
||||
#define OBJECTS_CLASSES_LAST_THREAD_CLASS OBJECTS_POSIX_THREADS
|
||||
|
||||
/*
|
||||
|
||||
@@ -31,7 +31,7 @@ extern "C" {
|
||||
typedef enum {
|
||||
SYSTEM_STATE_BEFORE_INITIALIZATION, /* start -> end of 1st init part */
|
||||
SYSTEM_STATE_BEFORE_MULTITASKING, /* end of 1st -> beginning of 2nd */
|
||||
SYSTEM_STATE_BEGIN_MULTITASKING, /* beginning of 2nd -> end of SYSI */
|
||||
SYSTEM_STATE_BEGIN_MULTITASKING, /* just before multitasking starts */
|
||||
SYSTEM_STATE_UP, /* normal operation */
|
||||
SYSTEM_STATE_FAILED /* fatal error occurred */
|
||||
} System_state_Codes;
|
||||
|
||||
@@ -160,6 +160,28 @@ typedef struct {
|
||||
void **extensions;
|
||||
} Thread_Control;
|
||||
|
||||
/*
|
||||
* The following constants define the stack size requirements for
|
||||
* the idle thread.
|
||||
*/
|
||||
|
||||
|
||||
#define THREAD_IDLE_STACK_SIZE STACK_MINIMUM_SIZE
|
||||
|
||||
/*
|
||||
* The following defines the information control block used to
|
||||
* manage this class of objects.
|
||||
*/
|
||||
|
||||
EXTERN Objects_Information _Thread_Internal_information;
|
||||
|
||||
/*
|
||||
* The following define the thread control pointers used to access
|
||||
* and manipulate the idle thread.
|
||||
*/
|
||||
|
||||
EXTERN Thread_Control *_Thread_Idle;
|
||||
|
||||
/*
|
||||
* The following context area contains the context of the "thread"
|
||||
* which invoked the start multitasking routine. This context is
|
||||
@@ -237,6 +259,18 @@ void _Thread_Handler_initialization (
|
||||
unsigned32 maximum_proxies
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Create_idle
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine creates the idle thread.
|
||||
*
|
||||
* WARNING!! No thread should be created before this one.
|
||||
*/
|
||||
|
||||
void _Thread_Create_idle( void );
|
||||
|
||||
/*
|
||||
* _Thread_Start_multitasking
|
||||
*
|
||||
@@ -756,6 +790,42 @@ STATIC INLINE boolean _Thread_Is_proxy_blocking (
|
||||
unsigned32 code
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Internal_allocate
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine allocates an internal thread.
|
||||
*/
|
||||
|
||||
STATIC INLINE Thread_Control *_Thread_Internal_allocate( void );
|
||||
|
||||
/*
|
||||
* _Thread_Internal_free
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine frees an internal thread.
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Thread_Internal_free (
|
||||
Thread_Control *the_task
|
||||
);
|
||||
|
||||
/*
|
||||
* _Thread_Idle_body
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine is the body of the system idle thread.
|
||||
*/
|
||||
|
||||
#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
|
||||
Thread _Thread_Idle_body(
|
||||
unsigned32 ignored
|
||||
);
|
||||
#endif
|
||||
|
||||
#include <rtems/score/thread.inl>
|
||||
#include <rtems/score/threadmp.h>
|
||||
|
||||
|
||||
@@ -283,5 +283,29 @@ STATIC INLINE boolean _Thread_Is_proxy_blocking (
|
||||
return (code == THREAD_STATUS_PROXY_BLOCKING);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Internal_allocate
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE Thread_Control *_Thread_Internal_allocate( void )
|
||||
{
|
||||
return (Thread_Control *) _Objects_Allocate( &_Thread_Internal_information );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Internal_free
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Thread_Internal_free (
|
||||
Thread_Control *the_task
|
||||
)
|
||||
{
|
||||
_Objects_Free( &_Thread_Internal_information, &the_task->Object );
|
||||
}
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
|
||||
@@ -197,5 +197,21 @@ void _Thread_Enable_dispatch( void );
|
||||
#define _Thread_Is_proxy_blocking( _code ) \
|
||||
( (_code) == THREAD_STATUS_PROXY_BLOCKING )
|
||||
|
||||
/*
|
||||
* _Thread_Internal_allocate
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Thread_Internal_allocate() \
|
||||
((Thread_Control *) _Objects_Allocate( &_Thread_Internal_information ))
|
||||
|
||||
/*
|
||||
* _Thread_Internal_free
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Thread_Internal_free( _the_task ) \
|
||||
_Objects_Free( &_Thread_Internal_information, &(_the_task)->Object )
|
||||
|
||||
#endif
|
||||
/* end of include file */
|
||||
|
||||
@@ -50,6 +50,22 @@ void _MPCI_Handler_initialization(
|
||||
|
||||
_MPCI_table = users_mpci_table;
|
||||
|
||||
if ( !_System_state_Is_multiprocessing )
|
||||
return;
|
||||
|
||||
/*
|
||||
* Register the MP Process Packet routine.
|
||||
*/
|
||||
|
||||
_MPCI_Register_packet_processor(
|
||||
MP_PACKET_MPCI_INTERNAL,
|
||||
_MPCI_Internal_packets_Process_packet
|
||||
);
|
||||
|
||||
/*
|
||||
* Create the counting semaphore used by the MPCI Receive Server.
|
||||
*/
|
||||
|
||||
attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
|
||||
|
||||
_CORE_semaphore_Initialize(
|
||||
@@ -70,6 +86,49 @@ void _MPCI_Handler_initialization(
|
||||
);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Create_server
|
||||
*
|
||||
* This subprogram creates the MPCI receive server.
|
||||
*/
|
||||
|
||||
char *_MPCI_Internal_name = "MPCI";
|
||||
|
||||
void _MPCI_Create_server( void )
|
||||
{
|
||||
|
||||
if ( !_System_state_Is_multiprocessing )
|
||||
return;
|
||||
|
||||
/*
|
||||
* Initialize the MPCI Receive Server
|
||||
*/
|
||||
|
||||
_MPCI_Receive_server_tcb = _Thread_Internal_allocate();
|
||||
|
||||
_Thread_Initialize(
|
||||
&_Thread_Internal_information,
|
||||
_MPCI_Receive_server_tcb,
|
||||
NULL, /* allocate the stack */
|
||||
MPCI_RECEIVE_SERVER_STACK_SIZE,
|
||||
CPU_ALL_TASKS_ARE_FP,
|
||||
PRIORITY_MINIMUM,
|
||||
FALSE, /* no preempt */
|
||||
FALSE, /* not timesliced */
|
||||
0, /* all interrupts enabled */
|
||||
_MPCI_Internal_name
|
||||
);
|
||||
|
||||
_Thread_Start(
|
||||
_MPCI_Receive_server_tcb,
|
||||
THREAD_START_NUMERIC,
|
||||
_MPCI_Receive_server,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Initialization
|
||||
@@ -286,7 +345,9 @@ Thread_Control *_MPCI_Process_response (
|
||||
*
|
||||
*/
|
||||
|
||||
void _MPCI_Receive_server( void )
|
||||
Thread _MPCI_Receive_server(
|
||||
unsigned32 ignored
|
||||
)
|
||||
{
|
||||
|
||||
MP_packet_Prefix *the_packet;
|
||||
@@ -294,7 +355,6 @@ void _MPCI_Receive_server( void )
|
||||
Thread_Control *executing;
|
||||
|
||||
executing = _Thread_Executing;
|
||||
_MPCI_Receive_server_tcb = executing;
|
||||
|
||||
for ( ; ; ) {
|
||||
|
||||
@@ -342,4 +402,123 @@ void _MPCI_Announce ( void )
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_process_packet
|
||||
*
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Send_process_packet (
|
||||
MPCI_Internal_Remote_operations operation
|
||||
)
|
||||
{
|
||||
MPCI_Internal_packet *the_packet;
|
||||
|
||||
switch ( operation ) {
|
||||
|
||||
case MPCI_PACKETS_SYSTEM_VERIFY:
|
||||
|
||||
the_packet = _MPCI_Internal_packets_Get_packet();
|
||||
the_packet->Prefix.the_class = MP_PACKET_MPCI_INTERNAL;
|
||||
the_packet->Prefix.length = sizeof ( MPCI_Internal_packet );
|
||||
the_packet->Prefix.to_convert = sizeof ( MPCI_Internal_packet );
|
||||
the_packet->operation = operation;
|
||||
|
||||
the_packet->maximum_nodes = _Objects_Maximum_nodes;
|
||||
|
||||
the_packet->maximum_global_objects = _Objects_MP_Maximum_global_objects;
|
||||
|
||||
_MPCI_Send_process_packet( MPCI_ALL_NODES, &the_packet->Prefix );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_request_packet
|
||||
*
|
||||
* This subprogram is not needed since there are no request
|
||||
* packets to be sent by this manager.
|
||||
*
|
||||
*/
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_response_packet
|
||||
*
|
||||
* This subprogram is not needed since there are no response
|
||||
* packets to be sent by this manager.
|
||||
*
|
||||
*/
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
*
|
||||
* _MPCI_Internal_packets_Process_packet
|
||||
*
|
||||
*/
|
||||
|
||||
void _MPCI_Internal_packets_Process_packet (
|
||||
MP_packet_Prefix *the_packet_prefix
|
||||
)
|
||||
{
|
||||
MPCI_Internal_packet *the_packet;
|
||||
unsigned32 maximum_nodes;
|
||||
unsigned32 maximum_global_objects;
|
||||
|
||||
the_packet = (MPCI_Internal_packet *) the_packet_prefix;
|
||||
|
||||
switch ( the_packet->operation ) {
|
||||
|
||||
case MPCI_PACKETS_SYSTEM_VERIFY:
|
||||
|
||||
maximum_nodes = the_packet->maximum_nodes;
|
||||
maximum_global_objects = the_packet->maximum_global_objects;
|
||||
if ( maximum_nodes != _Objects_Maximum_nodes ||
|
||||
maximum_global_objects != _Objects_MP_Maximum_global_objects ) {
|
||||
|
||||
_MPCI_Return_packet( the_packet_prefix );
|
||||
|
||||
_Internal_error_Occurred(
|
||||
INTERNAL_ERROR_CORE,
|
||||
TRUE,
|
||||
INTERNAL_ERROR_INCONSISTENT_MP_INFORMATION
|
||||
);
|
||||
}
|
||||
|
||||
_MPCI_Return_packet( the_packet_prefix );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_object_was_deleted
|
||||
*
|
||||
* This subprogram is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*
|
||||
*/
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Send_extract_proxy
|
||||
*
|
||||
* This subprogram is not needed since there are no objects
|
||||
* deleted by this manager.
|
||||
*
|
||||
*/
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _MPCI_Internal_packets_Get_packet
|
||||
*
|
||||
*/
|
||||
|
||||
MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void )
|
||||
{
|
||||
return ( (MPCI_Internal_packet *) _MPCI_Get_packet() );
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -40,13 +40,15 @@
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
char *_Thread_Idle_name = "IDLE";
|
||||
|
||||
void _Thread_Handler_initialization(
|
||||
unsigned32 ticks_per_timeslice,
|
||||
unsigned32 maximum_extensions,
|
||||
unsigned32 maximum_proxies
|
||||
)
|
||||
{
|
||||
unsigned32 index;
|
||||
unsigned32 index;
|
||||
|
||||
_Context_Switch_necessary = FALSE;
|
||||
_Thread_Executing = NULL;
|
||||
@@ -66,6 +68,83 @@ void _Thread_Handler_initialization(
|
||||
_Chain_Initialize_empty( &_Thread_Ready_chain[ index ] );
|
||||
|
||||
_Thread_MP_Handler_initialization( maximum_proxies );
|
||||
|
||||
/*
|
||||
* Initialize this class of objects.
|
||||
*/
|
||||
|
||||
_Objects_Initialize_information(
|
||||
&_Thread_Internal_information,
|
||||
OBJECTS_INTERNAL_THREADS,
|
||||
FALSE,
|
||||
( _System_state_Is_multiprocessing ) ? 2 : 1,
|
||||
sizeof( Thread_Control ),
|
||||
TRUE,
|
||||
8,
|
||||
TRUE
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Create_idle
|
||||
*/
|
||||
|
||||
void _Thread_Create_idle( void )
|
||||
{
|
||||
Thread (*idle);
|
||||
|
||||
/*
|
||||
* The entire workspace is zeroed during its initialization. Thus, all
|
||||
* fields not explicitly assigned were explicitly zeroed by
|
||||
* _Workspace_Initialization.
|
||||
*/
|
||||
|
||||
_Thread_Idle = _Thread_Internal_allocate();
|
||||
|
||||
/*
|
||||
* Initialize the IDLE task.
|
||||
*/
|
||||
|
||||
#if (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE)
|
||||
idle = _CPU_Thread_Idle_body;
|
||||
#else
|
||||
idle = _Thread_Idle_body;
|
||||
#endif
|
||||
|
||||
if ( _CPU_Table.idle_task )
|
||||
idle = _CPU_Table.idle_task;
|
||||
|
||||
_Thread_Initialize(
|
||||
&_Thread_Internal_information,
|
||||
_Thread_Idle,
|
||||
NULL, /* allocate the stack */
|
||||
THREAD_IDLE_STACK_SIZE,
|
||||
CPU_IDLE_TASK_IS_FP,
|
||||
PRIORITY_MAXIMUM,
|
||||
TRUE, /* preemptable */
|
||||
FALSE, /* not timesliced */
|
||||
0, /* all interrupts enabled */
|
||||
_Thread_Idle_name
|
||||
);
|
||||
|
||||
/*
|
||||
* WARNING!!! This is necessary to "kick" start the system and
|
||||
* MUST be done before _Thread_Start is invoked.
|
||||
*/
|
||||
|
||||
_Thread_Heir =
|
||||
_Thread_Executing = _Thread_Idle;
|
||||
|
||||
_Thread_Start(
|
||||
_Thread_Idle,
|
||||
THREAD_START_NUMERIC,
|
||||
idle,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -89,10 +168,7 @@ void _Thread_Handler_initialization(
|
||||
* select heir
|
||||
*/
|
||||
|
||||
void _Thread_Start_multitasking(
|
||||
Thread_Control *system_thread,
|
||||
Thread_Control *idle_thread
|
||||
)
|
||||
void _Thread_Start_multitasking( void )
|
||||
{
|
||||
/*
|
||||
* The system is now multitasking and completely initialized.
|
||||
@@ -1068,4 +1144,28 @@ STATIC INLINE Thread_Control *_Thread_Get (
|
||||
|
||||
return (Thread_Control *) _Objects_Get( information, id, location );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Thread_Idle_body
|
||||
*
|
||||
* This kernel routine is the idle thread. The idle thread runs any time
|
||||
* no other thread is ready to run. This thread loops forever with
|
||||
* interrupts enabled.
|
||||
*
|
||||
* Input parameters:
|
||||
* ignored - this parameter is ignored
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
|
||||
Thread _Thread_Idle_body(
|
||||
unsigned32 ignored
|
||||
)
|
||||
{
|
||||
for( ; ; ) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user