Index: c/src/exec/rtems/src/Makefile.in
===================================================================
--- c/src/exec/rtems/src/Makefile.in	(revision 3c49a508aa3d554f724e28d420d0cb62bd6d93aa)
+++ c/src/exec/rtems/src/Makefile.in	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
@@ -25,5 +25,6 @@
 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 \
Index: c/src/exec/rtems/src/tasks.c
===================================================================
--- c/src/exec/rtems/src/tasks.c	(revision 3c49a508aa3d554f724e28d420d0cb62bd6d93aa)
+++ c/src/exec/rtems/src/tasks.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
@@ -57,4 +57,5 @@
   api->pending_events = EVENT_SETS_NONE_PENDING;
   _ASR_Initialize( &api->Signal );
+  api->task_variables = NULL;
   return TRUE;
 }
@@ -94,5 +95,26 @@
 )
 {
-  (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;
@@ -107,4 +129,39 @@
  
 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
 )
@@ -117,4 +174,9 @@
 
   api = executing->API_Extensions[ THREAD_API_RTEMS ];
+
+  /*
+   *  Signal Processing
+   */
+
   asr = &api->Signal;
  
@@ -142,5 +204,5 @@
   NULL,                                     /* predriver */
   _RTEMS_tasks_Initialize_user_tasks,       /* postdriver */
-  _RTEMS_tasks_Switch_extension             /* post switch */
+  _RTEMS_tasks_Post_switch_extension        /* post switch */
 };
 
@@ -151,5 +213,5 @@
     _RTEMS_tasks_Start_extension,             /* restart */
     _RTEMS_tasks_Delete_extension,            /* delete */
-    NULL,                                     /* switch */
+    _RTEMS_tasks_Switch_extension,            /* switch */
     NULL,                                     /* begin */
     NULL,                                     /* exitted */
Index: c/src/exec/rtems/src/taskvariableadd.c
===================================================================
--- c/src/exec/rtems/src/taskvariableadd.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
+++ c/src/exec/rtems/src/taskvariableadd.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
@@ -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 */
+}
+
Index: c/src/exec/rtems/src/taskvariabledelete.c
===================================================================
--- c/src/exec/rtems/src/taskvariabledelete.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
+++ c/src/exec/rtems/src/taskvariabledelete.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
@@ -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 */
+}
Index: cpukit/rtems/src/tasks.c
===================================================================
--- cpukit/rtems/src/tasks.c	(revision 3c49a508aa3d554f724e28d420d0cb62bd6d93aa)
+++ cpukit/rtems/src/tasks.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
@@ -57,4 +57,5 @@
   api->pending_events = EVENT_SETS_NONE_PENDING;
   _ASR_Initialize( &api->Signal );
+  api->task_variables = NULL;
   return TRUE;
 }
@@ -94,5 +95,26 @@
 )
 {
-  (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;
@@ -107,4 +129,39 @@
  
 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
 )
@@ -117,4 +174,9 @@
 
   api = executing->API_Extensions[ THREAD_API_RTEMS ];
+
+  /*
+   *  Signal Processing
+   */
+
   asr = &api->Signal;
  
@@ -142,5 +204,5 @@
   NULL,                                     /* predriver */
   _RTEMS_tasks_Initialize_user_tasks,       /* postdriver */
-  _RTEMS_tasks_Switch_extension             /* post switch */
+  _RTEMS_tasks_Post_switch_extension        /* post switch */
 };
 
@@ -151,5 +213,5 @@
     _RTEMS_tasks_Start_extension,             /* restart */
     _RTEMS_tasks_Delete_extension,            /* delete */
-    NULL,                                     /* switch */
+    _RTEMS_tasks_Switch_extension,            /* switch */
     NULL,                                     /* begin */
     NULL,                                     /* exitted */
Index: cpukit/rtems/src/taskvariableadd.c
===================================================================
--- cpukit/rtems/src/taskvariableadd.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
+++ cpukit/rtems/src/taskvariableadd.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
@@ -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 */
+}
+
Index: cpukit/rtems/src/taskvariabledelete.c
===================================================================
--- cpukit/rtems/src/taskvariabledelete.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
+++ cpukit/rtems/src/taskvariabledelete.c	(revision 5aa5560746e012afa4f8685932fc5e2bf38b38ff)
@@ -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 */
+}
