From adf98bd423cabd47466b13d3432284da0d532176 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 21 Feb 1996 14:44:11 +0000 Subject: 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. --- c/src/exec/score/headers/mpci.h | 133 ++++++++++++++++- c/src/exec/score/headers/mppkt.h | 4 +- c/src/exec/score/headers/object.h | 2 +- c/src/exec/score/headers/sysstate.h | 2 +- c/src/exec/score/headers/thread.h | 70 +++++++++ c/src/exec/score/include/rtems/score/mpci.h | 133 ++++++++++++++++- c/src/exec/score/include/rtems/score/mppkt.h | 4 +- c/src/exec/score/include/rtems/score/object.h | 2 +- c/src/exec/score/include/rtems/score/sysstate.h | 2 +- c/src/exec/score/include/rtems/score/thread.h | 70 +++++++++ c/src/exec/score/inline/rtems/score/thread.inl | 24 ++++ c/src/exec/score/inline/thread.inl | 24 ++++ c/src/exec/score/macros/rtems/score/thread.inl | 16 +++ c/src/exec/score/macros/thread.inl | 16 +++ c/src/exec/score/src/mpci.c | 183 +++++++++++++++++++++++- c/src/exec/score/src/thread.c | 110 +++++++++++++- cpukit/score/include/rtems/score/mpci.h | 133 ++++++++++++++++- cpukit/score/include/rtems/score/mppkt.h | 4 +- cpukit/score/include/rtems/score/object.h | 2 +- cpukit/score/include/rtems/score/sysstate.h | 2 +- cpukit/score/include/rtems/score/thread.h | 70 +++++++++ cpukit/score/inline/rtems/score/thread.inl | 24 ++++ cpukit/score/macros/rtems/score/thread.inl | 16 +++ cpukit/score/src/mpci.c | 183 +++++++++++++++++++++++- cpukit/score/src/thread.c | 110 +++++++++++++- 25 files changed, 1310 insertions(+), 29 deletions(-) diff --git a/c/src/exec/score/headers/mpci.h b/c/src/exec/score/headers/mpci.h index 8f115e8fba..25d7ac4094 100644 --- a/c/src/exec/score/headers/mpci.h +++ b/c/src/exec/score/headers/mpci.h @@ -29,6 +29,17 @@ extern "C" { #include #include +/* + * 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 diff --git a/c/src/exec/score/headers/mppkt.h b/c/src/exec/score/headers/mppkt.h index 8ed1ab1fab..37469d93b8 100644 --- a/c/src/exec/score/headers/mppkt.h +++ b/c/src/exec/score/headers/mppkt.h @@ -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 /* diff --git a/c/src/exec/score/headers/object.h b/c/src/exec/score/headers/object.h index 2337a8e13a..2c93a44379 100644 --- a/c/src/exec/score/headers/object.h +++ b/c/src/exec/score/headers/object.h @@ -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 /* diff --git a/c/src/exec/score/headers/sysstate.h b/c/src/exec/score/headers/sysstate.h index 11b5018705..c5d8562001 100644 --- a/c/src/exec/score/headers/sysstate.h +++ b/c/src/exec/score/headers/sysstate.h @@ -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; diff --git a/c/src/exec/score/headers/thread.h b/c/src/exec/score/headers/thread.h index 654dddc825..d904df439b 100644 --- a/c/src/exec/score/headers/thread.h +++ b/c/src/exec/score/headers/thread.h @@ -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 #include diff --git a/c/src/exec/score/include/rtems/score/mpci.h b/c/src/exec/score/include/rtems/score/mpci.h index 8f115e8fba..25d7ac4094 100644 --- a/c/src/exec/score/include/rtems/score/mpci.h +++ b/c/src/exec/score/include/rtems/score/mpci.h @@ -29,6 +29,17 @@ extern "C" { #include #include +/* + * 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 diff --git a/c/src/exec/score/include/rtems/score/mppkt.h b/c/src/exec/score/include/rtems/score/mppkt.h index 8ed1ab1fab..37469d93b8 100644 --- a/c/src/exec/score/include/rtems/score/mppkt.h +++ b/c/src/exec/score/include/rtems/score/mppkt.h @@ -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 /* diff --git a/c/src/exec/score/include/rtems/score/object.h b/c/src/exec/score/include/rtems/score/object.h index 2337a8e13a..2c93a44379 100644 --- a/c/src/exec/score/include/rtems/score/object.h +++ b/c/src/exec/score/include/rtems/score/object.h @@ -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 /* diff --git a/c/src/exec/score/include/rtems/score/sysstate.h b/c/src/exec/score/include/rtems/score/sysstate.h index 11b5018705..c5d8562001 100644 --- a/c/src/exec/score/include/rtems/score/sysstate.h +++ b/c/src/exec/score/include/rtems/score/sysstate.h @@ -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; diff --git a/c/src/exec/score/include/rtems/score/thread.h b/c/src/exec/score/include/rtems/score/thread.h index 654dddc825..d904df439b 100644 --- a/c/src/exec/score/include/rtems/score/thread.h +++ b/c/src/exec/score/include/rtems/score/thread.h @@ -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 #include diff --git a/c/src/exec/score/inline/rtems/score/thread.inl b/c/src/exec/score/inline/rtems/score/thread.inl index 3a96acf4ea..265f51a8d0 100644 --- a/c/src/exec/score/inline/rtems/score/thread.inl +++ b/c/src/exec/score/inline/rtems/score/thread.inl @@ -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 */ diff --git a/c/src/exec/score/inline/thread.inl b/c/src/exec/score/inline/thread.inl index 3a96acf4ea..265f51a8d0 100644 --- a/c/src/exec/score/inline/thread.inl +++ b/c/src/exec/score/inline/thread.inl @@ -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 */ diff --git a/c/src/exec/score/macros/rtems/score/thread.inl b/c/src/exec/score/macros/rtems/score/thread.inl index 3f7afb054b..735686aa20 100644 --- a/c/src/exec/score/macros/rtems/score/thread.inl +++ b/c/src/exec/score/macros/rtems/score/thread.inl @@ -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 */ diff --git a/c/src/exec/score/macros/thread.inl b/c/src/exec/score/macros/thread.inl index 3f7afb054b..735686aa20 100644 --- a/c/src/exec/score/macros/thread.inl +++ b/c/src/exec/score/macros/thread.inl @@ -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 */ diff --git a/c/src/exec/score/src/mpci.c b/c/src/exec/score/src/mpci.c index 08b8eff9ba..c3090aacc1 100644 --- a/c/src/exec/score/src/mpci.c +++ b/c/src/exec/score/src/mpci.c @@ -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 */ diff --git a/c/src/exec/score/src/thread.c b/c/src/exec/score/src/thread.c index 1214b9141e..258fcb92bd 100644 --- a/c/src/exec/score/src/thread.c +++ b/c/src/exec/score/src/thread.c @@ -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 diff --git a/cpukit/score/include/rtems/score/mpci.h b/cpukit/score/include/rtems/score/mpci.h index 8f115e8fba..25d7ac4094 100644 --- a/cpukit/score/include/rtems/score/mpci.h +++ b/cpukit/score/include/rtems/score/mpci.h @@ -29,6 +29,17 @@ extern "C" { #include #include +/* + * 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 diff --git a/cpukit/score/include/rtems/score/mppkt.h b/cpukit/score/include/rtems/score/mppkt.h index 8ed1ab1fab..37469d93b8 100644 --- a/cpukit/score/include/rtems/score/mppkt.h +++ b/cpukit/score/include/rtems/score/mppkt.h @@ -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 /* diff --git a/cpukit/score/include/rtems/score/object.h b/cpukit/score/include/rtems/score/object.h index 2337a8e13a..2c93a44379 100644 --- a/cpukit/score/include/rtems/score/object.h +++ b/cpukit/score/include/rtems/score/object.h @@ -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 /* diff --git a/cpukit/score/include/rtems/score/sysstate.h b/cpukit/score/include/rtems/score/sysstate.h index 11b5018705..c5d8562001 100644 --- a/cpukit/score/include/rtems/score/sysstate.h +++ b/cpukit/score/include/rtems/score/sysstate.h @@ -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; diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index 654dddc825..d904df439b 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -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 #include diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl index 3a96acf4ea..265f51a8d0 100644 --- a/cpukit/score/inline/rtems/score/thread.inl +++ b/cpukit/score/inline/rtems/score/thread.inl @@ -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 */ diff --git a/cpukit/score/macros/rtems/score/thread.inl b/cpukit/score/macros/rtems/score/thread.inl index 3f7afb054b..735686aa20 100644 --- a/cpukit/score/macros/rtems/score/thread.inl +++ b/cpukit/score/macros/rtems/score/thread.inl @@ -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 */ diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c index 08b8eff9ba..c3090aacc1 100644 --- a/cpukit/score/src/mpci.c +++ b/cpukit/score/src/mpci.c @@ -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 */ diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c index 1214b9141e..258fcb92bd 100644 --- a/cpukit/score/src/thread.c +++ b/cpukit/score/src/thread.c @@ -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 -- cgit v1.2.3