From 5aa5560746e012afa4f8685932fc5e2bf38b38ff Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 12 Nov 1999 14:38:19 +0000 Subject: Added per task variables based on patch from Eric Norum . After being submitted, this support was rewritten to be inside the executive rather than layered on top of it using an extension. --- c/src/exec/rtems/src/Makefile.in | 3 +- c/src/exec/rtems/src/tasks.c | 68 ++++++++++++++++++++++-- c/src/exec/rtems/src/taskvariableadd.c | 86 +++++++++++++++++++++++++++++++ c/src/exec/rtems/src/taskvariabledelete.c | 71 +++++++++++++++++++++++++ 4 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 c/src/exec/rtems/src/taskvariableadd.c create mode 100644 c/src/exec/rtems/src/taskvariabledelete.c (limited to 'c') diff --git a/c/src/exec/rtems/src/Makefile.in b/c/src/exec/rtems/src/Makefile.in index cb188e5a4f..a8ff531bcf 100644 --- a/c/src/exec/rtems/src/Makefile.in +++ b/c/src/exec/rtems/src/Makefile.in @@ -24,7 +24,8 @@ MP_C_PIECES = $(MP_C_PIECES_$(HAS_MP)_V) TASK_C_PIECES = tasks taskcreate taskdelete taskgetnote taskident \ taskinitusers taskissuspended taskmode taskrestart taskresume tasksetnote \ - tasksetpriority taskstart tasksuspend taskwakeafter taskwakewhen + tasksetpriority taskstart tasksuspend taskwakeafter taskwakewhen \ + taskvariableadd taskvariabledelete RATEMON_C_PIECES = ratemon ratemoncancel ratemoncreate ratemondelete \ ratemongetstatus ratemonident ratemonperiod ratemontimeout diff --git a/c/src/exec/rtems/src/tasks.c b/c/src/exec/rtems/src/tasks.c index c711a89de3..283d5e8f20 100644 --- a/c/src/exec/rtems/src/tasks.c +++ b/c/src/exec/rtems/src/tasks.c @@ -56,6 +56,7 @@ boolean _RTEMS_tasks_Create_extension( api->pending_events = EVENT_SETS_NONE_PENDING; _ASR_Initialize( &api->Signal ); + api->task_variables = NULL; return TRUE; } @@ -93,7 +94,28 @@ User_extensions_routine _RTEMS_tasks_Delete_extension( Thread_Control *deleted ) { - (void) _Workspace_Free( deleted->API_Extensions[ THREAD_API_RTEMS ] ); + RTEMS_API_Control *api; + struct rtems_task_variable_t *tvp, *next; + + api = executing->API_Extensions[ THREAD_API_RTEMS ]; + + /* + * Free per task variable memory + */ + + tvp = api->task_variables; + api->task_variables = NULL; + while (tvp) { + next = tvp->next; + _Workspace_Free( tvp ); + tvp = next; + } + + /* + * Free API specific memory + */ + + (void) _Workspace_Free( api ); deleted->API_Extensions[ THREAD_API_RTEMS ] = NULL; } @@ -106,6 +128,41 @@ User_extensions_routine _RTEMS_tasks_Delete_extension( */ void _RTEMS_tasks_Switch_extension( + Thread_Control *executing, + Thread_Control *heir +) +{ + RTEMS_API_Control *api; + struct rtems_task_variable_t *tvp; + + /* + * Per Task Variables + */ + + + api = executing->API_Extensions[ THREAD_API_RTEMS ]; + tvp = api->task_variables; + while (tvp) { + tvp->var = *tvp->ptr; + tvp = tvp->next; + } + + api = heir->API_Extensions[ THREAD_API_RTEMS ]; + tvp = api->task_variables; + while (tvp) { + *tvp->ptr = tvp->var; + tvp = tvp->next; + } +} + +/*PAGE + * + * _RTEMS_tasks_Post_switch_extension + * + * This extension routine is invoked at each context switch. + */ + +void _RTEMS_tasks_Post_switch_extension( Thread_Control *executing ) { @@ -116,6 +173,11 @@ void _RTEMS_tasks_Switch_extension( Modes_Control prev_mode; api = executing->API_Extensions[ THREAD_API_RTEMS ]; + + /* + * Signal Processing + */ + asr = &api->Signal; _ISR_Disable( level ); @@ -141,7 +203,7 @@ API_extensions_Control _RTEMS_tasks_API_extensions = { { NULL, NULL }, NULL, /* predriver */ _RTEMS_tasks_Initialize_user_tasks, /* postdriver */ - _RTEMS_tasks_Switch_extension /* post switch */ + _RTEMS_tasks_Post_switch_extension /* post switch */ }; User_extensions_Control _RTEMS_tasks_User_extensions = { @@ -150,7 +212,7 @@ User_extensions_Control _RTEMS_tasks_User_extensions = { _RTEMS_tasks_Start_extension, /* start */ _RTEMS_tasks_Start_extension, /* restart */ _RTEMS_tasks_Delete_extension, /* delete */ - NULL, /* switch */ + _RTEMS_tasks_Switch_extension, /* switch */ NULL, /* begin */ NULL, /* exitted */ NULL /* fatal */ diff --git a/c/src/exec/rtems/src/taskvariableadd.c b/c/src/exec/rtems/src/taskvariableadd.c new file mode 100644 index 0000000000..9307612fe6 --- /dev/null +++ b/c/src/exec/rtems/src/taskvariableadd.c @@ -0,0 +1,86 @@ +/* + * rtems_task_variable_add - Add a per-task variable + * + * + * 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 + +/* + * rtems_task_variable_add + * + * This directive registers a task variable. + */ + +rtems_status_code rtems_task_variable_add( + rtems_id tid, + int *ptr +) +{ + Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + struct rtems_task_variable_t *tvp, *new; + + the_thread = _Thread_Get (tid, &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; + + default: + return RTEMS_INTERNAL_ERROR; + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + + /* + * Figure out if the variable is already in this task's list. + */ + + tvp = api->task_variables; + while (tvp) { + if (tvp->ptr == ptr) { + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + tvp = tvp->next; + } + + /* + * Now allocate memory for this task variable. + */ + + new = (struct rtems_task_variable_t *) + _Workspace_Allocate(sizeof(struct rtems_task_variable_t)); + if (new == NULL) { + _Thread_Enable_dispatch(); + return RTEMS_NO_MEMORY; + } + new->var = 0; + new->ptr = ptr; + + new->next = api->task_variables; + api->task_variables = new; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} + diff --git a/c/src/exec/rtems/src/taskvariabledelete.c b/c/src/exec/rtems/src/taskvariabledelete.c new file mode 100644 index 0000000000..8bc214665b --- /dev/null +++ b/c/src/exec/rtems/src/taskvariabledelete.c @@ -0,0 +1,71 @@ +/* + * rtems_task_variable_delete - Delete a per-task variable + * + * + * 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 + +/* + * rtems_task_variable_delete + * + * This directive removes a task variable. + */ + +rtems_status_code rtems_task_variable_delete( + rtems_id tid, + int *ptr +) +{ + Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + struct rtems_task_variable_t *tvp, *prev; + + prev = NULL; + + the_thread = _Thread_Get (tid, &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; + + default: + return RTEMS_INTERNAL_ERROR; + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + tvp = api->task_variables; + while (tvp) { + if (tvp->ptr == ptr) { + if (prev) prev->next = tvp->next; + else api->task_variables = tvp->next; + _Thread_Enable_dispatch(); + _Workspace_Free(tvp); + return RTEMS_SUCCESSFUL; + } + prev = tvp; + tvp = tvp->next; + } + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ADDRESS; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} -- cgit v1.2.3