From c4d69e21a751d4c907db9e8f4bb9bd38693075b1 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 17 May 1999 21:02:16 +0000 Subject: Split Task Manager into multiple files. Eventually this effort will reduce the size of executables. --- c/src/exec/rtems/src/Makefile.in | 7 +- c/src/exec/rtems/src/taskcreate.c | 229 ++++++++ c/src/exec/rtems/src/taskdelete.c | 101 ++++ c/src/exec/rtems/src/taskgetnote.c | 106 ++++ c/src/exec/rtems/src/taskident.c | 66 +++ c/src/exec/rtems/src/taskinitusers.c | 84 +++ c/src/exec/rtems/src/taskmode.c | 122 +++++ c/src/exec/rtems/src/taskrestart.c | 80 +++ c/src/exec/rtems/src/taskresume.c | 82 +++ c/src/exec/rtems/src/tasks.c | 961 --------------------------------- c/src/exec/rtems/src/tasksetnote.c | 103 ++++ c/src/exec/rtems/src/tasksetpriority.c | 95 ++++ c/src/exec/rtems/src/taskstart.c | 85 +++ c/src/exec/rtems/src/tasksuspend.c | 83 +++ c/src/exec/rtems/src/taskwakeafter.c | 65 +++ c/src/exec/rtems/src/taskwakewhen.c | 80 +++ cpukit/rtems/src/taskcreate.c | 229 ++++++++ cpukit/rtems/src/taskdelete.c | 101 ++++ cpukit/rtems/src/taskgetnote.c | 106 ++++ cpukit/rtems/src/taskident.c | 66 +++ cpukit/rtems/src/taskinitusers.c | 84 +++ cpukit/rtems/src/taskmode.c | 122 +++++ cpukit/rtems/src/taskrestart.c | 80 +++ cpukit/rtems/src/taskresume.c | 82 +++ cpukit/rtems/src/tasks.c | 961 --------------------------------- cpukit/rtems/src/tasksetnote.c | 103 ++++ cpukit/rtems/src/tasksetpriority.c | 95 ++++ cpukit/rtems/src/taskstart.c | 85 +++ cpukit/rtems/src/tasksuspend.c | 83 +++ cpukit/rtems/src/taskwakeafter.c | 65 +++ cpukit/rtems/src/taskwakewhen.c | 80 +++ 31 files changed, 2768 insertions(+), 1923 deletions(-) create mode 100644 c/src/exec/rtems/src/taskcreate.c create mode 100644 c/src/exec/rtems/src/taskdelete.c create mode 100644 c/src/exec/rtems/src/taskgetnote.c create mode 100644 c/src/exec/rtems/src/taskident.c create mode 100644 c/src/exec/rtems/src/taskinitusers.c create mode 100644 c/src/exec/rtems/src/taskmode.c create mode 100644 c/src/exec/rtems/src/taskrestart.c create mode 100644 c/src/exec/rtems/src/taskresume.c create mode 100644 c/src/exec/rtems/src/tasksetnote.c create mode 100644 c/src/exec/rtems/src/tasksetpriority.c create mode 100644 c/src/exec/rtems/src/taskstart.c create mode 100644 c/src/exec/rtems/src/tasksuspend.c create mode 100644 c/src/exec/rtems/src/taskwakeafter.c create mode 100644 c/src/exec/rtems/src/taskwakewhen.c create mode 100644 cpukit/rtems/src/taskcreate.c create mode 100644 cpukit/rtems/src/taskdelete.c create mode 100644 cpukit/rtems/src/taskgetnote.c create mode 100644 cpukit/rtems/src/taskident.c create mode 100644 cpukit/rtems/src/taskinitusers.c create mode 100644 cpukit/rtems/src/taskmode.c create mode 100644 cpukit/rtems/src/taskrestart.c create mode 100644 cpukit/rtems/src/taskresume.c create mode 100644 cpukit/rtems/src/tasksetnote.c create mode 100644 cpukit/rtems/src/tasksetpriority.c create mode 100644 cpukit/rtems/src/taskstart.c create mode 100644 cpukit/rtems/src/tasksuspend.c create mode 100644 cpukit/rtems/src/taskwakeafter.c create mode 100644 cpukit/rtems/src/taskwakewhen.c diff --git a/c/src/exec/rtems/src/Makefile.in b/c/src/exec/rtems/src/Makefile.in index 990568c5b6..1cdf244594 100644 --- a/c/src/exec/rtems/src/Makefile.in +++ b/c/src/exec/rtems/src/Makefile.in @@ -19,9 +19,14 @@ VPATH = @srcdir@ MP_PIECES_yes_V = eventmp mp msgmp partmp regionmp semmp signalmp taskmp MP_PIECES = $(MP_PIECES_$(HAS_MP)_V) +TASK_PIECES=\ + tasks taskcreate taskdelete taskgetnote taskident taskinitusers \ + taskmode taskrestart taskresume tasksetnote tasksetpriority \ + taskstart tasksuspend taskwakeafter taskwakewhen + C_PIECES=attr clock dpmem event intr intrbody msg \ part ratemon region sem signal \ - tasks timer $(MP_PIECES) + $(TASK_PIECES) timer $(MP_PIECES) C_FILES=$(C_PIECES:%=%.c) C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) diff --git a/c/src/exec/rtems/src/taskcreate.c b/c/src/exec/rtems/src/taskcreate.c new file mode 100644 index 0000000000..c5945a5332 --- /dev/null +++ b/c/src/exec/rtems/src/taskcreate.c @@ -0,0 +1,229 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_create + * + * This directive creates a thread by allocating and initializing a + * thread control block and a stack. The newly created thread is + * placed in the dormant state. + * + * Input parameters: + * name - user defined thread name + * initial_priority - thread priority + * stack_size - stack size in bytes + * initial_modes - initial thread mode + * attribute_set - thread attributes + * id - pointer to thread id + * + * Output parameters: + * id - thread id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_create( + rtems_name name, + rtems_task_priority initial_priority, + unsigned32 stack_size, + rtems_mode initial_modes, + rtems_attribute attribute_set, + Objects_Id *id +) +{ + register Thread_Control *the_thread; + boolean is_fp; +#if defined(RTEMS_MULTIPROCESSING) + Objects_MP_Control *the_global_object = NULL; + boolean is_global; +#endif + boolean status; + rtems_attribute the_attribute_set; + Priority_Control core_priority; + RTEMS_API_Control *api; + ASR_Information *asr; + + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + /* + * Core Thread Initialize insures we get the minimum amount of + * stack space. + */ + +#if 0 + if ( !_Stack_Is_enough( stack_size ) ) + return RTEMS_INVALID_SIZE; +#endif + + /* + * Fix the attribute set to match the attributes which + * this processor (1) requires and (2) is able to support. + * First add in the required flags for attribute_set + * Typically this might include FP if the platform + * or application required all tasks to be fp aware. + * Then turn off the requested bits which are not supported. + */ + + the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED ); + the_attribute_set = + _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED ); + + if ( _Attributes_Is_floating_point( the_attribute_set ) ) + is_fp = TRUE; + else + is_fp = FALSE; + + /* + * Validate the RTEMS API priority and convert it to the core priority range. + */ + + if ( !_Attributes_Is_system_task( the_attribute_set ) ) { + if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) ) + return RTEMS_INVALID_PRIORITY; + } + + core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority ); + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( the_attribute_set ) ) { + + is_global = TRUE; + + if ( !_System_state_Is_multiprocessing ) + return RTEMS_MP_NOT_CONFIGURED; + + } else + is_global = FALSE; +#endif + + /* + * Make sure system is MP if this task is global + */ + + /* + * Disable dispatch for protection + */ + + _Thread_Disable_dispatch(); + + /* + * Allocate the thread control block and -- if the task is global -- + * allocate a global object control block. + * + * NOTE: This routine does not use the combined allocate and open + * global object routine because this results in a lack of + * control over when memory is allocated and can be freed in + * the event of an error. + */ + + the_thread = _RTEMS_tasks_Allocate(); + + if ( !the_thread ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) { + the_global_object = _Objects_MP_Allocate_global_object(); + + if ( _Objects_MP_Is_null_global_object( the_global_object ) ) { + _RTEMS_tasks_Free( the_thread ); + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + } +#endif + + /* + * Initialize the core thread for this task. + */ + + status = _Thread_Initialize( + &_RTEMS_tasks_Information, + the_thread, + NULL, + stack_size, + is_fp, + core_priority, + _Modes_Is_preempt(initial_modes) ? TRUE : FALSE, + _Modes_Is_timeslice(initial_modes) ? + THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE : + THREAD_CPU_BUDGET_ALGORITHM_NONE, + NULL, /* no budget algorithm callout */ + _Modes_Get_interrupt_level(initial_modes), + &name + ); + + if ( !status ) { +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) + _Objects_MP_Free_global_object( the_global_object ); +#endif + _RTEMS_tasks_Free( the_thread ); + _Thread_Enable_dispatch(); + return RTEMS_UNSATISFIED; + } + + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + asr = &api->Signal; + + asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? FALSE : TRUE; + + *id = the_thread->Object.id; + +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) { + + the_thread->is_global = TRUE; + + _Objects_MP_Open( + &_RTEMS_tasks_Information, + the_global_object, + name, + the_thread->Object.id + ); + + _RTEMS_tasks_MP_Send_process_packet( + RTEMS_TASKS_MP_ANNOUNCE_CREATE, + the_thread->Object.id, + name + ); + + } +#endif + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/exec/rtems/src/taskdelete.c b/c/src/exec/rtems/src/taskdelete.c new file mode 100644 index 0000000000..b9a8a47d7a --- /dev/null +++ b/c/src/exec/rtems/src/taskdelete.c @@ -0,0 +1,101 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_delete + * + * This directive allows a thread to delete itself or the thread + * identified in the id field. The executive halts execution + * of the thread and frees the thread control block. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * nothing - if id is the requesting thread (always succeeds) + * RTEMS_SUCCESSFUL - if successful and id is + * not the requesting thread + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_delete( + Objects_Id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + Objects_Information *the_information; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + the_information = _Objects_Get_information( the_thread->Object.id ); + + if ( !the_information ) { + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ID; + /* This should never happen if _Thread_Get() works right */ + } + + _Thread_Close( the_information, the_thread ); + + _RTEMS_tasks_Free( the_thread ); + +#if defined(RTEMS_MULTIPROCESSING) + if ( the_thread->is_global ) { + + _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id ); + + _RTEMS_tasks_MP_Send_process_packet( + RTEMS_TASKS_MP_ANNOUNCE_DELETE, + the_thread->Object.id, + 0 /* Not used */ + ); + } +#endif + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/c/src/exec/rtems/src/taskgetnote.c b/c/src/exec/rtems/src/taskgetnote.c new file mode 100644 index 0000000000..dafbbaba3b --- /dev/null +++ b/c/src/exec/rtems/src/taskgetnote.c @@ -0,0 +1,106 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_get_note + * + * This directive obtains the note from the specified notepad + * of the specified thread. + * + * Input parameters: + * id - thread id + * notepad - notepad number + * note - pointer to note + * + * Output parameters: + * note - filled in if successful + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_get_note( + Objects_Id id, + unsigned32 notepad, + unsigned32 *note +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + + /* + * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would + * be checking an unsigned number for being negative. + */ + + if ( notepad > RTEMS_NOTEPAD_LAST ) + return RTEMS_INVALID_NUMBER; + + /* + * Optimize the most likely case to avoid the Thread_Dispatch. + */ + + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || + _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { + api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; + *note = api->Notepads[ notepad ]; + return RTEMS_SUCCESSFUL; + } + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Executing->Wait.return_argument = note; + + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_GET_NOTE_REQUEST, + id, + 0, /* Not used */ + notepad, + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + *note = api->Notepads[ notepad ]; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/c/src/exec/rtems/src/taskident.c b/c/src/exec/rtems/src/taskident.c new file mode 100644 index 0000000000..ac2b707279 --- /dev/null +++ b/c/src/exec/rtems/src/taskident.c @@ -0,0 +1,66 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_ident + * + * This directive returns the system ID associated with + * the thread name. + * + * Input parameters: + * name - user defined thread name + * node - node(s) to be searched + * id - pointer to thread id + * + * Output parameters: + * *id - thread id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_ident( + rtems_name name, + unsigned32 node, + Objects_Id *id +) +{ + Objects_Name_to_id_errors status; + + if ( name == OBJECTS_ID_OF_SELF ) { + *id = _Thread_Executing->Object.id; + return RTEMS_SUCCESSFUL; + } + + status = _Objects_Name_to_id( &_RTEMS_tasks_Information, &name, node, id ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/c/src/exec/rtems/src/taskinitusers.c b/c/src/exec/rtems/src/taskinitusers.c new file mode 100644 index 0000000000..648c059a22 --- /dev/null +++ b/c/src/exec/rtems/src/taskinitusers.c @@ -0,0 +1,84 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _RTEMS_tasks_Initialize_user_tasks + * + * This routine creates and starts all configured user + * initialzation threads. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _RTEMS_tasks_Initialize_user_tasks( void ) +{ + unsigned32 index; + unsigned32 maximum; + rtems_id id; + rtems_status_code return_value; + rtems_initialization_tasks_table *user_tasks; + + /* + * NOTE: This is slightly different from the Ada implementation. + */ + + user_tasks = _RTEMS_tasks_User_initialization_tasks; + maximum = _RTEMS_tasks_Number_of_initialization_tasks; + + if ( !user_tasks || maximum == 0 ) + return; + + for ( index=0 ; index < maximum ; index++ ) { + return_value = rtems_task_create( + user_tasks[ index ].name, + user_tasks[ index ].initial_priority, + user_tasks[ index ].stack_size, + user_tasks[ index ].mode_set, + user_tasks[ index ].attribute_set, + &id + ); + + if ( !rtems_is_status_successful( return_value ) ) + _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value ); + + return_value = rtems_task_start( + id, + user_tasks[ index ].entry_point, + user_tasks[ index ].argument + ); + + if ( !rtems_is_status_successful( return_value ) ) + _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value ); + } +} diff --git a/c/src/exec/rtems/src/taskmode.c b/c/src/exec/rtems/src/taskmode.c new file mode 100644 index 0000000000..2dc96a8a5d --- /dev/null +++ b/c/src/exec/rtems/src/taskmode.c @@ -0,0 +1,122 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_mode + * + * This directive enables and disables several modes of + * execution for the requesting thread. + * + * Input parameters: + * mode_set - new mode + * mask - mask + * previous_mode_set - address of previous mode set + * + * Output: + * *previous_mode_set - previous mode set + * always return RTEMS_SUCCESSFUL; + */ + +rtems_status_code rtems_task_mode( + rtems_mode mode_set, + rtems_mode mask, + rtems_mode *previous_mode_set +) +{ + Thread_Control *executing; + RTEMS_API_Control *api; + ASR_Information *asr; + boolean is_asr_enabled = FALSE; + boolean needs_asr_dispatching = FALSE; + rtems_mode old_mode; + + executing = _Thread_Executing; + api = executing->API_Extensions[ THREAD_API_RTEMS ]; + asr = &api->Signal; + + old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT; + + if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE ) + old_mode |= RTEMS_NO_TIMESLICE; + else + old_mode |= RTEMS_TIMESLICE; + + old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR; + old_mode |= _ISR_Get_level(); + + *previous_mode_set = old_mode; + + /* + * These are generic thread scheduling characteristics. + */ + + if ( mask & RTEMS_PREEMPT_MASK ) + executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE; + + if ( mask & RTEMS_TIMESLICE_MASK ) { + if ( _Modes_Is_timeslice(mode_set) ) + executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE; + else + executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; + } + + /* + * Set the new interrupt level + */ + + if ( mask & RTEMS_INTERRUPT_MASK ) + _Modes_Set_interrupt_level( mode_set ); + + /* + * This is specific to the RTEMS API + */ + + is_asr_enabled = FALSE; + needs_asr_dispatching = FALSE; + + if ( mask & RTEMS_ASR_MASK ) { + is_asr_enabled = _Modes_Is_asr_disabled( mode_set ) ? FALSE : TRUE; + if ( is_asr_enabled != asr->is_enabled ) { + asr->is_enabled = is_asr_enabled; + _ASR_Swap_signals( asr ); + if ( _ASR_Are_signals_pending( asr ) ) { + needs_asr_dispatching = TRUE; + executing->do_post_task_switch_extension = TRUE; + } + } + } + + if ( _Thread_Evaluate_mode() || needs_asr_dispatching ) + _Thread_Dispatch(); + + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/exec/rtems/src/taskrestart.c b/c/src/exec/rtems/src/taskrestart.c new file mode 100644 index 0000000000..14e11a06d7 --- /dev/null +++ b/c/src/exec/rtems/src/taskrestart.c @@ -0,0 +1,80 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_restart + * + * This directive readies the specified thread. It restores + * the thread environment to the original values established + * at thread creation and start time. A thread can be restarted + * from any state except the dormant state. + * + * Input parameters: + * id - thread id + * argument - thread argument + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_restart( + Objects_Id id, + unsigned32 argument +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + if ( _Thread_Restart( the_thread, NULL, argument ) ) { + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/c/src/exec/rtems/src/taskresume.c b/c/src/exec/rtems/src/taskresume.c new file mode 100644 index 0000000000..70c2051eaf --- /dev/null +++ b/c/src/exec/rtems/src/taskresume.c @@ -0,0 +1,82 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_resume + * + * This directive will remove the specified thread + * from the suspended state. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_resume( + Objects_Id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_RESUME_REQUEST, + id, + 0, /* Not used */ + 0, /* Not used */ + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + if ( _States_Is_suspended( the_thread->current_state ) ) { + _Thread_Resume( the_thread ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/c/src/exec/rtems/src/tasks.c b/c/src/exec/rtems/src/tasks.c index 0f3596c800..589f53e86b 100644 --- a/c/src/exec/rtems/src/tasks.c +++ b/c/src/exec/rtems/src/tasks.c @@ -215,964 +215,3 @@ void _RTEMS_tasks_Manager_initialization( } -/*PAGE - * - * rtems_task_create - * - * This directive creates a thread by allocating and initializing a - * thread control block and a stack. The newly created thread is - * placed in the dormant state. - * - * Input parameters: - * name - user defined thread name - * initial_priority - thread priority - * stack_size - stack size in bytes - * initial_modes - initial thread mode - * attribute_set - thread attributes - * id - pointer to thread id - * - * Output parameters: - * id - thread id - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_create( - rtems_name name, - rtems_task_priority initial_priority, - unsigned32 stack_size, - rtems_mode initial_modes, - rtems_attribute attribute_set, - Objects_Id *id -) -{ - register Thread_Control *the_thread; - boolean is_fp; -#if defined(RTEMS_MULTIPROCESSING) - Objects_MP_Control *the_global_object = NULL; - boolean is_global; -#endif - boolean status; - rtems_attribute the_attribute_set; - Priority_Control core_priority; - RTEMS_API_Control *api; - ASR_Information *asr; - - - if ( !rtems_is_name_valid( name ) ) - return RTEMS_INVALID_NAME; - - /* - * Core Thread Initialize insures we get the minimum amount of - * stack space. - */ - -#if 0 - if ( !_Stack_Is_enough( stack_size ) ) - return RTEMS_INVALID_SIZE; -#endif - - /* - * Fix the attribute set to match the attributes which - * this processor (1) requires and (2) is able to support. - * First add in the required flags for attribute_set - * Typically this might include FP if the platform - * or application required all tasks to be fp aware. - * Then turn off the requested bits which are not supported. - */ - - the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED ); - the_attribute_set = - _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED ); - - if ( _Attributes_Is_floating_point( the_attribute_set ) ) - is_fp = TRUE; - else - is_fp = FALSE; - - /* - * Validate the RTEMS API priority and convert it to the core priority range. - */ - - if ( !_Attributes_Is_system_task( the_attribute_set ) ) { - if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) ) - return RTEMS_INVALID_PRIORITY; - } - - core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority ); - -#if defined(RTEMS_MULTIPROCESSING) - if ( _Attributes_Is_global( the_attribute_set ) ) { - - is_global = TRUE; - - if ( !_System_state_Is_multiprocessing ) - return RTEMS_MP_NOT_CONFIGURED; - - } else - is_global = FALSE; -#endif - - /* - * Make sure system is MP if this task is global - */ - - /* - * Disable dispatch for protection - */ - - _Thread_Disable_dispatch(); - - /* - * Allocate the thread control block and -- if the task is global -- - * allocate a global object control block. - * - * NOTE: This routine does not use the combined allocate and open - * global object routine because this results in a lack of - * control over when memory is allocated and can be freed in - * the event of an error. - */ - - the_thread = _RTEMS_tasks_Allocate(); - - if ( !the_thread ) { - _Thread_Enable_dispatch(); - return RTEMS_TOO_MANY; - } - -#if defined(RTEMS_MULTIPROCESSING) - if ( is_global ) { - the_global_object = _Objects_MP_Allocate_global_object(); - - if ( _Objects_MP_Is_null_global_object( the_global_object ) ) { - _RTEMS_tasks_Free( the_thread ); - _Thread_Enable_dispatch(); - return RTEMS_TOO_MANY; - } - } -#endif - - /* - * Initialize the core thread for this task. - */ - - status = _Thread_Initialize( - &_RTEMS_tasks_Information, - the_thread, - NULL, - stack_size, - is_fp, - core_priority, - _Modes_Is_preempt(initial_modes) ? TRUE : FALSE, - _Modes_Is_timeslice(initial_modes) ? - THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE : - THREAD_CPU_BUDGET_ALGORITHM_NONE, - NULL, /* no budget algorithm callout */ - _Modes_Get_interrupt_level(initial_modes), - &name - ); - - if ( !status ) { -#if defined(RTEMS_MULTIPROCESSING) - if ( is_global ) - _Objects_MP_Free_global_object( the_global_object ); -#endif - _RTEMS_tasks_Free( the_thread ); - _Thread_Enable_dispatch(); - return RTEMS_UNSATISFIED; - } - - api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; - asr = &api->Signal; - - asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? FALSE : TRUE; - - *id = the_thread->Object.id; - -#if defined(RTEMS_MULTIPROCESSING) - if ( is_global ) { - - the_thread->is_global = TRUE; - - _Objects_MP_Open( - &_RTEMS_tasks_Information, - the_global_object, - name, - the_thread->Object.id - ); - - _RTEMS_tasks_MP_Send_process_packet( - RTEMS_TASKS_MP_ANNOUNCE_CREATE, - the_thread->Object.id, - name - ); - - } -#endif - - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; -} - -/*PAGE - * - * rtems_task_ident - * - * This directive returns the system ID associated with - * the thread name. - * - * Input parameters: - * name - user defined thread name - * node - node(s) to be searched - * id - pointer to thread id - * - * Output parameters: - * *id - thread id - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_ident( - rtems_name name, - unsigned32 node, - Objects_Id *id -) -{ - Objects_Name_to_id_errors status; - - if ( name == OBJECTS_ID_OF_SELF ) { - *id = _Thread_Executing->Object.id; - return RTEMS_SUCCESSFUL; - } - - status = _Objects_Name_to_id( &_RTEMS_tasks_Information, &name, node, id ); - - return _Status_Object_name_errors_to_status[ status ]; -} - -/*PAGE - * - * rtems_task_start - * - * This directive readies the thread identified by the "id" - * based on its current priorty, to await execution. A thread - * can be started only from the dormant state. - * - * Input parameters: - * id - thread id - * entry_point - start execution address of thread - * argument - thread argument - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_start( - rtems_id id, - rtems_task_entry entry_point, - unsigned32 argument -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - if ( entry_point == NULL ) - return RTEMS_INVALID_ADDRESS; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Dispatch(); - return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - if ( _Thread_Start( - the_thread, THREAD_START_NUMERIC, entry_point, NULL, argument ) ) { - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_INCORRECT_STATE; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_restart - * - * This directive readies the specified thread. It restores - * the thread environment to the original values established - * at thread creation and start time. A thread can be restarted - * from any state except the dormant state. - * - * Input parameters: - * id - thread id - * argument - thread argument - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_restart( - Objects_Id id, - unsigned32 argument -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Dispatch(); - return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - if ( _Thread_Restart( the_thread, NULL, argument ) ) { - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_INCORRECT_STATE; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_delete - * - * This directive allows a thread to delete itself or the thread - * identified in the id field. The executive halts execution - * of the thread and frees the thread control block. - * - * Input parameters: - * id - thread id - * - * Output parameters: - * nothing - if id is the requesting thread (always succeeds) - * RTEMS_SUCCESSFUL - if successful and id is - * not the requesting thread - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_delete( - Objects_Id id -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - Objects_Information *the_information; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Dispatch(); - return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - the_information = _Objects_Get_information( the_thread->Object.id ); - - if ( !the_information ) { - _Thread_Enable_dispatch(); - return RTEMS_INVALID_ID; - /* This should never happen if _Thread_Get() works right */ - } - - _Thread_Close( the_information, the_thread ); - - _RTEMS_tasks_Free( the_thread ); - -#if defined(RTEMS_MULTIPROCESSING) - if ( the_thread->is_global ) { - - _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id ); - - _RTEMS_tasks_MP_Send_process_packet( - RTEMS_TASKS_MP_ANNOUNCE_DELETE, - the_thread->Object.id, - 0 /* Not used */ - ); - } -#endif - - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_suspend - * - * This directive will place the specified thread in the "suspended" - * state. Note that the suspended state can be in addition to - * other waiting states. - * - * Input parameters: - * id - thread id - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_suspend( - Objects_Id id -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_SUSPEND_REQUEST, - id, - 0, /* Not used */ - 0, /* Not used */ - 0 /* Not used */ - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - if ( !_States_Is_suspended( the_thread->current_state ) ) { - _Thread_Set_state( the_thread, STATES_SUSPENDED ); - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_ALREADY_SUSPENDED; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_resume - * - * This directive will remove the specified thread - * from the suspended state. - * - * Input parameters: - * id - thread id - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_resume( - Objects_Id id -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_RESUME_REQUEST, - id, - 0, /* Not used */ - 0, /* Not used */ - 0 /* Not used */ - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - if ( _States_Is_suspended( the_thread->current_state ) ) { - _Thread_Resume( the_thread ); - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_INCORRECT_STATE; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_set_priority - * - * This directive changes the priority of the specified thread. - * The specified thread can be any thread in the system including - * the requesting thread. - * - * Input parameters: - * id - thread id (0 indicates requesting thread) - * new_priority - thread priority (0 indicates current priority) - * old_priority - pointer to previous priority - * - * Output parameters: - * old_priority - previous priority - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_set_priority( - Objects_Id id, - rtems_task_priority new_priority, - rtems_task_priority *old_priority -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - if ( new_priority != RTEMS_CURRENT_PRIORITY && - !_RTEMS_tasks_Priority_is_valid( new_priority ) ) - return RTEMS_INVALID_PRIORITY; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Executing->Wait.return_argument = old_priority; - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_SET_PRIORITY_REQUEST, - id, - new_priority, - 0, /* Not used */ - 0 /* Not used */ - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - *old_priority = the_thread->current_priority; - if ( new_priority != RTEMS_CURRENT_PRIORITY ) { - the_thread->real_priority = new_priority; - if ( the_thread->resource_count == 0 || - the_thread->current_priority > new_priority ) - _Thread_Change_priority( the_thread, new_priority, FALSE ); - } - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_mode - * - * This directive enables and disables several modes of - * execution for the requesting thread. - * - * Input parameters: - * mode_set - new mode - * mask - mask - * previous_mode_set - address of previous mode set - * - * Output: - * *previous_mode_set - previous mode set - * always return RTEMS_SUCCESSFUL; - */ - -rtems_status_code rtems_task_mode( - rtems_mode mode_set, - rtems_mode mask, - rtems_mode *previous_mode_set -) -{ - Thread_Control *executing; - RTEMS_API_Control *api; - ASR_Information *asr; - boolean is_asr_enabled = FALSE; - boolean needs_asr_dispatching = FALSE; - rtems_mode old_mode; - - executing = _Thread_Executing; - api = executing->API_Extensions[ THREAD_API_RTEMS ]; - asr = &api->Signal; - - old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT; - - if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE ) - old_mode |= RTEMS_NO_TIMESLICE; - else - old_mode |= RTEMS_TIMESLICE; - - old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR; - old_mode |= _ISR_Get_level(); - - *previous_mode_set = old_mode; - - /* - * These are generic thread scheduling characteristics. - */ - - if ( mask & RTEMS_PREEMPT_MASK ) - executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE; - - if ( mask & RTEMS_TIMESLICE_MASK ) { - if ( _Modes_Is_timeslice(mode_set) ) - executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE; - else - executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; - } - - /* - * Set the new interrupt level - */ - - if ( mask & RTEMS_INTERRUPT_MASK ) - _Modes_Set_interrupt_level( mode_set ); - - /* - * This is specific to the RTEMS API - */ - - is_asr_enabled = FALSE; - needs_asr_dispatching = FALSE; - - if ( mask & RTEMS_ASR_MASK ) { - is_asr_enabled = _Modes_Is_asr_disabled( mode_set ) ? FALSE : TRUE; - if ( is_asr_enabled != asr->is_enabled ) { - asr->is_enabled = is_asr_enabled; - _ASR_Swap_signals( asr ); - if ( _ASR_Are_signals_pending( asr ) ) { - needs_asr_dispatching = TRUE; - executing->do_post_task_switch_extension = TRUE; - } - } - } - - if ( _Thread_Evaluate_mode() || needs_asr_dispatching ) - _Thread_Dispatch(); - - return RTEMS_SUCCESSFUL; -} - -/*PAGE - * - * rtems_task_get_note - * - * This directive obtains the note from the specified notepad - * of the specified thread. - * - * Input parameters: - * id - thread id - * notepad - notepad number - * note - pointer to note - * - * Output parameters: - * note - filled in if successful - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_get_note( - Objects_Id id, - unsigned32 notepad, - unsigned32 *note -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - RTEMS_API_Control *api; - - /* - * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would - * be checking an unsigned number for being negative. - */ - - if ( notepad > RTEMS_NOTEPAD_LAST ) - return RTEMS_INVALID_NUMBER; - - /* - * Optimize the most likely case to avoid the Thread_Dispatch. - */ - - if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || - _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { - api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; - *note = api->Notepads[ notepad ]; - return RTEMS_SUCCESSFUL; - } - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Executing->Wait.return_argument = note; - - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_GET_NOTE_REQUEST, - id, - 0, /* Not used */ - notepad, - 0 /* Not used */ - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; - *note = api->Notepads[ notepad ]; - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_set_note - * - * This directive sets the specified notepad contents to the given - * note. - * - * Input parameters: - * id - thread id - * notepad - notepad number - * note - note value - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_set_note( - Objects_Id id, - unsigned32 notepad, - unsigned32 note -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - RTEMS_API_Control *api; - - /* - * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would - * be checking an unsigned number for being negative. - */ - - if ( notepad > RTEMS_NOTEPAD_LAST ) - return RTEMS_INVALID_NUMBER; - - /* - * Optimize the most likely case to avoid the Thread_Dispatch. - */ - - if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || - _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { - api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; - api->Notepads[ notepad ] = note; - return RTEMS_SUCCESSFUL; - } - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_SET_NOTE_REQUEST, - id, - 0, /* Not used */ - notepad, - note - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; - api->Notepads[ notepad ] = note; - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_wake_after - * - * This directive suspends the requesting thread for the given amount - * of ticks. - * - * Input parameters: - * ticks - number of ticks to wait - * - * Output parameters: - * RTEMS_SUCCESSFUL - always successful - */ - -rtems_status_code rtems_task_wake_after( - rtems_interval ticks -) -{ - _Thread_Disable_dispatch(); - if ( ticks == 0 ) { - _Thread_Yield_processor(); - } else { - _Thread_Set_state( _Thread_Executing, STATES_DELAYING ); - _Watchdog_Initialize( - &_Thread_Executing->Timer, - _Thread_Delay_ended, - _Thread_Executing->Object.id, - NULL - ); - _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks ); - } - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; -} - -/*PAGE - * - * rtems_task_wake_when - * - * This directive blocks the requesting thread until the given date and - * time is reached. - * - * Input parameters: - * time_buffer - pointer to the time and date structure - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_wake_when( -rtems_time_of_day *time_buffer -) -{ - Watchdog_Interval seconds; - - if ( !_TOD_Is_set ) - return RTEMS_NOT_DEFINED; - - time_buffer->ticks = 0; - - if ( !_TOD_Validate( time_buffer ) ) - return RTEMS_INVALID_CLOCK; - - seconds = _TOD_To_seconds( time_buffer ); - - if ( seconds <= _TOD_Seconds_since_epoch ) - return RTEMS_INVALID_CLOCK; - - _Thread_Disable_dispatch(); - _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME ); - _Watchdog_Initialize( - &_Thread_Executing->Timer, - _Thread_Delay_ended, - _Thread_Executing->Object.id, - NULL - ); - _Watchdog_Insert_seconds( - &_Thread_Executing->Timer, - seconds - _TOD_Seconds_since_epoch - ); - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; -} - -/*PAGE - * - * _RTEMS_tasks_Initialize_user_tasks - * - * This routine creates and starts all configured user - * initialzation threads. - * - * Input parameters: NONE - * - * Output parameters: NONE - */ - -void _RTEMS_tasks_Initialize_user_tasks( void ) -{ - unsigned32 index; - unsigned32 maximum; - rtems_id id; - rtems_status_code return_value; - rtems_initialization_tasks_table *user_tasks; - - /* - * NOTE: This is slightly different from the Ada implementation. - */ - - user_tasks = _RTEMS_tasks_User_initialization_tasks; - maximum = _RTEMS_tasks_Number_of_initialization_tasks; - - if ( !user_tasks || maximum == 0 ) - return; - - for ( index=0 ; index < maximum ; index++ ) { - return_value = rtems_task_create( - user_tasks[ index ].name, - user_tasks[ index ].initial_priority, - user_tasks[ index ].stack_size, - user_tasks[ index ].mode_set, - user_tasks[ index ].attribute_set, - &id - ); - - if ( !rtems_is_status_successful( return_value ) ) - _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value ); - - return_value = rtems_task_start( - id, - user_tasks[ index ].entry_point, - user_tasks[ index ].argument - ); - - if ( !rtems_is_status_successful( return_value ) ) - _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value ); - } -} - diff --git a/c/src/exec/rtems/src/tasksetnote.c b/c/src/exec/rtems/src/tasksetnote.c new file mode 100644 index 0000000000..982d111b7c --- /dev/null +++ b/c/src/exec/rtems/src/tasksetnote.c @@ -0,0 +1,103 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_set_note + * + * This directive sets the specified notepad contents to the given + * note. + * + * Input parameters: + * id - thread id + * notepad - notepad number + * note - note value + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_set_note( + Objects_Id id, + unsigned32 notepad, + unsigned32 note +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + + /* + * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would + * be checking an unsigned number for being negative. + */ + + if ( notepad > RTEMS_NOTEPAD_LAST ) + return RTEMS_INVALID_NUMBER; + + /* + * Optimize the most likely case to avoid the Thread_Dispatch. + */ + + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || + _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { + api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; + api->Notepads[ notepad ] = note; + return RTEMS_SUCCESSFUL; + } + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SET_NOTE_REQUEST, + id, + 0, /* Not used */ + notepad, + note + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + api->Notepads[ notepad ] = note; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/c/src/exec/rtems/src/tasksetpriority.c b/c/src/exec/rtems/src/tasksetpriority.c new file mode 100644 index 0000000000..f79ad581a5 --- /dev/null +++ b/c/src/exec/rtems/src/tasksetpriority.c @@ -0,0 +1,95 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_set_priority + * + * This directive changes the priority of the specified thread. + * The specified thread can be any thread in the system including + * the requesting thread. + * + * Input parameters: + * id - thread id (0 indicates requesting thread) + * new_priority - thread priority (0 indicates current priority) + * old_priority - pointer to previous priority + * + * Output parameters: + * old_priority - previous priority + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_set_priority( + Objects_Id id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + if ( new_priority != RTEMS_CURRENT_PRIORITY && + !_RTEMS_tasks_Priority_is_valid( new_priority ) ) + return RTEMS_INVALID_PRIORITY; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Executing->Wait.return_argument = old_priority; + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SET_PRIORITY_REQUEST, + id, + new_priority, + 0, /* Not used */ + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + *old_priority = the_thread->current_priority; + if ( new_priority != RTEMS_CURRENT_PRIORITY ) { + the_thread->real_priority = new_priority; + if ( the_thread->resource_count == 0 || + the_thread->current_priority > new_priority ) + _Thread_Change_priority( the_thread, new_priority, FALSE ); + } + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/c/src/exec/rtems/src/taskstart.c b/c/src/exec/rtems/src/taskstart.c new file mode 100644 index 0000000000..45a89eba63 --- /dev/null +++ b/c/src/exec/rtems/src/taskstart.c @@ -0,0 +1,85 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_start + * + * This directive readies the thread identified by the "id" + * based on its current priorty, to await execution. A thread + * can be started only from the dormant state. + * + * Input parameters: + * id - thread id + * entry_point - start execution address of thread + * argument - thread argument + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_start( + rtems_id id, + rtems_task_entry entry_point, + unsigned32 argument +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + if ( entry_point == NULL ) + return RTEMS_INVALID_ADDRESS; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + if ( _Thread_Start( + the_thread, THREAD_START_NUMERIC, entry_point, NULL, argument ) ) { + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/c/src/exec/rtems/src/tasksuspend.c b/c/src/exec/rtems/src/tasksuspend.c new file mode 100644 index 0000000000..c9635b0ff3 --- /dev/null +++ b/c/src/exec/rtems/src/tasksuspend.c @@ -0,0 +1,83 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_suspend + * + * This directive will place the specified thread in the "suspended" + * state. Note that the suspended state can be in addition to + * other waiting states. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_suspend( + Objects_Id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SUSPEND_REQUEST, + id, + 0, /* Not used */ + 0, /* Not used */ + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + if ( !_States_Is_suspended( the_thread->current_state ) ) { + _Thread_Set_state( the_thread, STATES_SUSPENDED ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_ALREADY_SUSPENDED; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/c/src/exec/rtems/src/taskwakeafter.c b/c/src/exec/rtems/src/taskwakeafter.c new file mode 100644 index 0000000000..5e83aaee5e --- /dev/null +++ b/c/src/exec/rtems/src/taskwakeafter.c @@ -0,0 +1,65 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_wake_after + * + * This directive suspends the requesting thread for the given amount + * of ticks. + * + * Input parameters: + * ticks - number of ticks to wait + * + * Output parameters: + * RTEMS_SUCCESSFUL - always successful + */ + +rtems_status_code rtems_task_wake_after( + rtems_interval ticks +) +{ + _Thread_Disable_dispatch(); + if ( ticks == 0 ) { + _Thread_Yield_processor(); + } else { + _Thread_Set_state( _Thread_Executing, STATES_DELAYING ); + _Watchdog_Initialize( + &_Thread_Executing->Timer, + _Thread_Delay_ended, + _Thread_Executing->Object.id, + NULL + ); + _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks ); + } + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/exec/rtems/src/taskwakewhen.c b/c/src/exec/rtems/src/taskwakewhen.c new file mode 100644 index 0000000000..238bbb7dcd --- /dev/null +++ b/c/src/exec/rtems/src/taskwakewhen.c @@ -0,0 +1,80 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_wake_when + * + * This directive blocks the requesting thread until the given date and + * time is reached. + * + * Input parameters: + * time_buffer - pointer to the time and date structure + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_wake_when( +rtems_time_of_day *time_buffer +) +{ + Watchdog_Interval seconds; + + if ( !_TOD_Is_set ) + return RTEMS_NOT_DEFINED; + + time_buffer->ticks = 0; + + if ( !_TOD_Validate( time_buffer ) ) + return RTEMS_INVALID_CLOCK; + + seconds = _TOD_To_seconds( time_buffer ); + + if ( seconds <= _TOD_Seconds_since_epoch ) + return RTEMS_INVALID_CLOCK; + + _Thread_Disable_dispatch(); + _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME ); + _Watchdog_Initialize( + &_Thread_Executing->Timer, + _Thread_Delay_ended, + _Thread_Executing->Object.id, + NULL + ); + _Watchdog_Insert_seconds( + &_Thread_Executing->Timer, + seconds - _TOD_Seconds_since_epoch + ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c new file mode 100644 index 0000000000..c5945a5332 --- /dev/null +++ b/cpukit/rtems/src/taskcreate.c @@ -0,0 +1,229 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_create + * + * This directive creates a thread by allocating and initializing a + * thread control block and a stack. The newly created thread is + * placed in the dormant state. + * + * Input parameters: + * name - user defined thread name + * initial_priority - thread priority + * stack_size - stack size in bytes + * initial_modes - initial thread mode + * attribute_set - thread attributes + * id - pointer to thread id + * + * Output parameters: + * id - thread id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_create( + rtems_name name, + rtems_task_priority initial_priority, + unsigned32 stack_size, + rtems_mode initial_modes, + rtems_attribute attribute_set, + Objects_Id *id +) +{ + register Thread_Control *the_thread; + boolean is_fp; +#if defined(RTEMS_MULTIPROCESSING) + Objects_MP_Control *the_global_object = NULL; + boolean is_global; +#endif + boolean status; + rtems_attribute the_attribute_set; + Priority_Control core_priority; + RTEMS_API_Control *api; + ASR_Information *asr; + + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + /* + * Core Thread Initialize insures we get the minimum amount of + * stack space. + */ + +#if 0 + if ( !_Stack_Is_enough( stack_size ) ) + return RTEMS_INVALID_SIZE; +#endif + + /* + * Fix the attribute set to match the attributes which + * this processor (1) requires and (2) is able to support. + * First add in the required flags for attribute_set + * Typically this might include FP if the platform + * or application required all tasks to be fp aware. + * Then turn off the requested bits which are not supported. + */ + + the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED ); + the_attribute_set = + _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED ); + + if ( _Attributes_Is_floating_point( the_attribute_set ) ) + is_fp = TRUE; + else + is_fp = FALSE; + + /* + * Validate the RTEMS API priority and convert it to the core priority range. + */ + + if ( !_Attributes_Is_system_task( the_attribute_set ) ) { + if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) ) + return RTEMS_INVALID_PRIORITY; + } + + core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority ); + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( the_attribute_set ) ) { + + is_global = TRUE; + + if ( !_System_state_Is_multiprocessing ) + return RTEMS_MP_NOT_CONFIGURED; + + } else + is_global = FALSE; +#endif + + /* + * Make sure system is MP if this task is global + */ + + /* + * Disable dispatch for protection + */ + + _Thread_Disable_dispatch(); + + /* + * Allocate the thread control block and -- if the task is global -- + * allocate a global object control block. + * + * NOTE: This routine does not use the combined allocate and open + * global object routine because this results in a lack of + * control over when memory is allocated and can be freed in + * the event of an error. + */ + + the_thread = _RTEMS_tasks_Allocate(); + + if ( !the_thread ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) { + the_global_object = _Objects_MP_Allocate_global_object(); + + if ( _Objects_MP_Is_null_global_object( the_global_object ) ) { + _RTEMS_tasks_Free( the_thread ); + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + } +#endif + + /* + * Initialize the core thread for this task. + */ + + status = _Thread_Initialize( + &_RTEMS_tasks_Information, + the_thread, + NULL, + stack_size, + is_fp, + core_priority, + _Modes_Is_preempt(initial_modes) ? TRUE : FALSE, + _Modes_Is_timeslice(initial_modes) ? + THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE : + THREAD_CPU_BUDGET_ALGORITHM_NONE, + NULL, /* no budget algorithm callout */ + _Modes_Get_interrupt_level(initial_modes), + &name + ); + + if ( !status ) { +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) + _Objects_MP_Free_global_object( the_global_object ); +#endif + _RTEMS_tasks_Free( the_thread ); + _Thread_Enable_dispatch(); + return RTEMS_UNSATISFIED; + } + + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + asr = &api->Signal; + + asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? FALSE : TRUE; + + *id = the_thread->Object.id; + +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) { + + the_thread->is_global = TRUE; + + _Objects_MP_Open( + &_RTEMS_tasks_Information, + the_global_object, + name, + the_thread->Object.id + ); + + _RTEMS_tasks_MP_Send_process_packet( + RTEMS_TASKS_MP_ANNOUNCE_CREATE, + the_thread->Object.id, + name + ); + + } +#endif + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/taskdelete.c b/cpukit/rtems/src/taskdelete.c new file mode 100644 index 0000000000..b9a8a47d7a --- /dev/null +++ b/cpukit/rtems/src/taskdelete.c @@ -0,0 +1,101 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_delete + * + * This directive allows a thread to delete itself or the thread + * identified in the id field. The executive halts execution + * of the thread and frees the thread control block. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * nothing - if id is the requesting thread (always succeeds) + * RTEMS_SUCCESSFUL - if successful and id is + * not the requesting thread + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_delete( + Objects_Id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + Objects_Information *the_information; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + the_information = _Objects_Get_information( the_thread->Object.id ); + + if ( !the_information ) { + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ID; + /* This should never happen if _Thread_Get() works right */ + } + + _Thread_Close( the_information, the_thread ); + + _RTEMS_tasks_Free( the_thread ); + +#if defined(RTEMS_MULTIPROCESSING) + if ( the_thread->is_global ) { + + _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id ); + + _RTEMS_tasks_MP_Send_process_packet( + RTEMS_TASKS_MP_ANNOUNCE_DELETE, + the_thread->Object.id, + 0 /* Not used */ + ); + } +#endif + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/taskgetnote.c b/cpukit/rtems/src/taskgetnote.c new file mode 100644 index 0000000000..dafbbaba3b --- /dev/null +++ b/cpukit/rtems/src/taskgetnote.c @@ -0,0 +1,106 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_get_note + * + * This directive obtains the note from the specified notepad + * of the specified thread. + * + * Input parameters: + * id - thread id + * notepad - notepad number + * note - pointer to note + * + * Output parameters: + * note - filled in if successful + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_get_note( + Objects_Id id, + unsigned32 notepad, + unsigned32 *note +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + + /* + * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would + * be checking an unsigned number for being negative. + */ + + if ( notepad > RTEMS_NOTEPAD_LAST ) + return RTEMS_INVALID_NUMBER; + + /* + * Optimize the most likely case to avoid the Thread_Dispatch. + */ + + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || + _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { + api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; + *note = api->Notepads[ notepad ]; + return RTEMS_SUCCESSFUL; + } + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Executing->Wait.return_argument = note; + + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_GET_NOTE_REQUEST, + id, + 0, /* Not used */ + notepad, + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + *note = api->Notepads[ notepad ]; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/taskident.c b/cpukit/rtems/src/taskident.c new file mode 100644 index 0000000000..ac2b707279 --- /dev/null +++ b/cpukit/rtems/src/taskident.c @@ -0,0 +1,66 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_ident + * + * This directive returns the system ID associated with + * the thread name. + * + * Input parameters: + * name - user defined thread name + * node - node(s) to be searched + * id - pointer to thread id + * + * Output parameters: + * *id - thread id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_ident( + rtems_name name, + unsigned32 node, + Objects_Id *id +) +{ + Objects_Name_to_id_errors status; + + if ( name == OBJECTS_ID_OF_SELF ) { + *id = _Thread_Executing->Object.id; + return RTEMS_SUCCESSFUL; + } + + status = _Objects_Name_to_id( &_RTEMS_tasks_Information, &name, node, id ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/taskinitusers.c b/cpukit/rtems/src/taskinitusers.c new file mode 100644 index 0000000000..648c059a22 --- /dev/null +++ b/cpukit/rtems/src/taskinitusers.c @@ -0,0 +1,84 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _RTEMS_tasks_Initialize_user_tasks + * + * This routine creates and starts all configured user + * initialzation threads. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _RTEMS_tasks_Initialize_user_tasks( void ) +{ + unsigned32 index; + unsigned32 maximum; + rtems_id id; + rtems_status_code return_value; + rtems_initialization_tasks_table *user_tasks; + + /* + * NOTE: This is slightly different from the Ada implementation. + */ + + user_tasks = _RTEMS_tasks_User_initialization_tasks; + maximum = _RTEMS_tasks_Number_of_initialization_tasks; + + if ( !user_tasks || maximum == 0 ) + return; + + for ( index=0 ; index < maximum ; index++ ) { + return_value = rtems_task_create( + user_tasks[ index ].name, + user_tasks[ index ].initial_priority, + user_tasks[ index ].stack_size, + user_tasks[ index ].mode_set, + user_tasks[ index ].attribute_set, + &id + ); + + if ( !rtems_is_status_successful( return_value ) ) + _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value ); + + return_value = rtems_task_start( + id, + user_tasks[ index ].entry_point, + user_tasks[ index ].argument + ); + + if ( !rtems_is_status_successful( return_value ) ) + _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value ); + } +} diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c new file mode 100644 index 0000000000..2dc96a8a5d --- /dev/null +++ b/cpukit/rtems/src/taskmode.c @@ -0,0 +1,122 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_mode + * + * This directive enables and disables several modes of + * execution for the requesting thread. + * + * Input parameters: + * mode_set - new mode + * mask - mask + * previous_mode_set - address of previous mode set + * + * Output: + * *previous_mode_set - previous mode set + * always return RTEMS_SUCCESSFUL; + */ + +rtems_status_code rtems_task_mode( + rtems_mode mode_set, + rtems_mode mask, + rtems_mode *previous_mode_set +) +{ + Thread_Control *executing; + RTEMS_API_Control *api; + ASR_Information *asr; + boolean is_asr_enabled = FALSE; + boolean needs_asr_dispatching = FALSE; + rtems_mode old_mode; + + executing = _Thread_Executing; + api = executing->API_Extensions[ THREAD_API_RTEMS ]; + asr = &api->Signal; + + old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT; + + if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE ) + old_mode |= RTEMS_NO_TIMESLICE; + else + old_mode |= RTEMS_TIMESLICE; + + old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR; + old_mode |= _ISR_Get_level(); + + *previous_mode_set = old_mode; + + /* + * These are generic thread scheduling characteristics. + */ + + if ( mask & RTEMS_PREEMPT_MASK ) + executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE; + + if ( mask & RTEMS_TIMESLICE_MASK ) { + if ( _Modes_Is_timeslice(mode_set) ) + executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE; + else + executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; + } + + /* + * Set the new interrupt level + */ + + if ( mask & RTEMS_INTERRUPT_MASK ) + _Modes_Set_interrupt_level( mode_set ); + + /* + * This is specific to the RTEMS API + */ + + is_asr_enabled = FALSE; + needs_asr_dispatching = FALSE; + + if ( mask & RTEMS_ASR_MASK ) { + is_asr_enabled = _Modes_Is_asr_disabled( mode_set ) ? FALSE : TRUE; + if ( is_asr_enabled != asr->is_enabled ) { + asr->is_enabled = is_asr_enabled; + _ASR_Swap_signals( asr ); + if ( _ASR_Are_signals_pending( asr ) ) { + needs_asr_dispatching = TRUE; + executing->do_post_task_switch_extension = TRUE; + } + } + } + + if ( _Thread_Evaluate_mode() || needs_asr_dispatching ) + _Thread_Dispatch(); + + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/taskrestart.c b/cpukit/rtems/src/taskrestart.c new file mode 100644 index 0000000000..14e11a06d7 --- /dev/null +++ b/cpukit/rtems/src/taskrestart.c @@ -0,0 +1,80 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_restart + * + * This directive readies the specified thread. It restores + * the thread environment to the original values established + * at thread creation and start time. A thread can be restarted + * from any state except the dormant state. + * + * Input parameters: + * id - thread id + * argument - thread argument + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_restart( + Objects_Id id, + unsigned32 argument +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + if ( _Thread_Restart( the_thread, NULL, argument ) ) { + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/taskresume.c b/cpukit/rtems/src/taskresume.c new file mode 100644 index 0000000000..70c2051eaf --- /dev/null +++ b/cpukit/rtems/src/taskresume.c @@ -0,0 +1,82 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_resume + * + * This directive will remove the specified thread + * from the suspended state. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_resume( + Objects_Id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_RESUME_REQUEST, + id, + 0, /* Not used */ + 0, /* Not used */ + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + if ( _States_Is_suspended( the_thread->current_state ) ) { + _Thread_Resume( the_thread ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c index 0f3596c800..589f53e86b 100644 --- a/cpukit/rtems/src/tasks.c +++ b/cpukit/rtems/src/tasks.c @@ -215,964 +215,3 @@ void _RTEMS_tasks_Manager_initialization( } -/*PAGE - * - * rtems_task_create - * - * This directive creates a thread by allocating and initializing a - * thread control block and a stack. The newly created thread is - * placed in the dormant state. - * - * Input parameters: - * name - user defined thread name - * initial_priority - thread priority - * stack_size - stack size in bytes - * initial_modes - initial thread mode - * attribute_set - thread attributes - * id - pointer to thread id - * - * Output parameters: - * id - thread id - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_create( - rtems_name name, - rtems_task_priority initial_priority, - unsigned32 stack_size, - rtems_mode initial_modes, - rtems_attribute attribute_set, - Objects_Id *id -) -{ - register Thread_Control *the_thread; - boolean is_fp; -#if defined(RTEMS_MULTIPROCESSING) - Objects_MP_Control *the_global_object = NULL; - boolean is_global; -#endif - boolean status; - rtems_attribute the_attribute_set; - Priority_Control core_priority; - RTEMS_API_Control *api; - ASR_Information *asr; - - - if ( !rtems_is_name_valid( name ) ) - return RTEMS_INVALID_NAME; - - /* - * Core Thread Initialize insures we get the minimum amount of - * stack space. - */ - -#if 0 - if ( !_Stack_Is_enough( stack_size ) ) - return RTEMS_INVALID_SIZE; -#endif - - /* - * Fix the attribute set to match the attributes which - * this processor (1) requires and (2) is able to support. - * First add in the required flags for attribute_set - * Typically this might include FP if the platform - * or application required all tasks to be fp aware. - * Then turn off the requested bits which are not supported. - */ - - the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED ); - the_attribute_set = - _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED ); - - if ( _Attributes_Is_floating_point( the_attribute_set ) ) - is_fp = TRUE; - else - is_fp = FALSE; - - /* - * Validate the RTEMS API priority and convert it to the core priority range. - */ - - if ( !_Attributes_Is_system_task( the_attribute_set ) ) { - if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) ) - return RTEMS_INVALID_PRIORITY; - } - - core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority ); - -#if defined(RTEMS_MULTIPROCESSING) - if ( _Attributes_Is_global( the_attribute_set ) ) { - - is_global = TRUE; - - if ( !_System_state_Is_multiprocessing ) - return RTEMS_MP_NOT_CONFIGURED; - - } else - is_global = FALSE; -#endif - - /* - * Make sure system is MP if this task is global - */ - - /* - * Disable dispatch for protection - */ - - _Thread_Disable_dispatch(); - - /* - * Allocate the thread control block and -- if the task is global -- - * allocate a global object control block. - * - * NOTE: This routine does not use the combined allocate and open - * global object routine because this results in a lack of - * control over when memory is allocated and can be freed in - * the event of an error. - */ - - the_thread = _RTEMS_tasks_Allocate(); - - if ( !the_thread ) { - _Thread_Enable_dispatch(); - return RTEMS_TOO_MANY; - } - -#if defined(RTEMS_MULTIPROCESSING) - if ( is_global ) { - the_global_object = _Objects_MP_Allocate_global_object(); - - if ( _Objects_MP_Is_null_global_object( the_global_object ) ) { - _RTEMS_tasks_Free( the_thread ); - _Thread_Enable_dispatch(); - return RTEMS_TOO_MANY; - } - } -#endif - - /* - * Initialize the core thread for this task. - */ - - status = _Thread_Initialize( - &_RTEMS_tasks_Information, - the_thread, - NULL, - stack_size, - is_fp, - core_priority, - _Modes_Is_preempt(initial_modes) ? TRUE : FALSE, - _Modes_Is_timeslice(initial_modes) ? - THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE : - THREAD_CPU_BUDGET_ALGORITHM_NONE, - NULL, /* no budget algorithm callout */ - _Modes_Get_interrupt_level(initial_modes), - &name - ); - - if ( !status ) { -#if defined(RTEMS_MULTIPROCESSING) - if ( is_global ) - _Objects_MP_Free_global_object( the_global_object ); -#endif - _RTEMS_tasks_Free( the_thread ); - _Thread_Enable_dispatch(); - return RTEMS_UNSATISFIED; - } - - api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; - asr = &api->Signal; - - asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? FALSE : TRUE; - - *id = the_thread->Object.id; - -#if defined(RTEMS_MULTIPROCESSING) - if ( is_global ) { - - the_thread->is_global = TRUE; - - _Objects_MP_Open( - &_RTEMS_tasks_Information, - the_global_object, - name, - the_thread->Object.id - ); - - _RTEMS_tasks_MP_Send_process_packet( - RTEMS_TASKS_MP_ANNOUNCE_CREATE, - the_thread->Object.id, - name - ); - - } -#endif - - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; -} - -/*PAGE - * - * rtems_task_ident - * - * This directive returns the system ID associated with - * the thread name. - * - * Input parameters: - * name - user defined thread name - * node - node(s) to be searched - * id - pointer to thread id - * - * Output parameters: - * *id - thread id - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_ident( - rtems_name name, - unsigned32 node, - Objects_Id *id -) -{ - Objects_Name_to_id_errors status; - - if ( name == OBJECTS_ID_OF_SELF ) { - *id = _Thread_Executing->Object.id; - return RTEMS_SUCCESSFUL; - } - - status = _Objects_Name_to_id( &_RTEMS_tasks_Information, &name, node, id ); - - return _Status_Object_name_errors_to_status[ status ]; -} - -/*PAGE - * - * rtems_task_start - * - * This directive readies the thread identified by the "id" - * based on its current priorty, to await execution. A thread - * can be started only from the dormant state. - * - * Input parameters: - * id - thread id - * entry_point - start execution address of thread - * argument - thread argument - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_start( - rtems_id id, - rtems_task_entry entry_point, - unsigned32 argument -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - if ( entry_point == NULL ) - return RTEMS_INVALID_ADDRESS; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Dispatch(); - return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - if ( _Thread_Start( - the_thread, THREAD_START_NUMERIC, entry_point, NULL, argument ) ) { - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_INCORRECT_STATE; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_restart - * - * This directive readies the specified thread. It restores - * the thread environment to the original values established - * at thread creation and start time. A thread can be restarted - * from any state except the dormant state. - * - * Input parameters: - * id - thread id - * argument - thread argument - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_restart( - Objects_Id id, - unsigned32 argument -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Dispatch(); - return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - if ( _Thread_Restart( the_thread, NULL, argument ) ) { - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_INCORRECT_STATE; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_delete - * - * This directive allows a thread to delete itself or the thread - * identified in the id field. The executive halts execution - * of the thread and frees the thread control block. - * - * Input parameters: - * id - thread id - * - * Output parameters: - * nothing - if id is the requesting thread (always succeeds) - * RTEMS_SUCCESSFUL - if successful and id is - * not the requesting thread - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_delete( - Objects_Id id -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - Objects_Information *the_information; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Dispatch(); - return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - the_information = _Objects_Get_information( the_thread->Object.id ); - - if ( !the_information ) { - _Thread_Enable_dispatch(); - return RTEMS_INVALID_ID; - /* This should never happen if _Thread_Get() works right */ - } - - _Thread_Close( the_information, the_thread ); - - _RTEMS_tasks_Free( the_thread ); - -#if defined(RTEMS_MULTIPROCESSING) - if ( the_thread->is_global ) { - - _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id ); - - _RTEMS_tasks_MP_Send_process_packet( - RTEMS_TASKS_MP_ANNOUNCE_DELETE, - the_thread->Object.id, - 0 /* Not used */ - ); - } -#endif - - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_suspend - * - * This directive will place the specified thread in the "suspended" - * state. Note that the suspended state can be in addition to - * other waiting states. - * - * Input parameters: - * id - thread id - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_suspend( - Objects_Id id -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_SUSPEND_REQUEST, - id, - 0, /* Not used */ - 0, /* Not used */ - 0 /* Not used */ - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - if ( !_States_Is_suspended( the_thread->current_state ) ) { - _Thread_Set_state( the_thread, STATES_SUSPENDED ); - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_ALREADY_SUSPENDED; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_resume - * - * This directive will remove the specified thread - * from the suspended state. - * - * Input parameters: - * id - thread id - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_resume( - Objects_Id id -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_RESUME_REQUEST, - id, - 0, /* Not used */ - 0, /* Not used */ - 0 /* Not used */ - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - if ( _States_Is_suspended( the_thread->current_state ) ) { - _Thread_Resume( the_thread ); - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_INCORRECT_STATE; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_set_priority - * - * This directive changes the priority of the specified thread. - * The specified thread can be any thread in the system including - * the requesting thread. - * - * Input parameters: - * id - thread id (0 indicates requesting thread) - * new_priority - thread priority (0 indicates current priority) - * old_priority - pointer to previous priority - * - * Output parameters: - * old_priority - previous priority - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_set_priority( - Objects_Id id, - rtems_task_priority new_priority, - rtems_task_priority *old_priority -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - - if ( new_priority != RTEMS_CURRENT_PRIORITY && - !_RTEMS_tasks_Priority_is_valid( new_priority ) ) - return RTEMS_INVALID_PRIORITY; - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Executing->Wait.return_argument = old_priority; - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_SET_PRIORITY_REQUEST, - id, - new_priority, - 0, /* Not used */ - 0 /* Not used */ - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - *old_priority = the_thread->current_priority; - if ( new_priority != RTEMS_CURRENT_PRIORITY ) { - the_thread->real_priority = new_priority; - if ( the_thread->resource_count == 0 || - the_thread->current_priority > new_priority ) - _Thread_Change_priority( the_thread, new_priority, FALSE ); - } - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_mode - * - * This directive enables and disables several modes of - * execution for the requesting thread. - * - * Input parameters: - * mode_set - new mode - * mask - mask - * previous_mode_set - address of previous mode set - * - * Output: - * *previous_mode_set - previous mode set - * always return RTEMS_SUCCESSFUL; - */ - -rtems_status_code rtems_task_mode( - rtems_mode mode_set, - rtems_mode mask, - rtems_mode *previous_mode_set -) -{ - Thread_Control *executing; - RTEMS_API_Control *api; - ASR_Information *asr; - boolean is_asr_enabled = FALSE; - boolean needs_asr_dispatching = FALSE; - rtems_mode old_mode; - - executing = _Thread_Executing; - api = executing->API_Extensions[ THREAD_API_RTEMS ]; - asr = &api->Signal; - - old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT; - - if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE ) - old_mode |= RTEMS_NO_TIMESLICE; - else - old_mode |= RTEMS_TIMESLICE; - - old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR; - old_mode |= _ISR_Get_level(); - - *previous_mode_set = old_mode; - - /* - * These are generic thread scheduling characteristics. - */ - - if ( mask & RTEMS_PREEMPT_MASK ) - executing->is_preemptible = _Modes_Is_preempt(mode_set) ? TRUE : FALSE; - - if ( mask & RTEMS_TIMESLICE_MASK ) { - if ( _Modes_Is_timeslice(mode_set) ) - executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE; - else - executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; - } - - /* - * Set the new interrupt level - */ - - if ( mask & RTEMS_INTERRUPT_MASK ) - _Modes_Set_interrupt_level( mode_set ); - - /* - * This is specific to the RTEMS API - */ - - is_asr_enabled = FALSE; - needs_asr_dispatching = FALSE; - - if ( mask & RTEMS_ASR_MASK ) { - is_asr_enabled = _Modes_Is_asr_disabled( mode_set ) ? FALSE : TRUE; - if ( is_asr_enabled != asr->is_enabled ) { - asr->is_enabled = is_asr_enabled; - _ASR_Swap_signals( asr ); - if ( _ASR_Are_signals_pending( asr ) ) { - needs_asr_dispatching = TRUE; - executing->do_post_task_switch_extension = TRUE; - } - } - } - - if ( _Thread_Evaluate_mode() || needs_asr_dispatching ) - _Thread_Dispatch(); - - return RTEMS_SUCCESSFUL; -} - -/*PAGE - * - * rtems_task_get_note - * - * This directive obtains the note from the specified notepad - * of the specified thread. - * - * Input parameters: - * id - thread id - * notepad - notepad number - * note - pointer to note - * - * Output parameters: - * note - filled in if successful - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_get_note( - Objects_Id id, - unsigned32 notepad, - unsigned32 *note -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - RTEMS_API_Control *api; - - /* - * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would - * be checking an unsigned number for being negative. - */ - - if ( notepad > RTEMS_NOTEPAD_LAST ) - return RTEMS_INVALID_NUMBER; - - /* - * Optimize the most likely case to avoid the Thread_Dispatch. - */ - - if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || - _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { - api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; - *note = api->Notepads[ notepad ]; - return RTEMS_SUCCESSFUL; - } - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - _Thread_Executing->Wait.return_argument = note; - - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_GET_NOTE_REQUEST, - id, - 0, /* Not used */ - notepad, - 0 /* Not used */ - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; - *note = api->Notepads[ notepad ]; - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_set_note - * - * This directive sets the specified notepad contents to the given - * note. - * - * Input parameters: - * id - thread id - * notepad - notepad number - * note - note value - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_set_note( - Objects_Id id, - unsigned32 notepad, - unsigned32 note -) -{ - register Thread_Control *the_thread; - Objects_Locations location; - RTEMS_API_Control *api; - - /* - * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would - * be checking an unsigned number for being negative. - */ - - if ( notepad > RTEMS_NOTEPAD_LAST ) - return RTEMS_INVALID_NUMBER; - - /* - * Optimize the most likely case to avoid the Thread_Dispatch. - */ - - if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || - _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { - api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; - api->Notepads[ notepad ] = note; - return RTEMS_SUCCESSFUL; - } - - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: -#if defined(RTEMS_MULTIPROCESSING) - return _RTEMS_tasks_MP_Send_request_packet( - RTEMS_TASKS_MP_SET_NOTE_REQUEST, - id, - 0, /* Not used */ - notepad, - note - ); -#endif - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; - api->Notepads[ notepad ] = note; - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_task_wake_after - * - * This directive suspends the requesting thread for the given amount - * of ticks. - * - * Input parameters: - * ticks - number of ticks to wait - * - * Output parameters: - * RTEMS_SUCCESSFUL - always successful - */ - -rtems_status_code rtems_task_wake_after( - rtems_interval ticks -) -{ - _Thread_Disable_dispatch(); - if ( ticks == 0 ) { - _Thread_Yield_processor(); - } else { - _Thread_Set_state( _Thread_Executing, STATES_DELAYING ); - _Watchdog_Initialize( - &_Thread_Executing->Timer, - _Thread_Delay_ended, - _Thread_Executing->Object.id, - NULL - ); - _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks ); - } - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; -} - -/*PAGE - * - * rtems_task_wake_when - * - * This directive blocks the requesting thread until the given date and - * time is reached. - * - * Input parameters: - * time_buffer - pointer to the time and date structure - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_task_wake_when( -rtems_time_of_day *time_buffer -) -{ - Watchdog_Interval seconds; - - if ( !_TOD_Is_set ) - return RTEMS_NOT_DEFINED; - - time_buffer->ticks = 0; - - if ( !_TOD_Validate( time_buffer ) ) - return RTEMS_INVALID_CLOCK; - - seconds = _TOD_To_seconds( time_buffer ); - - if ( seconds <= _TOD_Seconds_since_epoch ) - return RTEMS_INVALID_CLOCK; - - _Thread_Disable_dispatch(); - _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME ); - _Watchdog_Initialize( - &_Thread_Executing->Timer, - _Thread_Delay_ended, - _Thread_Executing->Object.id, - NULL - ); - _Watchdog_Insert_seconds( - &_Thread_Executing->Timer, - seconds - _TOD_Seconds_since_epoch - ); - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; -} - -/*PAGE - * - * _RTEMS_tasks_Initialize_user_tasks - * - * This routine creates and starts all configured user - * initialzation threads. - * - * Input parameters: NONE - * - * Output parameters: NONE - */ - -void _RTEMS_tasks_Initialize_user_tasks( void ) -{ - unsigned32 index; - unsigned32 maximum; - rtems_id id; - rtems_status_code return_value; - rtems_initialization_tasks_table *user_tasks; - - /* - * NOTE: This is slightly different from the Ada implementation. - */ - - user_tasks = _RTEMS_tasks_User_initialization_tasks; - maximum = _RTEMS_tasks_Number_of_initialization_tasks; - - if ( !user_tasks || maximum == 0 ) - return; - - for ( index=0 ; index < maximum ; index++ ) { - return_value = rtems_task_create( - user_tasks[ index ].name, - user_tasks[ index ].initial_priority, - user_tasks[ index ].stack_size, - user_tasks[ index ].mode_set, - user_tasks[ index ].attribute_set, - &id - ); - - if ( !rtems_is_status_successful( return_value ) ) - _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value ); - - return_value = rtems_task_start( - id, - user_tasks[ index ].entry_point, - user_tasks[ index ].argument - ); - - if ( !rtems_is_status_successful( return_value ) ) - _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, TRUE, return_value ); - } -} - diff --git a/cpukit/rtems/src/tasksetnote.c b/cpukit/rtems/src/tasksetnote.c new file mode 100644 index 0000000000..982d111b7c --- /dev/null +++ b/cpukit/rtems/src/tasksetnote.c @@ -0,0 +1,103 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_set_note + * + * This directive sets the specified notepad contents to the given + * note. + * + * Input parameters: + * id - thread id + * notepad - notepad number + * note - note value + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_set_note( + Objects_Id id, + unsigned32 notepad, + unsigned32 note +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + + /* + * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would + * be checking an unsigned number for being negative. + */ + + if ( notepad > RTEMS_NOTEPAD_LAST ) + return RTEMS_INVALID_NUMBER; + + /* + * Optimize the most likely case to avoid the Thread_Dispatch. + */ + + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || + _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { + api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; + api->Notepads[ notepad ] = note; + return RTEMS_SUCCESSFUL; + } + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SET_NOTE_REQUEST, + id, + 0, /* Not used */ + notepad, + note + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + api->Notepads[ notepad ] = note; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/tasksetpriority.c b/cpukit/rtems/src/tasksetpriority.c new file mode 100644 index 0000000000..f79ad581a5 --- /dev/null +++ b/cpukit/rtems/src/tasksetpriority.c @@ -0,0 +1,95 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_set_priority + * + * This directive changes the priority of the specified thread. + * The specified thread can be any thread in the system including + * the requesting thread. + * + * Input parameters: + * id - thread id (0 indicates requesting thread) + * new_priority - thread priority (0 indicates current priority) + * old_priority - pointer to previous priority + * + * Output parameters: + * old_priority - previous priority + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_set_priority( + Objects_Id id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + if ( new_priority != RTEMS_CURRENT_PRIORITY && + !_RTEMS_tasks_Priority_is_valid( new_priority ) ) + return RTEMS_INVALID_PRIORITY; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Executing->Wait.return_argument = old_priority; + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SET_PRIORITY_REQUEST, + id, + new_priority, + 0, /* Not used */ + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + *old_priority = the_thread->current_priority; + if ( new_priority != RTEMS_CURRENT_PRIORITY ) { + the_thread->real_priority = new_priority; + if ( the_thread->resource_count == 0 || + the_thread->current_priority > new_priority ) + _Thread_Change_priority( the_thread, new_priority, FALSE ); + } + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/taskstart.c b/cpukit/rtems/src/taskstart.c new file mode 100644 index 0000000000..45a89eba63 --- /dev/null +++ b/cpukit/rtems/src/taskstart.c @@ -0,0 +1,85 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_start + * + * This directive readies the thread identified by the "id" + * based on its current priorty, to await execution. A thread + * can be started only from the dormant state. + * + * Input parameters: + * id - thread id + * entry_point - start execution address of thread + * argument - thread argument + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_start( + rtems_id id, + rtems_task_entry entry_point, + unsigned32 argument +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + if ( entry_point == NULL ) + return RTEMS_INVALID_ADDRESS; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + if ( _Thread_Start( + the_thread, THREAD_START_NUMERIC, entry_point, NULL, argument ) ) { + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/tasksuspend.c b/cpukit/rtems/src/tasksuspend.c new file mode 100644 index 0000000000..c9635b0ff3 --- /dev/null +++ b/cpukit/rtems/src/tasksuspend.c @@ -0,0 +1,83 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_suspend + * + * This directive will place the specified thread in the "suspended" + * state. Note that the suspended state can be in addition to + * other waiting states. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_suspend( + Objects_Id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SUSPEND_REQUEST, + id, + 0, /* Not used */ + 0, /* Not used */ + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + if ( !_States_Is_suspended( the_thread->current_state ) ) { + _Thread_Set_state( the_thread, STATES_SUSPENDED ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_ALREADY_SUSPENDED; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/taskwakeafter.c b/cpukit/rtems/src/taskwakeafter.c new file mode 100644 index 0000000000..5e83aaee5e --- /dev/null +++ b/cpukit/rtems/src/taskwakeafter.c @@ -0,0 +1,65 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_wake_after + * + * This directive suspends the requesting thread for the given amount + * of ticks. + * + * Input parameters: + * ticks - number of ticks to wait + * + * Output parameters: + * RTEMS_SUCCESSFUL - always successful + */ + +rtems_status_code rtems_task_wake_after( + rtems_interval ticks +) +{ + _Thread_Disable_dispatch(); + if ( ticks == 0 ) { + _Thread_Yield_processor(); + } else { + _Thread_Set_state( _Thread_Executing, STATES_DELAYING ); + _Watchdog_Initialize( + &_Thread_Executing->Timer, + _Thread_Delay_ended, + _Thread_Executing->Object.id, + NULL + ); + _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks ); + } + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/taskwakewhen.c b/cpukit/rtems/src/taskwakewhen.c new file mode 100644 index 0000000000..238bbb7dcd --- /dev/null +++ b/cpukit/rtems/src/taskwakewhen.c @@ -0,0 +1,80 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_wake_when + * + * This directive blocks the requesting thread until the given date and + * time is reached. + * + * Input parameters: + * time_buffer - pointer to the time and date structure + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_wake_when( +rtems_time_of_day *time_buffer +) +{ + Watchdog_Interval seconds; + + if ( !_TOD_Is_set ) + return RTEMS_NOT_DEFINED; + + time_buffer->ticks = 0; + + if ( !_TOD_Validate( time_buffer ) ) + return RTEMS_INVALID_CLOCK; + + seconds = _TOD_To_seconds( time_buffer ); + + if ( seconds <= _TOD_Seconds_since_epoch ) + return RTEMS_INVALID_CLOCK; + + _Thread_Disable_dispatch(); + _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME ); + _Watchdog_Initialize( + &_Thread_Executing->Timer, + _Thread_Delay_ended, + _Thread_Executing->Object.id, + NULL + ); + _Watchdog_Insert_seconds( + &_Thread_Executing->Timer, + seconds - _TOD_Seconds_since_epoch + ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} -- cgit v1.2.3