diff src/nucleus/tcc.c @ 0:92470e5d0b9e

src: partial import from FC Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 15 May 2020 01:28:16 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nucleus/tcc.c	Fri May 15 01:28:16 2020 +0000
@@ -0,0 +1,3060 @@
+/*************************************************************************/
+/*                                                                       */
+/*               Copyright Mentor Graphics Corporation 2002              */
+/*                         All Rights Reserved.                          */
+/*                                                                       */
+/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS  */
+/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS   */
+/* SUBJECT TO LICENSE TERMS.                                             */
+/*                                                                       */
+/*************************************************************************/
+
+/*************************************************************************/
+/*                                                                       */
+/* FILE NAME                                               VERSION       */
+/*                                                                       */
+/*      tcc.c                                          Nucleus PLUS 1.14 */
+/*                                                                       */
+/* COMPONENT                                                             */
+/*                                                                       */
+/*      TC - Thread Control                                              */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This file contains the core routines for the Thread Control      */
+/*      component.                                                       */
+/*                                                                       */
+/* DATA STRUCTURES                                                       */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* FUNCTIONS                                                             */
+/*                                                                       */
+/*      TCC_Create_Task                     Create a task                */
+/*      TCC_Delete_Task                     Delete a task                */
+/*      TCC_Create_HISR                     Create HISR                  */
+/*      TCC_Delete_HISR                     Delete HISR                  */
+/*      TCC_Reset_Task                      Reset the specified task     */
+/*      TCC_Terminate_Task                  Terminate the specified task */
+/*      TCC_Resume_Task                     Resume a task                */
+/*      TCC_Resume_Service                  Resume a task service call   */
+/*      TCC_Suspend_Task                    Suspend a task               */
+/*      TCC_Suspend_Service                 Suspend a task service call  */
+/*      TCC_Task_Timeout                    Task timeout function        */
+/*      TCC_Task_Sleep                      Task sleep request           */
+/*      TCC_Relinquish                      Relinquish task execution    */
+/*      TCC_Time_Slice                      Process task time-slice      */
+/*      TCC_Current_Task_Pointer            Retrieve current task pointer*/
+/*      TCC_Current_HISR_Pointer            Retrieve current HISR pointer*/
+/*      TCC_Task_Shell                      Task execution shell         */
+/*      TCC_Signal_Shell                    Signal execution shell       */
+/*      TCC_Dispatch_LISR                   Dispatch LISR routine        */
+/*      TCC_Register_LISR                   Register an LISR             */
+/*                                                                       */
+/* DEPENDENCIES                                                          */
+/*                                                                       */
+/*      cs_extr.h                           Common Service functions     */
+/*      tc_extr.h                           Thread Control functions     */
+/*      in_extr.h                           Initialization/Interrupt     */
+/*                                            functions                  */
+/*      tm_extr.h                           Timer Control function       */
+/*      er_extr.h                           Error handling function      */
+/*      hi_extr.h                           History functions            */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      05-15-1993      Corrected comment problems in                    */
+/*                      TCC_Control_Signals and                          */
+/*                      TCC_Register_Signal_Handler,                     */
+/*                      making version 1.0a                              */
+/*      05-15-1993      Verified version 1.0a                            */
+/*      06-01-1993      Modified a multi-line comment                    */
+/*                      after a #include directive                       */
+/*                      that gave some compilers a                       */
+/*                      problem, making version 1.0b                     */
+/*      06-01-1993      Verified version 1.0b                            */
+/*      08-09-1993      Corrected pointer retrieval                      */
+/*                      loop, resulting in version 1.0c                  */
+/*      08-09-1993      Verified version 1.0c                            */
+/*      09-19-1993      Corrected an initialization                      */
+/*                      problem of de-referencing a                      */
+/*                      NULL pointer, resulting in                       */
+/*                      version 1.0d                                     */
+/*      09-19-1993      Verified version 1.0d                            */
+/*      11-01-1993      Added logic to save unhandled                    */
+/*                      interrupt vector number in                       */
+/*                      a global variable, resulting                     */
+/*                      in version 1.0e                                  */
+/*      11-01-1993      Verified version 1.0e                            */
+/*      02-01-1994      Corrected a suspension with                      */
+/*                      timeout problem that caused                      */
+/*                      unconditional task suspension                    */
+/*                      for timeouts and sleeps for 1                    */
+/*                      tick, resulting in version 1.0f                  */
+/*      02-01-1994      Verified version 1.0f                            */
+/*      03-01-1994      Added another routine that                       */
+/*                      validates resume calls with                      */
+/*                      the appropriate protection and                   */
+/*                      added code to clear cleanup                      */
+/*                      information at task create and                   */
+/*                      task resume time, resulting in                   */
+/*                      version 1.0g                                     */
+/*      03-01-1994      Verified version 1.0g                            */
+/*      03-01-1994      Moved non-core functions into                    */
+/*                      supplemental files, changed                      */
+/*                      function interfaces to match                     */
+/*                      those in prototype, added                        */
+/*                      register options, fixed bug                      */
+/*                      in suspending current task from                  */
+/*                      a HISR, added a system protect                   */
+/*                      structure to reduce overhead                     */
+/*                      in protection, moved resume                      */
+/*                      validate to error checking                       */
+/*                      file, resulting in version 1.1                   */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*      12-18-1995      Modified TCC_Resume_Service,                     */
+/*                      resulting in version 1.1+                        */
+/*                      (SPR 36, 64, 66, 77)                             */
+/*      04-17-1996      updated to version 1.2                           */
+/*      06-01-1996      Modified TCC_Suspend_Task                        */
+/*                      (SPR152) creating version 1.2a                   */
+/*      10-29-1997      Modified TCC_Resume_Task                         */
+/*                      (SPR115) creating vresion 1.2b                   */
+/*      01-23-1998      Released version 1.2b                            */
+/*      03-20-1998      Corrected problem where tasks                    */
+/*                      created with NU_NO_PREEMPT in                    */
+/*                      Application_Initialize would                     */
+/*                      start in the order of creation                   */
+/*                      and not in priority order.                       */
+/*                      SPR455 creates version 1.2c                      */
+/*      03-24-1998      Released version 1.3.                            */
+/*      10-02-1998      Another protect problem (1.3a)                   */
+/*      10-02-1998      Corrected a problem where a                      */
+/*                      a timer expiration occurs                        */
+/*                      during signal handler execution                  */
+/*                      and causes the task to never                     */
+/*                      run again (SPR 923) creating                     */
+/*                      version 1.3b.                                    */
+/*      03-26-1999      Released 1.11m (new release                      */
+/*                        numbering scheme)                              */
+/*      04-17-2002      Released version 1.13m                           */
+/*      11-07-2002      Released version 1.14                            */
+/*************************************************************************/
+#define         NU_SOURCE_FILE
+
+#include        "in_defs.h"                 /* Initialization defines    */
+#include        "cs_extr.h"                 /* Common service functions  */
+#include        "tc_extr.h"                 /* Thread control functions  */
+#include        "in_extr.h"                 /* Initialization/Interrupt  */
+                                            /*   functions               */
+#include        "tm_extr.h"                 /* Timer control functions   */
+#include        "er_extr.h"                 /* Error handling function   */
+#include        "hi_extr.h"                 /* History functions         */
+#include        "profiler.h"                /* Nucleus Profiling header  */
+
+#if ((defined(NU_MODULE_SUPPORT)) && (NU_MODULE_SUPPORT > 0))
+#include        "module/inc/ms_defs.h"      /* MS_Module typedef */
+#endif
+
+/* Define external inner-component global data references.  */
+
+extern INT              INC_Initialize_State;
+extern CS_NODE         *TCD_Created_Tasks_List;
+extern UNSIGNED         TCD_Total_Tasks;
+extern TC_TCB          *TCD_Priority_List[TC_PRIORITIES];
+extern UNSIGNED         TCD_Priority_Groups;
+extern DATA_ELEMENT     TCD_Sub_Priority_Groups[TC_MAX_GROUPS];
+extern UNSIGNED_CHAR    TCD_Lowest_Set_Bit[];
+extern INT              TCD_Highest_Priority;
+extern TC_TCB          *TCD_Execute_Task;
+extern VOID            *TCD_Current_Thread;
+extern UNSIGNED_CHAR    TCD_Registered_LISRs[NU_MAX_VECTORS+1];
+extern VOID           (*TCD_LISR_Pointers[NU_MAX_LISRS+1])(INT vector);
+extern INT              TCD_Interrupt_Count;
+extern INT              TCD_Stack_Switched;
+extern TC_PROTECT       TCD_List_Protect;
+extern TC_PROTECT       TCD_System_Protect;
+extern TC_PROTECT       TCD_LISR_Protect;
+extern CS_NODE         *TCD_Created_HISRs_List;
+extern UNSIGNED         TCD_Total_HISRs;
+extern TC_PROTECT       TCD_HISR_Protect;
+extern INT              TCD_Unhandled_Interrupt;
+
+
+/* Define external inner-component function calls that are not available to
+   other components.  */
+
+VOID            TCT_Build_Task_Stack(TC_TCB *task_ptr);
+VOID            TCT_Build_HISR_Stack(TC_HCB *hisr_ptr);
+VOID            TCT_Build_Signal_Frame(TC_TCB *task_ptr);
+VOID            TCT_Protect_Switch(TC_TCB *task);
+VOID            TCT_Signal_Exit(VOID);
+
+
+/* Define internal function calls.  */
+
+VOID            TCC_Signal_Shell(VOID);
+
+
+#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0)
+
+/* Define service routines "privately" imported from other components */
+extern MS_MODULE* msd_current_module;
+
+STATUS MSC_Bind_Module_HISR(MS_MODULE* module, TC_HCB* hisr);
+STATUS MSC_Bind_Module_Task(MS_MODULE* module, TC_TCB* task);
+
+#endif /* NU_MODULE_SUPPORT */
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Create_Task                                                  */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function creates a task and then places it on the list of   */
+/*      created tasks.  All the resources necessary to create the task   */
+/*      are supplied to this routine.  If specified, the newly created   */
+/*      task is started.  Otherwise, it is left in a suspended state.    */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TCCE_Create_Task                    Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      CSC_Place_On_List                   Add TCB to linked-list       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      TCC_Resume_Task                     Start the created task       */
+/*      TCT_Build_Task_Stack                Build an initial task stack  */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Control_To_System               Transfer control to system   */
+/*      TCT_Protect                         Protect created task list    */
+/*      TCT_Unprotect                       Release protection of list   */
+/*      TMC_Init_Task_Timer                 Initialize the task's timer  */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task_ptr                            Task control block pointer   */
+/*      name                                Task name                    */
+/*      task_entry                          Entry function of the task   */
+/*      argc                                Optional task parameter      */
+/*      argv                                Optional task parameter      */
+/*      stack_address                       Pointer to start of stack    */
+/*      stack_size                          Size of task stack in bytes  */
+/*      priority                            Task priority                */
+/*      time_slice                          Task time slice              */
+/*      preempt                             Task preemptability flag     */
+/*      auto_start                          Automatic task start         */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                                                       */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      added system protection logic,                   */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Create_Task(NU_TASK *task_ptr, CHAR *name,
+          VOID (*task_entry)(UNSIGNED, VOID *), UNSIGNED argc, VOID *argv,
+          VOID *stack_address, UNSIGNED stack_size,
+          OPTION priority, UNSIGNED time_slice,
+          OPTION preempt, OPTION auto_start)
+{
+
+R1 TC_TCB      *task;                       /* Task control block ptr    */
+R2 INT          i;                          /* Working index variable    */
+STATUS          status = NU_SUCCESS;
+
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move input task pointer into internal pointer.  */
+    task =  (TC_TCB *) task_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_CREATE_TASK_ID, (UNSIGNED) task,
+                                (UNSIGNED) name, (UNSIGNED) task_entry);
+
+#endif
+
+    /* First, clear the task ID just in case it is an old Task
+       Control Block.  */
+    task -> tc_id =             0;
+
+    /* Fill in the task name.  */
+    for (i = 0; i < NU_MAX_NAME; i++)
+        task -> tc_name[i] =  name[i];
+
+    /* Fill in the basic task information.  */
+    task -> tc_entry =                  task_entry;
+    task -> tc_argc =                   argc;
+    task -> tc_argv =                   argv;
+    task -> tc_status =                 NU_PURE_SUSPEND;
+    task -> tc_delayed_suspend =        NU_FALSE;
+    task -> tc_scheduled =              0;
+    task -> tc_time_slice =             time_slice;
+    task -> tc_cur_time_slice =         time_slice;
+    task -> tc_current_protect =        NU_NULL;
+    task -> tc_suspend_protect =        NU_NULL;
+    task -> tc_cleanup =                NU_NULL;
+    task -> tc_cleanup_info =           NU_NULL;
+
+    /* Setup task's preemption posture.  */
+    if (preempt == NU_PREEMPT)
+        task -> tc_preemption =  NU_TRUE;
+    else
+        task -> tc_preemption =  NU_FALSE;
+
+    /* Fill in information about the task's stack.  */
+    task -> tc_stack_start =            stack_address;
+    task -> tc_stack_end =              0;
+    task -> tc_stack_size =             stack_size;
+    task -> tc_stack_minimum =          stack_size;
+
+    /* Setup priority information for the task.  There are two bit maps
+       associated with each task.  The first bit map indicates which group
+       of 8-priorities it is.  The second bit map indicates the actual
+       priority within the group.  */
+    task -> tc_priority =               priority;
+    task -> tc_priority_head =          &(TCD_Priority_List[priority]);
+    task -> tc_sub_priority =           (DATA_ELEMENT) (1 << (priority & 7));
+    priority =                          priority >> 3;
+    task -> tc_priority_group =         ((UNSIGNED) 1) << priority;
+    task -> tc_sub_priority_ptr =       &(TCD_Sub_Priority_Groups[priority]);
+
+    /* Initialize link pointers.  */
+    task -> tc_created.cs_previous =    NU_NULL;
+    task -> tc_created.cs_next =        NU_NULL;
+    task -> tc_ready_previous =         NU_NULL;
+    task -> tc_ready_next =             NU_NULL;
+
+    /* Build a stack frame for this task by calling TCT_Build_Task_Stack.  */
+    TCT_Build_Task_Stack(task);
+
+    /* Initialize the signal information of the task.  */
+    task -> tc_signals =                0;
+    task -> tc_enabled_signals =        0;
+    task -> tc_signal_handler =         0;
+    task -> tc_signal_active =          NU_FALSE;
+    /* Initialize additional kernel options data */
+
+#if (NU_SUPERV_USER_MODE == 1)
+    task->tc_su_mode = 0;              /* Initially in User mode */
+    task->tc_module = 0;               /* Not initially bound to a module */
+#endif
+
+    /* Initialize the task timer.  */
+    task -> tc_timer_active =           NU_FALSE;
+    TMC_Init_Task_Timer(&(task -> tc_timer_control), (VOID *) task);
+
+    /* Protect the list of created tasks.  */
+    TCT_Protect(&TCD_List_Protect);
+
+    /* At this point the task is completely built.  The ID can now be
+       set and it can be linked into the created task list.  */
+    task -> tc_id =                     TC_TASK_ID;
+
+#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0)
+    /* If executing in a thread's context, bind to that thread's module */
+    if(TCD_Current_Thread != NU_NULL)
+    {
+        status = MSC_Bind_Module_Task(
+          (MS_MODULE*)(((TC_TCB*)(TCD_Current_Thread))->tc_module), task);
+    }
+    else /* It must be initialization time, so use the current module */
+    {
+        status = MSC_Bind_Module_Task(msd_current_module, task);
+    }
+#endif /* NU_MODULE_SUPPORT */
+
+    /* Link the task into the list of created tasks and increment the
+       total number of tasks in the system.  */
+    CSC_Place_On_List(&TCD_Created_Tasks_List, &(task -> tc_created));
+    TCD_Total_Tasks++;
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTask(task,RT_PROF_CREATE_TASK);
+#endif
+
+    /* Release the protection.  */
+    TCT_Unprotect();
+
+    /* Determine if the task should be automatically started.  */
+    if (auto_start == NU_START)
+    {
+
+        /* Protect the system data structures.  */
+        TCT_Protect(&TCD_System_Protect);
+
+        /* Start the task by resuming it.  If the preemption is required,
+           leave the current task.  */
+        if (TCC_Resume_Task(task_ptr, NU_PURE_SUSPEND))
+
+
+            /* Transfer control back to the system.  */
+            TCT_Control_To_System();
+        else
+
+            /* Release the protection.  */
+            TCT_Unprotect();
+    }
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return successful completion.  */
+    return(status);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Create_HISR                                                  */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function creates a High-Level Interrupt Service Routine     */
+/*      (HISR) and then places it on the list of created HISRs.  All     */
+/*      the resources necessary to create the HISR are supplied to this  */
+/*      routine.  HISRs are always created in a dormant state.           */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TCCE_Create_HISR                    Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      CSC_Place_On_List                   Add TCB to linked-list       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      TCT_Build_HISR_Stack                Build an initial HISR stack  */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect created HISR list    */
+/*      TCT_Unprotect                       Release protection of list   */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      hisr_ptr                            HISR control block pointer   */
+/*      name                                HISR name                    */
+/*      hisr_entry                          Entry function of the HISR   */
+/*      priority                            Task priority                */
+/*      stack_address                       Pointer to start of stack    */
+/*      stack_size                          Size of HISR stack in bytes  */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                                                       */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      added more control block                         */
+/*                      initialization, resulting in                     */
+/*                      version 1.1                                      */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Create_HISR(NU_HISR *hisr_ptr, CHAR *name,
+          VOID (*hisr_entry)(VOID), OPTION priority,
+          VOID *stack_address, UNSIGNED stack_size)
+{
+
+R1 TC_HCB      *hisr;                       /* HISR control block ptr    */
+R2 INT          i;                          /* Working index variable    */
+STATUS          status = NU_SUCCESS;
+
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move input HISR pointer into internal pointer.  */
+    hisr =  (TC_HCB *) hisr_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_CREATE_HISR_ID, (UNSIGNED) hisr,
+                                (UNSIGNED) name, (UNSIGNED) hisr_entry);
+
+#endif
+
+    /* First, clear the HISR ID just in case it is an old HISR
+       Control Block.  */
+    hisr -> tc_id =             0;
+
+    /* Fill in the HISR name.  */
+    for (i = 0; i < NU_MAX_NAME; i++)
+        hisr -> tc_name[i] =  name[i];
+
+    /* Fill in the basic HISR information.  */
+    hisr -> tc_entry =                  hisr_entry;
+    hisr -> tc_scheduled =              0;
+    hisr -> tc_activation_count =       0;
+    hisr -> tc_cur_time_slice =         0;
+
+    /* Fill in information about the HISR's stack.  */
+    hisr -> tc_stack_start =            stack_address;
+    hisr -> tc_stack_end =              0;
+    hisr -> tc_stack_size =             stack_size;
+    hisr -> tc_stack_minimum =          stack_size;
+
+    /* Setup priority information for the HISR.  Priorities range from 0 to
+       TC_HISR_PRIORITIES - 1.  */
+    hisr -> tc_priority =               priority & 3;
+
+    /* Initialize link pointers.  */
+    hisr -> tc_created.cs_previous =    NU_NULL;
+    hisr -> tc_created.cs_next =        NU_NULL;
+    hisr -> tc_active_next =            NU_NULL;
+
+    /* Clear protect pointer.  */
+    hisr -> tc_current_protect =        NU_NULL;
+
+    /* Initialize additional kernel options data */
+#if (NU_SUPERV_USER_MODE == 1)
+    hisr->tc_su_mode = 1;                   /* TCT_HISR_Shell in Supervisor mode */
+    hisr->tc_module = 0;                    /* Not initially bound to a module */
+#endif
+
+    /* Build a stack frame for this HISR by calling TCT_Build_HISR_Stack.  */
+    TCT_Build_HISR_Stack(hisr);
+
+    /* Protect the list of created HISRs.  */
+    TCT_Protect(&TCD_HISR_Protect);
+
+    /* At this point the HISR is completely built.  The ID can now be
+       set and it can be linked into the created HISR list.  */
+    hisr -> tc_id =                     TC_HISR_ID;
+
+#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0)
+    /* If executing in a thread's context, bind to that thread's module */
+    if(TCD_Current_Thread != NU_NULL)
+    {
+        status = MSC_Bind_Module_HISR(
+          (MS_MODULE*)(((TC_TCB*)(TCD_Current_Thread))->tc_module), hisr);
+    }
+    else /* It must be initialization time, so use the current module */
+    {
+        status = MSC_Bind_Module_HISR(msd_current_module, hisr);
+    }
+#endif /* NU_MODULE_SUPPORT */
+
+    /* Link the HISR into the list of created HISRs and increment the
+       total number of HISRs in the system.  */
+    CSC_Place_On_List(&TCD_Created_HISRs_List, &(hisr -> tc_created));
+    TCD_Total_HISRs++;
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpHisr(hisr,RT_PROF_CREATE_HISR);
+#endif
+
+    /* Release the protection.  */
+    TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return successful completion.  */
+    return(status);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Delete_Task                                                  */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function deletes a task and removes it from the list of     */
+/*      created tasks.  It is assumed by this function that the task is  */
+/*      in a finished or terminated state.  Note that this function      */
+/*      does not free memory associated with the task's control block or */
+/*      its stack.  This is the responsibility of the application.       */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TCCE_Delete_Task                    Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      CSC_Remove_From_List                Remove node from list        */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect created task list    */
+/*      TCT_Unprotect                       Release protection of list   */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task_ptr                            Task control block pointer   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                                                       */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Delete_Task(NU_TASK *task_ptr)
+{
+
+R1 TC_TCB  *task;                           /* Task control block ptr    */
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move input task pointer into internal pointer.  */
+    task =  (TC_TCB *) task_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_DELETE_TASK_ID, (UNSIGNED) task,
+                                        (UNSIGNED) 0, (UNSIGNED) 0);
+
+#endif
+
+    /* Protect the list of created tasks.  */
+    TCT_Protect(&TCD_List_Protect);
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTask(task,RT_PROF_DELETE_TASK);
+#endif /*INCLUDE_PROVIEW*/
+
+    /* Remove the task from the list of created tasks.  */
+    CSC_Remove_From_List(&TCD_Created_Tasks_List, &(task -> tc_created));
+
+    /* Decrement the total number of created tasks.  */
+    TCD_Total_Tasks--;
+
+    /* Clear the task ID just in case.  */
+    task -> tc_id =  0;
+
+    /* Release protection.  */
+    TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return a successful completion.  */
+    return(NU_SUCCESS);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Delete_HISR                                                  */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function deletes a HISR and removes it from the list of     */
+/*      created HISRs.  It is assumed by this function that the HISR is  */
+/*      in a non-active state.  Note that this function does not free    */
+/*      memory associated with the HISR's control block or its stack.    */
+/*      This is the responsibility of the application.                   */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TCCE_Delete_HISR                    Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      CSC_Remove_From_List                Remove node from list        */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect created HISR list    */
+/*      TCT_Unprotect                       Release protection of list   */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      hisr_ptr                            HISR control block pointer   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                                                       */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Delete_HISR(NU_HISR *hisr_ptr)
+{
+
+R1 TC_HCB  *hisr;                           /* HISR control block ptr    */
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move input HISR pointer into internal pointer.  */
+    hisr =  (TC_HCB *) hisr_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_DELETE_HISR_ID, (UNSIGNED) hisr,
+                                        (UNSIGNED) 0, (UNSIGNED) 0);
+
+#endif
+
+    /* Protect the list of created HISRs.  */
+    TCT_Protect(&TCD_HISR_Protect);
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpHisr(hisr,RT_PROF_DELETE_HISR);
+#endif /*INCLUDE_PROVIEW*/
+
+    /* Remove the HISR from the list of created HISRs.  */
+    CSC_Remove_From_List(&TCD_Created_HISRs_List, &(hisr -> tc_created));
+
+    /* Decrement the total number of created HISRs.  */
+    TCD_Total_HISRs--;
+
+    /* Clear the HISR ID just in case.  */
+    hisr -> tc_id =  0;
+
+    /* Release protection.  */
+    TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return a successful completion.  */
+    return(NU_SUCCESS);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Reset_Task                                                   */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function resets the specified task.  Note that a task reset */
+/*      can only be performed on tasks in a finished or terminated state.*/
+/*      The task is left in an unconditional suspended state.            */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TCCE_Reset_Task                     Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      TCT_Build_Task_Stack                Build an initial task stack  */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect created task list    */
+/*      TCT_Unprotect                       Release protection of list   */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task_ptr                            Task control block pointer   */
+/*      argc                                Optional task parameter      */
+/*      argv                                Optional task parameter      */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                          Indicates successful request */
+/*      NU_NOT_TERMINATED                   Indicates task was not       */
+/*                                            finished or terminated     */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      added system protection logic,                   */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Reset_Task(NU_TASK *task_ptr, UNSIGNED argc, VOID *argv)
+{
+
+R1 TC_TCB      *task;                       /* Task control block ptr   */
+STATUS          status;                     /* Status of the request    */
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move input task pointer into internal pointer.  */
+    task =  (TC_TCB *) task_ptr;
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_RESET_TASK_ID, (UNSIGNED) task,
+                                        (UNSIGNED) argc, (UNSIGNED) argv);
+
+#endif
+
+    /* Protect system structures.  */
+    TCT_Protect(&TCD_System_Protect);
+
+    /* Determine if the task is in the proper state.  */
+    if ((task -> tc_status == NU_FINISHED) ||
+                        (task -> tc_status == NU_TERMINATED))
+    {
+
+        /* Yes, a valid reset is present.  Indicate this in the status.  */
+        status =  NU_SUCCESS;
+
+        /* Fill in the new argument information and reset some of the other
+           fields.  */
+        task -> tc_argc =                   argc;
+        task -> tc_argv =                   argv;
+        task -> tc_status =                 NU_PURE_SUSPEND;
+        task -> tc_delayed_suspend =        NU_FALSE;
+        task -> tc_scheduled =              0;
+        task -> tc_stack_minimum =          task -> tc_stack_size;
+
+#if (NU_SUPERV_USER_MODE == 1)
+        /* Since we are doing a complete reset we need to ensure 
+           that this field is 0 since the task will be started in
+           user mode.  TCC_Task_Shell can not return and therefore
+           left the task in supervisor mode when the task completed.
+           If we were to not re-initialize this field the task would
+           become locked in user mode and API would fail. */
+        task -> tc_su_mode = 0;
+#endif
+
+        /* Build a stack frame for this task by calling
+           TCT_Build_Task_Stack.  */
+        TCT_Build_Task_Stack(task);
+    }
+    else
+
+        /* The requested task is not in a finished or terminated state.  */
+        status =  NU_NOT_TERMINATED;
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTask(task,RT_PROF_RESET_TASK);
+#endif /*INCLUDE_PROVIEW*/
+
+    /* Release the protection.  */
+    TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return completion status.  */
+    return(status);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Terminate_Task                                               */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function terminates the specified task.  If the task is     */
+/*      already terminated, this function does nothing.  If the task     */
+/*      to terminate is currently suspended, the specified cleanup       */
+/*      routine is also invoked to cleanup suspension data structures.   */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TCCE_Terminate_Task                 Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      Cleanup routine                     Task's suspend cleanup funct */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      TCC_Suspend_Task                    Suspend a ready task         */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect created task list    */
+/*      TCT_Unprotect                       Release protection of list   */
+/*      TCT_Unprotect_Specific              Specific unprotection        */
+/*      TMC_Stop_Task_Timer                 Stop a task timer            */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task_ptr                            Task control block pointer   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                                                       */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      added system protection logic,                   */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Terminate_Task(NU_TASK *task_ptr)
+{
+
+R1 TC_TCB      *task;                       /* Task control block ptr    */
+TC_PROTECT     *suspend_protect;            /* Suspension protection ptr */
+DATA_ELEMENT    status;                     /* Task status               */
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move task pointer into internal pointer.  */
+    task =  (TC_TCB *) task_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_TERMINATE_TASK_ID, (UNSIGNED) task,
+                                        (UNSIGNED) 0, (UNSIGNED) 0);
+
+#endif
+
+    /* Determine if the calling task is the current task.  */
+    if (task == (TC_TCB *) TCD_Current_Thread)
+    {
+
+        /* Protect system  data structures.  */
+        TCT_Protect(&TCD_System_Protect);
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTask(task,RT_PROF_TERMINATE_TASK);
+#endif /*INCLUDE_PROVIEW*/
+
+        /* Suspend the calling task with the NU_TERMINATED status.  */
+        TCC_Suspend_Task(task_ptr, NU_TERMINATED, NU_NULL, NU_NULL,
+                                                            NU_SUSPEND);
+
+        /* No need to un-protect, since control never comes back to this
+           point and the protection is cleared in TCT_Control_To_System.  */
+    }
+    else
+    {
+
+        /* Protect scheduling structures.  */
+        TCT_Protect(&TCD_System_Protect);
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTask(task,RT_PROF_TERMINATE_TASK);
+#endif /*INCLUDE_PROVIEW*/
+
+        /* Keep trying to terminate the specified task until its status
+           indicates that it is terminated or finished.  */
+        while ((task -> tc_status != NU_FINISHED) &&
+                  task -> tc_status != NU_TERMINATED)
+        {
+
+            /* Is the task in a ready state?  */
+            if (task -> tc_status == NU_READY)
+            {
+
+                /* Terminate the specified task.  */
+                TCC_Suspend_Task(task_ptr, NU_TERMINATED, NU_NULL,
+                                                        NU_NULL,NU_SUSPEND);
+
+                /* Clear system protection.  */
+                TCT_Unprotect();
+            }
+            else
+            {
+
+                /* Task is suspended currently.  Pickup the suspension
+                   protection.  */
+                suspend_protect =  task -> tc_suspend_protect;
+
+                /* Save the current status.  */
+                status =           task -> tc_status;
+
+                /* Release protection on system structures.  */
+                TCT_Unprotect();
+
+                /* Determine if there was a suspension protection.  If so
+                   protect it first before the scheduling list protection.
+                   This avoids a deadlock situation.  */
+                if (suspend_protect)
+
+                    /* Protect the terminated task's last suspension
+                       structures.  */
+                    TCT_Protect(suspend_protect);
+
+                /* Protect the system structures again.  */
+                TCT_Protect(&TCD_System_Protect);
+
+                /* Now determine if the same suspension is in force.  */
+                if ((task -> tc_status == status) &&
+                    (task -> tc_suspend_protect == suspend_protect))
+                {
+
+                    /* Yes, same suspension is in force.  */
+
+                    /* Call cleanup routine, if there is one.  */
+                    if (task -> tc_cleanup)
+
+                        /* Call cleanup function.  */
+                        (*(task -> tc_cleanup)) (task -> tc_cleanup_info);
+
+                    /* Status the task as terminated.  */
+                    task -> tc_status =  NU_TERMINATED;
+
+                    /* Determine if there is a timer active.  */
+                    if (task -> tc_timer_active)
+                    {
+
+                        /* Call the stop timer function.  */
+                        TMC_Stop_Task_Timer(&(task -> tc_timer_control));
+
+                        /* Clear the timer active flag.  */
+                        task -> tc_timer_active =  NU_FALSE;
+                    }
+                }
+
+                /* Cleanup the protection.  */
+                if (suspend_protect)
+                {
+
+                    /* Release specific protection.  */
+                    TCT_Unprotect_Specific(suspend_protect);
+
+                    /* Clear the suspend protect field.  */
+                    task -> tc_suspend_protect =  NU_NULL;
+                }
+
+                /* Release current protection.  */
+                TCT_Unprotect();
+            }
+
+            /* Protect the scheduling list again.  */
+            TCT_Protect(&TCD_System_Protect);
+        }
+
+        /* Release the protection.  */
+        TCT_Unprotect();
+    }
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return successful completion.  */
+    return(NU_SUCCESS);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Resume_Task                                                  */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function resumes a previously suspended task.  The task     */
+/*      task must currently be suspended for the same reason indicated   */
+/*      by this request.  If the task resumed is higher priority than    */
+/*      the calling task and the current task is preemptable, this       */
+/*      function returns a value of NU_TRUE.  Otherwise, if no           */
+/*      preemption is required, a NU_FALSE is returned.  This routine    */
+/*      must be called from Supervisor mode in a Supervisor/User mode    */
+/*      switching kernel.                                                */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Other Components                                                 */
+/*      TCC_Resume_Service                  Resume service function      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Set_Current_Protect             Set current protection field */
+/*      TCT_Set_Execute_Task                Set TCD_Execute_Task pointer */
+/*      TMC_Stop_Task_Timer                 Stop task timer              */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task_ptr                            Task control block pointer   */
+/*      suspend_type                        Type of suspension to lift   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_TRUE                             A higher priority task is    */
+/*                                            ready to execute           */
+/*      NU_FALSE                            No change in the task to     */
+/*                                            execute                    */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      09-19-1993      Corrected an initialization                      */
+/*                      problem of de-referencing a                      */
+/*                      NULL pointer, resulting in                       */
+/*                      version 1.0d                                     */
+/*      09-19-1993      Verified version 1.0d                            */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      modified protection logic to                     */
+/*                      assume that system protection                    */
+/*                      is already in force, resulting                   */
+/*                      in version 1.1                                   */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*      10-29-1997      Changed so that tc_cleanup,                      */
+/*                      tc_cleanup_info, and                             */
+/*                      tc_suspend_protect are cleared                   */
+/*                      only if a signal is not active                   */
+/*                      (SPR115)                                         */
+/*      03-20-1998      Corrected SPR455.                                */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Resume_Task(NU_TASK *task_ptr, OPTION suspend_type)
+{
+
+R1 TC_TCB      *task;                       /* Task control block ptr    */
+R2 TC_TCB      *head;                       /* Pointer to priority list  */
+STATUS          status =  NU_FALSE;         /* Status variable           */
+
+    /* Move task pointer into internal pointer.  */
+    task =  (TC_TCB *) task_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+
+    /* Check to see if the task is suspended for the reason that this
+       resume is attempting to clear.  */
+    if (task -> tc_status == suspend_type)
+    {
+
+        /* Yes, this resume call is valid.  */
+
+        /* If signals are not active, clear any suspend or cleanup
+           information (SPR115).  */
+        if (!task -> tc_signal_active)
+        {
+            task -> tc_suspend_protect =        NU_NULL;
+            task -> tc_cleanup =                NU_NULL;
+            task -> tc_cleanup_info =           NU_NULL;
+        }
+
+        /* Determine if there is a timer active and the task is not being
+           resumed to handle a signal.  */
+        if ((task -> tc_timer_active) && (!task -> tc_signal_active))
+        {
+
+            /* Call the stop timer function.  */
+            TMC_Stop_Task_Timer(&(task -> tc_timer_control));
+
+            /* Clear the timer active flag.  */
+            task -> tc_timer_active =  NU_FALSE;
+        }
+
+        /* Check to see if there is a pending pure suspension.  If so,
+           change the cause of the suspension and leave in a suspended
+           state.  */
+        if (task -> tc_delayed_suspend)
+        {
+
+            /* Leave suspended but change the task's status and clear the
+               delayed suspension flag.  */
+            task -> tc_delayed_suspend =  NU_FALSE;
+            task -> tc_status =  NU_PURE_SUSPEND;
+        }
+        else
+        {
+
+            /* Lift the suspension of the specified task.  */
+
+            /* Clear the status of the task.  */
+            task -> tc_status =  NU_READY;
+
+#ifdef INCLUDE_PROVIEW
+            _RTProf_TaskStatus(task,RT_TASK_READY);
+#endif /*INCLUDE_PROVIEW*/
+
+            /* Link the task into the appropriate priority list.  */
+            head =  *(task -> tc_priority_head);
+
+            /* Determine if the list is non-empty.  */
+            if (head)
+            {
+
+                /* Add the new TCB to the end of the ready list.  */
+                task -> tc_ready_previous =      head -> tc_ready_previous;
+                (task -> tc_ready_previous) -> tc_ready_next =  task;
+                task -> tc_ready_next =          head;
+                (task -> tc_ready_next) -> tc_ready_previous =  task;
+
+                /* Note that the priority bit map does not need to be
+                   modified since there are other active tasks at the
+                   same priority.  */
+            }
+            else
+            {
+
+                /* Add the new TCB to an empty list.  */
+                task -> tc_ready_previous =  task;
+                task -> tc_ready_next =      task;
+                *(task -> tc_priority_head)= task;
+
+                /* Update the priority group bit map to indicate that this
+                   priority now has a task ready.  */
+                TCD_Priority_Groups =
+                        TCD_Priority_Groups | (task -> tc_priority_group);
+
+                /* Update the sub-priority bit map to show that this priority
+                   is ready.  */
+                *(task -> tc_sub_priority_ptr) =
+                   (*(task -> tc_sub_priority_ptr)) | task -> tc_sub_priority;
+
+                /* Determine if this newly ready task is higher priority
+                   than the current task.  */
+                if ((INT) (task -> tc_priority) < TCD_Highest_Priority)
+                {
+
+                    /* Update the highest priority field.  */
+                    TCD_Highest_Priority = (INT) task -> tc_priority;
+
+                    /* See if there is a task to execute.  */
+                    if (TCD_Execute_Task == NU_NULL)
+
+                        /* Make this task the current.  */
+                        TCT_Set_Execute_Task(task);
+
+                    /* Check to see if the task to execute is preemptable.  */
+                    /* SPR455 checks if we are in Application_Initialize */
+                    else if ((TCD_Execute_Task -> tc_preemption)
+                             || (INC_Initialize_State == INC_START_INITIALIZE))
+                    {
+
+                        /* Yes, the task to execute is preemptable.  Replace
+                           it with the new task.  */
+                        TCT_Set_Execute_Task(task);
+
+                        /* Now, check and see if the current thread is a task.
+                           If so, return a status that indicates a context
+                           switch is needed.  */
+                        if ((TCD_Current_Thread) &&
+                           (((TC_TCB *) TCD_Current_Thread) -> tc_id ==
+                                TC_TASK_ID))
+
+                            /* Yes, a context switch is needed.  */
+                            status =  NU_TRUE;
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+
+        /* Check for a resumption of a delayed pure suspend.  */
+        if (suspend_type == NU_PURE_SUSPEND)
+
+            /* Clear the delayed suspension.  */
+            task -> tc_delayed_suspend =  NU_FALSE;
+
+        /* Check for a signal active and the saved status the same as
+           the resume request.  */
+        if ((suspend_type == task -> tc_saved_status) &&
+            (task -> tc_signal_active))
+        {
+
+            /* Indicate the saved status as ready.  */
+            task -> tc_saved_status =  NU_READY;
+
+            /* Determine if the task's timer is active.  */
+            if (task -> tc_timer_active)
+            {
+
+                /* Stop the timer.  */
+                TMC_Stop_Task_Timer(&(task -> tc_timer_control));
+
+                /* Clear the timer active flag.  */
+                task -> tc_timer_active =  NU_FALSE;
+            }
+        }
+    }
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTask(task,RT_PROF_RESUME_TASK);
+#endif /*INCLUDE_PROVIEW*/
+
+    /* Return back the status.  */
+    return(status);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Resume_Service                                               */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function provides an interface identical to the application */
+/*      service call to resume a task.                                   */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TCCE_Resume_Service                 Error checking function      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      TCC_Resume_Task                     Resume a task                */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Control_To_System               Transfer control to system   */
+/*      TCT_Protect                         Protect system structures    */
+/*      TCT_Unprotect                       Release system protection    */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task_ptr                            Task control block pointer   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                          Always returns success       */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      added system protection logic,                   */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*      12-19-1995      Changed the "task" parameter to                  */
+/*                      "task_ptr" in the                                */
+/*                      HIC_Make_History_Entry call,                     */
+/*                      resulting in version 1.1+                        */
+/*                      (SPR 36, 64, 66, 77)                             */
+/*      10-02-1998      Another protect problem (1.3a)                   */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Resume_Service(NU_TASK *task_ptr)
+{
+
+TC_PROTECT     *save_protect;               /* Save current protection   */
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_RESUME_TASK_ID, (UNSIGNED) task_ptr,
+                                        (UNSIGNED) 0, (UNSIGNED) 0);
+
+#endif
+
+    /* Save current protection.  */
+    if (TCD_Current_Thread != NU_NULL)
+    {
+        save_protect = TCT_Get_Current_Protect();
+    }
+    else
+    {
+        save_protect = NU_NULL;
+    }
+
+    /* Protect system structures.  */
+    TCT_Protect(&TCD_System_Protect);
+
+    /* Call the actual resume task function.  If the function returns a
+       NU_TRUE, context switching is needed.  */
+    if (TCC_Resume_Task(task_ptr, NU_PURE_SUSPEND))
+    {
+
+        /* Transfer control back to the system for a context switch.  */
+        TCT_Control_To_System();
+    }
+
+    /* Determine how to get out of protection.  */
+    if (save_protect)
+    {
+
+        /* Restore current protection.  */
+        TCT_Set_Current_Protect(save_protect);
+
+        /* Release system protect.  */
+        TCT_Unprotect_Specific(&TCD_System_Protect);
+    }
+    else
+
+        /* Release protection of system structures.  */
+        TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Always return a successful status.  */
+    return(NU_SUCCESS);
+}
+
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Suspend_Task                                                 */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function suspends the specified task.  If the specified     */
+/*      task is the calling task, control is transferred back to the     */
+/*      system.                                                          */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Other Components                                                 */
+/*      TCC_Suspend_Service                 Task suspend service         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      TCT_Control_To_System               Transfer control to system   */
+/*      TCT_Protect                         Protect system structures    */
+/*      TCT_Set_Execute_Task                Set TCD_Execute_Task pointer */
+/*      TCT_Protect_Switch                  Allow protected task to run  */
+/*                                            briefly                    */
+/*      TCT_Unprotect                       Release system protection    */
+/*      TMC_Start_Task_Timer                Start a task timer           */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task_ptr                            Task control block pointer   */
+/*      suspend_type                        Type of suspension to lift   */
+/*      cleanup                             Cleanup routine              */
+/*      information                         Information for cleanup      */
+/*      timeout                             Timeout on the suspension    */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      02-01-1994      Corrected a suspension with                      */
+/*                      timeout problem that caused                      */
+/*                      unconditional task suspension                    */
+/*                      for timeouts and sleeps for 1                    */
+/*                      tick, resulting in version 1.0f                  */
+/*      02-01-1994      Verified version 1.0f                            */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      fixed a possible suspending an                   */
+/*                      executing task from a HISR,                      */
+/*                      removed excessive protection                     */
+/*                      logic since protection is now                    */
+/*                      in force upon function entry,                    */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*      06-01-1996      Checked to see whether                           */
+/*                      task == TCD_Current_Thread                       */
+/*                      regardless of whether task ==                    */
+/*                      TCD_Execute_Task (SPR152)                        */
+/*                                                                       */
+/*************************************************************************/
+VOID  TCC_Suspend_Task(NU_TASK *task_ptr, OPTION suspend_type,
+                VOID (*cleanup) (VOID *), VOID *information, UNSIGNED timeout)
+{
+
+R1 TC_TCB      *task;                       /* Task control block ptr    */
+R2 INT          index;                      /* Working index variable    */
+DATA_ELEMENT    temp;                       /* Temporary variable        */
+
+
+
+    /* Move input task pointer into internal pointer.  */
+    task =  (TC_TCB *) task_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+
+    /* Determine if there is a timeout to initiate.  */
+    if (timeout != NU_SUSPEND)
+    {
+
+        /* Indicate that a task timer is active.  */
+        task -> tc_timer_active =  NU_TRUE;
+
+        /* Start a timeout on the suspension.  */
+        TMC_Start_Task_Timer(&(task -> tc_timer_control),timeout);
+    }
+
+
+    /* Check for a non self-suspension.  In such cases, the target task
+       cannot have any type of protection in force.  */
+    if (task != (TC_TCB *) TCD_Current_Thread)
+    {
+
+        do
+        {
+
+            /* Check for protection.  Remember that system protection is
+               in effect.  */
+            if (task -> tc_current_protect)
+            {
+
+                /* Yes, target task is in a protected mode.  Release
+                   the protection on the scheduling list and transfer
+                   control briefly to the target task.  */
+                TCT_Unprotect();
+
+                /* Switch to the protected task and wait until the
+                   task is not protected.  */
+                TCT_Protect_Switch(task);
+
+                /* Restore protection of the system structures.  */
+                TCT_Protect(&TCD_System_Protect);
+            }
+        } while (task -> tc_current_protect);
+    }
+
+    /* Check to see if the task is currently ready.  */
+    if (task -> tc_status == NU_READY)
+    {
+
+        /* Mark the task with the appropriate suspension code.  */
+        task -> tc_status =        suspend_type;
+
+        /* Store off termination information in the tasks control block. */
+        task -> tc_cleanup =       cleanup;
+        task -> tc_cleanup_info =  information;
+
+        /* Remove the task from the ready list.  */
+
+        /* Determine if the task is the only one on the list.  */
+        if (task -> tc_ready_next == task)
+        {
+
+            /* Only task on the list.  Clear the task's pointers and
+               clear the entry in the priority table.  */
+            task -> tc_ready_next =        NU_NULL;
+            task -> tc_ready_previous =    NU_NULL;
+            *(task -> tc_priority_head) =  NU_NULL;
+
+            /* Clear the sub-priority group.  */
+            *(task -> tc_sub_priority_ptr) =
+                (*(task -> tc_sub_priority_ptr)) & ~(task -> tc_sub_priority);
+
+            /* Determine if the main priority group needs to be cleared.
+               This is only true if there are no other bits set in this
+               sub-priority.  */
+            if (*(task -> tc_sub_priority_ptr) == 0)
+
+                /* Clear the main priority group bit.  */
+                TCD_Priority_Groups =
+                    TCD_Priority_Groups & ~(task -> tc_priority_group);
+
+            /* Determine if this priority group was the highest in the
+               system.  */
+            if (task -> tc_priority == (DATA_ELEMENT) TCD_Highest_Priority)
+            {
+
+                /* Determine the highest priority task in the system.  */
+                if (TCD_Priority_Groups == 0)
+                {
+
+                    /* Re-initialize the highest priority variable and
+                       clear the current task pointer.  */
+                    TCD_Highest_Priority =  TC_PRIORITIES;
+                }
+                else
+                {
+
+                    /* Find the next highest priority task.  */
+                    if (TCD_Priority_Groups & TC_HIGHEST_MASK)
+
+                        /* Base of sub-group is 0.  */
+                       index =  0;
+
+                    else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK)
+
+                        /* Base of sub-group is 8.  */
+                        index =  8;
+
+                    else if (TCD_Priority_Groups & TC_NEXT_LOWEST_MASK)
+
+                        /* Base of sub-group is 16.  */
+                        index =  16;
+                    else
+
+                        /* Base of sub-group is 24.  */
+                        index =  24;
+
+                    /* Calculate the highest available priority.  */
+                    index =  index + TCD_Lowest_Set_Bit[(INT)
+                        ((TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)];
+
+                    /* Get the mask of the priority within the group of
+                       8 priorities.  */
+                    temp =  TCD_Sub_Priority_Groups[index];
+
+                    /* Calculate the actual priority.  */
+                    TCD_Highest_Priority =
+                        (index << 3) + TCD_Lowest_Set_Bit[temp];
+                }
+            }
+        }
+        else
+        {
+
+            /* Not the only task ready at the same priority level.  */
+
+            /* Remove from the linked-list.  */
+            (task -> tc_ready_previous) -> tc_ready_next =
+                                                 task -> tc_ready_next;
+            (task -> tc_ready_next) -> tc_ready_previous =
+                                                 task -> tc_ready_previous;
+
+            /* See if the task being suspended is the current.  */
+            if (*(task -> tc_priority_head) == task)
+
+                /* Update the head of this priority list.  */
+                *(task -> tc_priority_head) =  task -> tc_ready_next;
+
+            /* Clear the task's pointers.  */
+            task -> tc_ready_next =        NU_NULL;
+            task -> tc_ready_previous =    NU_NULL;
+        }
+
+        /* Determine if this task the highest priority task.  */
+        if (task == TCD_Execute_Task)
+        {
+
+            /* Determine the next task to execute.  */
+            if (TCD_Highest_Priority < TC_PRIORITIES)
+
+                /* Put the next task to execute in TCD_Execute_Task.  */
+                TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]);
+            else
+
+                /* No other task is ready for execution.  */
+                TCT_Set_Execute_Task(NU_NULL);
+        }
+
+#ifdef INCLUDE_PROVIEW
+        _RTProf_DumpTask(task,RT_PROF_SUSPEND_TASK);
+
+        if (suspend_type == NU_SLEEP_SUSPEND)
+        {
+            _RTProf_TaskStatus(task,RT_TASK_SLEEPING);
+        }
+        else if (suspend_type == NU_PURE_SUSPEND)
+        {
+            _RTProf_TaskStatus(task,RT_TASK_SUSPENDED);
+        }
+        else
+        {
+            _RTProf_TaskStatus(task,RT_TASK_WAITING);
+        }
+#endif /*INCLUDE_PROVIEW*/
+
+        /* See if the suspending task is the current thread. (SPR152) */
+        if (task == (TC_TCB *) TCD_Current_Thread)
+
+            /* Leave the task, transfer control to the system.  */
+            TCT_Control_To_System();
+
+    }
+    else
+    {
+
+        /* Check for a pure suspension request.  If present, the delayed
+           suspension flag is set.  */
+        if (suspend_type == NU_PURE_SUSPEND)
+
+            /* Setup the delayed suspension flag.  */
+            task -> tc_delayed_suspend =  NU_TRUE;
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTask(task,RT_PROF_SUSPEND_TASK);
+#endif /*INCLUDE_PROVIEW*/
+
+    }
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Suspend_Service                                              */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function provides a suitable interface to the actual        */
+/*      service to suspend a task.                                       */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TCCE_Suspend_Service                Error checking function      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      TCC_Suspend_Task                    Suspend a task               */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect system structures    */
+/*      TCT_Unprotect                       Release system structures    */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task_ptr                            Task control block pointer   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                          Always a successful status   */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      added system protection logic,                   */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Suspend_Service(NU_TASK *task_ptr)
+{
+
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_SUSPEND_TASK_ID, (UNSIGNED) task_ptr,
+                                        (UNSIGNED) 0, (UNSIGNED) 0);
+
+#endif
+
+
+    /* Protect system data structures.  */
+    TCT_Protect(&TCD_System_Protect);
+
+    /* Call the actual routine to suspend the task.  */
+    TCC_Suspend_Task(task_ptr, NU_PURE_SUSPEND, NU_NULL, NU_NULL, NU_SUSPEND);
+
+    /* Release system protection.  */
+    TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Always return a successful status.  */
+    return(NU_SUCCESS);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Task_Timeout                                                 */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function processes task suspension timeout conditions.      */
+/*      Note that task sleep requests are also considered a timeout      */
+/*      condition.  This routine must be called from Supervisor mode in  */
+/*      a Supervisor/User mode switching kernel.                         */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      TMC_Timer_Task                      Timer expiration task        */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      Caller's cleanup function                                        */
+/*      TCC_Resume_Task                     Resume a suspended task      */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect scheduling list      */
+/*      TCT_Set_Current_Protect             Setup current protection     */
+/*      TCT_Unprotect                       Release protection           */
+/*      TCT_Unprotect_Specific              Release specific protection  */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task_ptr                            Task control block pointer   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      02-01-1994      Added logic to clear the timer                   */
+/*                      active flag when the target                      */
+/*                      task is already in a ready                       */
+/*                      state, resulting in                              */
+/*                      version 1.0f                                     */
+/*      02-01-1994      Verified version 1.0f                            */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      removed logic for timeout                        */
+/*                      before suspension because new                    */
+/*                      protection logic eliminates                      */
+/*                      the possibility,                                 */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TCC_Task_Timeout(NU_TASK *task_ptr)
+{
+
+R1 TC_TCB       *task;                      /* Task control block ptr    */
+TC_PROTECT      *suspend_protect;           /* Suspension protect ptr    */
+DATA_ELEMENT     task_status;               /* Task status variable      */
+
+
+
+    /* Move task control block pointer into internal pointer.  */
+    task =  (TC_TCB *) task_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+    /* Protect system data structures.  */
+    TCT_Protect(&TCD_System_Protect);
+
+    /* Pickup the suspension protection saved-off when the task was
+       suspended.  */
+    suspend_protect =  task -> tc_suspend_protect;
+
+    /* Is a signal handler currently running? */
+    if (task -> tc_signal_active)
+
+        /* Use the saved status for current task status */
+        task_status =      task -> tc_saved_status;
+    else
+
+        /* Just use the current task status */
+        task_status =      task -> tc_status;
+
+    /* Release protection of the scheduling list.  */
+    TCT_Unprotect();
+
+    /* Determine if there is a suspend protect.  */
+    if (suspend_protect)
+
+        /* Protect the suspended protection.  */
+        TCT_Protect(suspend_protect);
+
+    /* Now protect the system structures again.  Note that the order the
+       protections are made prevents deadlocks.  */
+    TCT_Protect(&TCD_System_Protect);
+
+    /* Determine if the task is still suspended in the same manner.  */
+    if ((task -> tc_status == task_status) ||
+      ((task -> tc_signal_active) && (task -> tc_saved_status == task_status)))
+    {
+
+        /* Make sure that this timeout processing is still valid. */
+        if ((task -> tc_timer_active) &&
+                 (task -> tc_timer_control.tm_remaining_time == 0))
+        {
+
+            /* Clear the timer active flag.  */
+            task -> tc_timer_active =  NU_FALSE;
+
+            /* Call the cleanup function, if there is one.  */
+            if (task -> tc_cleanup)
+
+                /* Call cleanup function.  */
+                (*(task -> tc_cleanup)) (task -> tc_cleanup_info);
+
+            /* Resume the task.  */
+            TCC_Resume_Task(task_ptr, task_status);
+        }
+    }
+
+    /* Determine if a suspend protection was in force.  */
+    if (suspend_protect)
+    {
+
+        /* Set the current protection to the suspend protect.  */
+        TCT_Set_Current_Protect(suspend_protect);
+        TCT_Unprotect_Specific(&TCD_System_Protect);
+    }
+
+    /* Release current protection.  */
+    TCT_Unprotect();
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Task_Sleep                                                   */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function provides task sleep suspensions.  Its primary      */
+/*      purpose is to interface with the actual task suspension function.*/
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      TCC_Suspend_Task                    Suspend a task               */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect system structures    */
+/*      TCT_Unprotect                       Release system structures    */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      ticks                               Number of timer ticks        */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified call to suspend the                     */
+/*                      calling task, resulting in                       */
+/*                      version 1.1                                      */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TCC_Task_Sleep(UNSIGNED ticks)
+{
+
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_SLEEP_ID, (UNSIGNED) ticks,
+                                        (UNSIGNED) 0, (UNSIGNED) 0);
+
+#endif
+
+
+    /* Protect system data structures.  */
+    TCT_Protect(&TCD_System_Protect);
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTask((TC_TCB *)TCD_Current_Thread,RT_PROF_SLEEP);
+#endif /*INCLUDE_PROVIEW*/
+
+    /* Call the actual routine to suspend the task.  */
+    TCC_Suspend_Task((NU_TASK *) TCD_Current_Thread, NU_SLEEP_SUSPEND,
+                                                NU_NULL, NU_NULL, ticks);
+
+    /* Release system protection.  */
+    TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Relinquish                                                   */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function moves the calling task to the end of other tasks   */
+/*      at the same priority level.  The calling task does not execute   */
+/*      again until all the other tasks of the same priority get a       */
+/*      chance to execute.                                               */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TCCE_Relinquish                     Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Control_To_System               Transfer control to system   */
+/*      TCT_Protect                         Protect system structures    */
+/*      TCT_Set_Execute_Task                Set TCD_Execute_Task pointer */
+/*      TCT_Unprotect                       Release protection           */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified protection logic,                       */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TCC_Relinquish(VOID)
+{
+
+TC_TCB         *task;                       /* Pointer to task           */
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_RELINQUISH_ID, (UNSIGNED) 0,
+                                        (UNSIGNED) 0, (UNSIGNED) 0);
+
+#endif
+
+    /* Protect against multiple access to the system structures.  */
+    TCT_Protect(&TCD_System_Protect);
+
+    /* Pickup the current thread and place it in the task pointer.  */
+    task =  (TC_TCB *) TCD_Current_Thread;
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTask(task,RT_PROF_RELINQUISH);
+#endif /*INCLUDE_PROVIEW*/
+     
+    /* Determine if another task is ready to run.  */
+    if ((task -> tc_ready_next != task) ||
+        (task -> tc_priority != (DATA_ELEMENT) TCD_Highest_Priority))
+    {
+
+        /* Move the executing task to the end of tasks having the same
+           priority. */
+        *(task -> tc_priority_head) =  task -> tc_ready_next;
+
+        /* Setup the next task to execute.  */
+        TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]);
+
+        /* Transfer control back to the system.  */
+        TCT_Control_To_System();
+    }
+
+    /* Release protection of system structures.  */
+    TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Time_Slice                                                   */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function moves the specified task to the end of the other   */
+/*      tasks at the same priority level.  If the specified task is no   */
+/*      longer ready, this request is ignored.  This routine must be     */
+/*      called from Supervisor mode in a Supervisor/User mode            */
+/*      switching kernel.                                                */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      TMC_Timer_HISR                      Time-slice interrupt         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect the scheduling data  */
+/*      TCT_Set_Execute_Task                Set TCD_Execute_Task pointer */
+/*      TCT_Unprotect                       Release protection           */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      task                                Task control block pointer   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      added register optimizations,                    */
+/*                      slightly modified protection                     */
+/*                      logic, resulting in version 1.1                  */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TCC_Time_Slice(NU_TASK *task_ptr)
+{
+
+R1 TC_TCB      *task;                       /* Task control block ptr    */
+
+
+    /* Move input task control block pointer into internal pointer.  */
+    task =  (TC_TCB *) task_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+    /* Protect against multiple access to the system structures.  */
+    TCT_Protect(&TCD_System_Protect);
+
+    /* Determine if another task is ready to run.  */
+    if (((task -> tc_status == NU_READY) && (task -> tc_preemption)) &&
+        ((task -> tc_ready_next != task) ||
+         (task -> tc_priority != (DATA_ELEMENT) TCD_Highest_Priority)))
+    {
+
+        /* Move the executing task to the end of tasks having the same
+           priority. */
+        *(task -> tc_priority_head) =  task -> tc_ready_next;
+
+        /* Setup the next task to execute.  */
+        TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]);
+
+    }
+
+    /* Release protection of the system structures.  */
+    TCT_Unprotect();
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Current_Task_Pointer                                         */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function returns the pointer of the currently executing     */
+/*      task.  If the current thread is not a task thread, a NU_NULL     */
+/*      is returned.                                                     */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      Other Components                                                 */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      Task Pointer                        Active tasks pointer or      */
+/*                                            NU_NULL if not a task      */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+NU_TASK  *TCC_Current_Task_Pointer(VOID)
+{
+
+
+    /* Determine if a task thread is executing.  */
+    if ((TCD_Current_Thread) &&
+        (((TC_TCB *) TCD_Current_Thread) -> tc_id == TC_TASK_ID))
+
+        /* Task thread is running, return the pointer.  */
+        return((NU_TASK *) TCD_Current_Thread);
+    else
+
+        /* No, task thread is not running, return a NU_NULL.  */
+        return(NU_NULL);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Current_HISR_Pointer                                         */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function returns the pointer of the currently executing     */
+/*      HISR.  If the current thread is not a HISR thread, a NU_NULL     */
+/*      is returned.                                                     */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      Other Components                                                 */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      HISR Pointer                        Active HISR pointer or       */
+/*                                            NU_NULL if not a HISR      */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified function interface,                     */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+NU_HISR  *TCC_Current_HISR_Pointer(VOID)
+{
+
+
+    /* Determine if a HISR thread is executing.  */
+    if ((TCD_Current_Thread) &&
+        (((TC_HCB *) TCD_Current_Thread) -> tc_id == TC_HISR_ID))
+
+        /* HISR thread is running, return the pointer.  */
+        return((NU_HISR *) TCD_Current_Thread);
+    else
+
+        /* No, HISR thread is not running, return a NU_NULL.  */
+        return(NU_NULL);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Task_Shell                                                   */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function is shell from which all application tasks are      */
+/*      initially executed.  The shell causes the task to finish when    */
+/*      control is returned from the application task.  Also, the shell  */
+/*      passes argc and argv arguments to the task's entry function.     */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      TCC_Control_To_Task                 Control to task routine      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      Task Entry Function                                              */
+/*      TCC_Suspend_Task                    Suspend task when finished   */
+/*      TCT_Protect                         Protect system structures    */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Added protection logic prior to                  */
+/*                      suspending the task, resulting                   */
+/*                      in version 1.1                                   */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TCC_Task_Shell(VOID)
+{
+NU_SUPERV_USER_VARIABLES
+
+    /* Call the task's entry function with the argc and argv parameters
+       supplied during task creation or reset.  */
+    (*(TCD_Execute_Task -> tc_entry)) (TCD_Execute_Task -> tc_argc,
+                                       TCD_Execute_Task -> tc_argv);
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Protect system data structures.  */
+    TCT_Protect(&TCD_System_Protect);
+
+    /* If the task returns, suspend it in a finished state.  Note that
+       the task cannot execute again until it is reset.  Therefore, this
+       call never returns.  */
+    TCC_Suspend_Task((NU_TASK *) TCD_Execute_Task, NU_FINISHED,
+                                NU_NULL, NU_NULL, NU_SUSPEND);
+
+    /* Return to user mode */
+    NU_USER_MODE();
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Signal_Shell                                                 */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function processes signals by calling the task supplied     */
+/*      signal handling function.  When signal handling is completed,    */
+/*      the task is placed in the appropriate state.                     */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      TCC_Control_Signals                 Control task's signals       */
+/*      TCC_Register_Signal_Handler         Register a signal handler    */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      task's signal handling routine                                   */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Signal_Exit                     Signal handling exit routine */
+/*      TCT_Protect                         Protect against other access */
+/*      TCT_Set_Execute_Task                Set TCD_Execute_Task pointer */
+/*      TCT_Unprotect                       Release protection           */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Added register optimizations,                    */
+/*                      modified protection logic,                       */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TCC_Signal_Shell(VOID)
+{
+
+R2 UNSIGNED     signals;                    /* Signals to send to task   */
+INT             index;                      /* Working index variable    */
+DATA_ELEMENT    temp;                       /* Temporary variable        */
+R1 TC_TCB      *task;                       /* Task pointer              */
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+    /* Point at the current task.  */
+    task =  (TC_TCB *) TCD_Current_Thread;
+
+    /* Protect against simultaneous access.  */
+    TCT_Protect(&TCD_System_Protect);
+
+    /* Process while there are signals to handle.  */
+    while (task -> tc_signals & task -> tc_enabled_signals)
+    {
+
+        /* Pickup the signals and clear them.  */
+        signals =  task -> tc_signals;
+        task -> tc_signals =  0;
+
+        /* Release protection.  */
+        TCT_Unprotect();
+
+        /* Call the application signal handling function, if there still is
+           one.  */
+        if (task -> tc_signal_handler)
+        {
+            NU_SUPERV_USER_VARIABLES
+
+#if (defined(NU_SUPERV_USER_MODE)) && (NU_SUPERV_USER_MODE > 0)
+            UNSIGNED savedMode = task->tc_su_mode;
+            task->tc_su_mode = 1;         /* Force transition to User mode */
+#endif
+            /* Switch to user mode */
+            NU_USER_MODE();
+
+            /* Call signal handler.  (always in User mode) */
+            (*(task -> tc_signal_handler))(signals);
+
+            /* Return to supervisor mode */
+            NU_SUPERVISOR_MODE();
+
+#if (defined(NU_SUPERV_USER_MODE)) && (NU_SUPERV_USER_MODE > 0)
+            task->tc_su_mode = savedMode;   /* Restore original nesting count */
+#endif
+        }
+
+        /* Protect against simultaneous access again.  */
+        TCT_Protect(&TCD_System_Protect);
+    }
+
+    /* At this point, signals have been exhausted and protection is in
+       force.  */
+
+    /* Clear the signal in process flag.  */
+    task -> tc_signal_active =  NU_FALSE;
+
+    /* Determine how the signal handler was called.  Either in a solicited or
+       an unsolicited manner.  */
+    if (task -> tc_saved_stack_ptr)
+    {
+
+        /* Determine if the saved status still indicates that the task should
+           be suspended.  */
+        if (task -> tc_saved_status != NU_READY)
+        {
+
+            /* Suspend the task.  */
+            task -> tc_status =  task -> tc_saved_status;
+
+            /* Remove the task from the ready list.  */
+
+            /* Determine if the task is the only one on the list.  */
+            if (task -> tc_ready_next == task)
+            {
+
+                /* Only task on the list.  Clear the task's pointers and
+                   clear the entry in the priority table.  */
+                task -> tc_ready_next =        NU_NULL;
+                task -> tc_ready_previous =    NU_NULL;
+                *(task -> tc_priority_head) =  NU_NULL;
+
+                /* Clear the sub-priority group.  */
+                *(task -> tc_sub_priority_ptr) =
+                 (*(task -> tc_sub_priority_ptr)) & ~(task -> tc_sub_priority);
+
+                /* Determine if the main priority group needs to be cleared.
+                   This is only true if there are no other bits set in this
+                   sub-priority.  */
+                if (*(task -> tc_sub_priority_ptr) == 0)
+
+                /* Clear the main priority group bit.  */
+                TCD_Priority_Groups =
+                    TCD_Priority_Groups & ~(task -> tc_priority_group);
+
+                /* Determine if this priority group was the highest in the
+                   system.  */
+                if (task -> tc_priority == (DATA_ELEMENT) TCD_Highest_Priority)
+                {
+
+                    /* Determine the highest priority task in the system.  */
+                    if (TCD_Priority_Groups == 0)
+                    {
+
+                        /* Re-initialize the highest priority variable and
+                           clear the current task pointer.  */
+                        TCD_Highest_Priority =  TC_PRIORITIES;
+                    }
+                    else
+                    {
+
+                        /* Find the next highest priority task.  */
+                        if (TCD_Priority_Groups & TC_HIGHEST_MASK)
+
+                            /* Base of sub-group is 0.  */
+                            index =  0;
+
+                        else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK)
+
+                            /* Base of sub-group is 8.  */
+                            index =  8;
+
+                        else if (TCD_Priority_Groups & TC_NEXT_LOWEST_MASK)
+
+                            /* Base of sub-group is 16.  */
+                            index =  16;
+                        else
+
+                            /* Base of sub-group is 24.  */
+                            index =  24;
+
+                        /* Calculate the highest available priority.  */
+                        index =  index + TCD_Lowest_Set_Bit[(INT)
+                           ((TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)];
+
+                        /* Get the mask of the priority within the group of
+                           8 priorities.  */
+                        temp =  TCD_Sub_Priority_Groups[index];
+
+                        /* Calculate the actual priority.  */
+                        TCD_Highest_Priority =
+                            (index << 3) + TCD_Lowest_Set_Bit[temp];
+                    }
+                }
+            }
+            else
+            {
+
+                /* Not the only task ready at the same priority level.  */
+
+                /* Remove from the linked-list.  */
+                (task -> tc_ready_previous) -> tc_ready_next =
+                                                 task -> tc_ready_next;
+                (task -> tc_ready_next) -> tc_ready_previous =
+                                                 task -> tc_ready_previous;
+
+                /* See if the task being suspended is the current.  */
+                if (*(task -> tc_priority_head) == task)
+
+                    /* Update the head of this priority list.  */
+                    *(task -> tc_priority_head) =  task -> tc_ready_next;
+
+                /* Clear the task's pointers.  */
+                task -> tc_ready_next =        NU_NULL;
+                task -> tc_ready_previous =    NU_NULL;
+            }
+
+            /* Determine the next task to execute.  */
+            if (TCD_Highest_Priority < TC_PRIORITIES)
+
+                /* Put the next task to execute in TCD_Execute_Task.  */
+                TCT_Set_Execute_Task(TCD_Priority_List[TCD_Highest_Priority]);
+            else
+
+                /* No other task is ready for execution.  */
+                TCT_Set_Execute_Task(NU_NULL);
+        }
+
+        /* At this point, just exit back to the system.  Note that the
+           signal exit routine clears the scheduling protection.  */
+        TCT_Signal_Exit();
+    }
+
+    /* A signal handler was called from the current task.  Nothing needs
+       to be done except to release protection.  */
+    TCT_Unprotect();
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Dispatch_LISR                                                */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function dispatches the LISR associated with the specified  */
+/*      interrupt vector.  Note that this function is called during      */
+/*      the interrupt thread.  This routine must be called from          */
+/*      Supervisor mode in a Supervisor/User mode switching kernel.      */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      INT_Interrupt_Shell                 Shell of interrupt routine   */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      application LISR                                                 */
+/*      ERC_System_Error                    Unhandled interrupt error    */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      vector                              Vector number of interrupt   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      11-01-1993      Added logic to save unhandled                    */
+/*                      interrupt vector number in                       */
+/*                      a global variable, resulting                     */
+/*                      in version 1.0e                                  */
+/*      11-01-1993      Verified version 1.0e                            */
+/*                                                                       */
+/*************************************************************************/
+VOID  TCC_Dispatch_LISR(INT vector)
+{
+
+INT             index;                      /* Working index variable    */
+
+
+    /* Determine if the specified vector has an LISR registered to it.  */
+    index =  (INT)  TCD_Registered_LISRs[vector];
+    if (index <= NU_MAX_LISRS)
+    {
+#ifdef INCLUDE_PROVIEW
+        _RTProf_Dispatch_LISR_No_INT_Lock(vector);
+#endif /*INCLUDE_PROVIEW*/
+
+        /* Yes, an LISR is associated with this vector.  Call the actual
+           registered LISR routine.  */
+        (*(TCD_LISR_Pointers[index])) (vector);
+    }
+    else
+    {
+
+        /* Save interrupt vector number in TCD_Unhandled_Interrupt.  */
+        TCD_Unhandled_Interrupt =  vector;
+
+        /* System error, unhandled interrupt.  */
+        ERC_System_Error(NU_UNHANDLED_INTERRUPT);
+    }
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TCC_Register_LISR                                                */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function registers the supplied LISR with the supplied      */
+/*      vector number.  If the supplied LISR is NU_NULL, the supplied    */
+/*      vector is de-registered.  The previously registered LISR is      */
+/*      returned to the caller, along with the completion status.  This  */
+/*      routine must be called from Supervisor mode in a Supervisor/     */
+/*      User mode switching kernel.                                      */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      INT_Retrieve_Shell                  Retrieve vector shell pointer*/
+/*      INT_Setup_Vector                    Setup the actual vector      */
+/*      INT_Vectors_Loaded                  Determine if interrupt shell */
+/*                                            routines are loaded        */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect LISR registration    */
+/*      TCT_Unprotect                       Release LISR protection      */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      vector                              Vector number of interrupt   */
+/*      new_lisr                            New LISR function            */
+/*      old_lisr                            Previous LISR function ptr   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                          Successful registration      */
+/*      NU_INVALID_VECTOR                   Invalid interrupt vector     */
+/*      NU_NO_MORE_LISRS                    LISR registration table is   */
+/*                                            full                       */
+/*      NU_NOT_REGISTERED                   LISR was not registered      */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Added appropriate casting,                       */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TCC_Register_LISR(INT vector, VOID (*new_lisr)(INT),
+                                        VOID (**old_lisr)(INT))
+{
+
+INT             index;                      /* Working index variable    */
+STATUS          status;                     /* Completion status         */
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_REGISTER_LISR_ID, (UNSIGNED) vector,
+                                (UNSIGNED) new_lisr, (UNSIGNED) old_lisr);
+
+#endif
+
+    /* Determine if the vector is legal. */
+    if (vector > NU_MAX_VECTORS)
+        return(NU_INVALID_VECTOR);
+
+    /* Initialize the completion status to successful.  */
+    status =  NU_SUCCESS;
+
+    /* Protect against LISR registration list access.  */
+    TCT_Protect(&TCD_LISR_Protect);
+
+    /* Determine if a registration or deregistration is requested.  This is
+       determined by the value of new_lisr.  A NULL value indicates
+       deregistration.  */
+    if (new_lisr)
+    {
+
+        /* Register the new LISR.  */
+
+        /* Determine if the vector already has a registration.  */
+        if (TCD_Registered_LISRs[vector])
+        {
+
+            /* Yes, a registration exists.  */
+
+            /* Pickup the index into the LISR pointer list.  */
+            index =  (INT) TCD_Registered_LISRs[vector];
+
+            /* Temporarily indicate that the LISR is not registered.  */
+            TCD_Registered_LISRs[vector] =  0;
+
+            /* Copy the currently registered LISR into the old_lisr return
+               area.  */
+            *old_lisr =  TCD_LISR_Pointers[index];
+
+            /* Place the new LISR into the list. */
+            TCD_LISR_Pointers[index] =  new_lisr;
+
+            /* Indicate the LISR is registered again.  */
+            TCD_Registered_LISRs[vector] =  (UNSIGNED_CHAR) index;
+        }
+        else
+        {
+
+            /* An empty slot needs to be found in the LISR pointers list.  */
+
+            index =  0;
+            while ((index <= NU_MAX_LISRS) && 
+                   (TCD_LISR_Pointers[index] != NU_NULL))
+                      index++;
+
+            /* Determine if an empty slot was found.  */
+            if (index <= NU_MAX_LISRS)
+            {
+
+                /* Yes, an empty slot was found.  */
+
+                /* Place the new LISR in the LISR pointers list.  */
+                TCD_LISR_Pointers[index] =  new_lisr;
+
+                /* Associate the index into the pointers list to the actual
+                   vector.  */
+                TCD_Registered_LISRs[vector] =  (UNSIGNED_CHAR) index;
+
+                /* Indicate that there was no previous LISR registered.  */
+                *old_lisr =  NU_NULL;
+
+                /* Determine if the actual vector needs to be stolen.  */
+                if (!INT_Vectors_Loaded())
+
+                    /* Actual vector needs to be replaced with the
+                       appropriate ISR shell.  */
+                    INT_Setup_Vector(vector, INT_Retrieve_Shell(vector));
+            }
+            else
+
+                /* Return the completion status that indicates that there
+                   is no more room in the LISR pointers list.  */
+                status =  NU_NO_MORE_LISRS;
+        }
+    }
+    else
+    {
+
+        /* De-register the specified vector.  */
+
+        /* Determine if the vector has a registration current.  */
+        if (TCD_Registered_LISRs[vector])
+        {
+
+            /* Pickup the index into the LISR pointer list.  */
+            index =  (INT) TCD_Registered_LISRs[vector];
+
+            /* Clear the registration table.  */
+            TCD_Registered_LISRs[vector] =  0;
+
+            /* Return the previously registered LISR.  */
+            *old_lisr =  TCD_LISR_Pointers[index];
+
+            /* Clear the LISR pointer list entry.  */
+            TCD_LISR_Pointers[index] =  NU_NULL;
+        }
+        else
+
+            /* The vector is not registered.  Return an error completion
+               status.  */
+            status =  NU_NOT_REGISTERED;
+    }
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_RegisterLisr(vector);
+#endif /*INCLUDE_PROVIEW*/
+
+    /* Release protection on the LISR registration list.  */
+    TCT_Unprotect();
+
+    /* Return the completion status.  */
+    return(status);
+}
+
+
+
+
+
+