summaryrefslogtreecommitdiffstats
path: root/cpukit/rtems
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-12 14:38:19 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-12 14:38:19 +0000
commit5aa5560746e012afa4f8685932fc5e2bf38b38ff (patch)
tree1540ec594530b44cc5d5fce7bc39dcd238879e7b /cpukit/rtems
parentCleaned up style. (diff)
downloadrtems-5aa5560746e012afa4f8685932fc5e2bf38b38ff.tar.bz2
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.
Diffstat (limited to 'cpukit/rtems')
-rw-r--r--cpukit/rtems/src/tasks.c68
-rw-r--r--cpukit/rtems/src/taskvariableadd.c86
-rw-r--r--cpukit/rtems/src/taskvariabledelete.c71
3 files changed, 222 insertions, 3 deletions
diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c
index c711a89de3..283d5e8f20 100644
--- a/cpukit/rtems/src/tasks.c
+++ b/cpukit/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/cpukit/rtems/src/taskvariableadd.c b/cpukit/rtems/src/taskvariableadd.c
new file mode 100644
index 0000000000..9307612fe6
--- /dev/null
+++ b/cpukit/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 <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 */
+}
+
diff --git a/cpukit/rtems/src/taskvariabledelete.c b/cpukit/rtems/src/taskvariabledelete.c
new file mode 100644
index 0000000000..8bc214665b
--- /dev/null
+++ b/cpukit/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 <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 */
+}