Added per task variables based on patch from Eric Norum <eric@cls.usask.ca>.

After being submitted, this support was rewritten to be inside the
executive rather than layered on top of it using an extension.
This commit is contained in:
Joel Sherrill
1999-11-12 14:38:19 +00:00
parent 3c49a508aa
commit 5aa5560746
7 changed files with 446 additions and 7 deletions
+2 -1
View File
@@ -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
+65 -3
View File
@@ -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 */
+86
View File
@@ -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 <rtems/system.h>
#include <rtems/rtems/tasks.h>
#include <rtems/score/wkspace.h>
/*
* 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 */
}
+71
View File
@@ -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 <rtems/system.h>
#include <rtems/rtems/tasks.h>
#include <rtems/score/wkspace.h>
/*
* 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 */
}
+65 -3
View File
@@ -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 */
+86
View File
@@ -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 <rtems/system.h>
#include <rtems/rtems/tasks.h>
#include <rtems/score/wkspace.h>
/*
* 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 */
}
+71
View File
@@ -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 <rtems/system.h>
#include <rtems/rtems/tasks.h>
#include <rtems/score/wkspace.h>
/*
* 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 */
}