diff src/nucleus/tmc.c @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nucleus/tmc.c	Fri Oct 16 06:23:26 2020 +0000
@@ -0,0 +1,944 @@
+/*************************************************************************/
+/*                                                                       */
+/*               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       */
+/*                                                                       */
+/*      tmc.c                                          Nucleus PLUS 1.14 */
+/*                                                                       */
+/* COMPONENT                                                             */
+/*                                                                       */
+/*      TM - Timer Management                                            */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This file contains the core routines for the timer management    */
+/*      component.                                                       */
+/*                                                                       */
+/* DATA STRUCTURES                                                       */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* FUNCTIONS                                                             */
+/*                                                                       */
+/*      TMC_Init_Task_Timer                 Initialize task timer        */
+/*      TMC_Start_Task_Timer                Start task timer             */
+/*      TMC_Stop_Task_Timer                 Stop task timer              */
+/*      TMC_Start_Timer                     Actually start a timer       */
+/*      TMC_Stop_Timer                      Actually stop a timer        */
+/*      TMC_Timer_HISR                      Timer High-Level Interrupt   */
+/*                                            Service Routine (HISR)     */
+/*      TMC_Timer_Expiration                Timer expiration function    */
+/*                                                                       */
+/* DEPENDENCIES                                                          */
+/*                                                                       */
+/*      cs_extr.h                           Common Service functions     */
+/*      tc_extr.h                           Thread Control functions     */
+/*      tm_extr.h                           Timer functions              */
+/*      hi_extr.h                           History functions            */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      08-09-1993      Corrected the following problems                 */
+/*                       - Moved sleep, timeout, and                     */
+/*                         application timer expiration                  */
+/*                         processing to system timer                    */
+/*                         HISR.  Removed timer task                     */
+/*                         logic                                         */
+/*                       - Corrected a disable timer                     */
+/*                         problem that caused a delay                   */
+/*                         in subsequent timer                           */
+/*                         expiration                                    */
+/*                       - Corrected the application                     */
+/*                         timer ID returned by the                      */
+/*                         timer information service                     */
+/*                         Corrected the loop to return                  */
+/*                         all application timer                         */
+/*                         pointers                                      */
+/*                       - Corrected timer expiration                    */
+/*                         while accessing from an LISR                  */
+/*                       - Using the task time slice ptr                 */
+/*                         instead of the time slice                     */
+/*                         state flag                                    */
+/*                         Modifications resulted in                     */
+/*                         version 1.0a                                  */
+/*      08-09-1993      Verified version 1.0a                            */
+/*      03-01-1994      Moved non-core functions into                    */
+/*                        supplemental files, modified                   */
+/*                        protection logic to use system                 */
+/*                        protect mechanism, removed the                 */
+/*                        disable timer logic in start                   */
+/*                        timer, insured valid time-                     */
+/*                        slice task pointer, added                      */
+/*                        register logic, resulting                      */
+/*                        in version 1.1                                 */
+/*                                                                       */
+/*      3-18-1994       Verified version 1.1                             */
+/*      08-25-95        Made the following changes                       */
+/*                                                                       */
+/*    +INT             type = 0;                Type of expiration       */
+/*    +VOID           *pointer = NU_NULL;       Pointer type             */
+/*    +UNSIGNED        id = 0;                  Application timer ID     */
+/*    -INT             type;                    Type of expiration       */
+/*    -VOID           *pointer;                 Pointer type             */
+/*    -UNSIGNED        id;                      Application timer ID     */
+/*                                              Expiration routine ptr   */
+/*    +VOID            (*expiration_routine)(UNSIGNED)= NU_NULL;         */
+/*    -VOID            (*expiration_routine)(UNSIGNED);                  */
+/*      04-17-1996      updated to version 1.2                           */
+/*      03-24-1998      Released version 1.3.                            */
+/*      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        "cs_extr.h"                 /* Common service functions  */
+#include        "tc_extr.h"                 /* Thread control functions  */
+#include        "tm_extr.h"                 /* Timer functions           */
+#include        "hi_extr.h"                 /* History functions         */
+
+
+/* Define external inner-component global data references.  */
+
+extern TM_TCB         *TMD_Active_Timers_List;
+extern INT             TMD_Active_List_Busy;
+extern UNSIGNED        TMD_System_Clock;
+extern UNSIGNED        TMD_Timer_Start;
+extern UNSIGNED        TMD_Timer;
+extern INT             TMD_Timer_State;
+extern UNSIGNED        TMD_Time_Slice;
+extern TC_TCB         *TMD_Time_Slice_Task;
+extern INT             TMD_Time_Slice_State;
+
+
+/* Define internal function prototypes.  */
+
+VOID            TMC_Start_Timer(TM_TCB *timer, UNSIGNED time);
+VOID            TMC_Stop_Timer(TM_TCB *timer);
+VOID            TMC_Timer_Expiration(VOID);
+UNSIGNED        TMT_Read_Timer(VOID);
+VOID            TMT_Enable_Timer(UNSIGNED time);
+VOID            TMT_Disable_Timer(VOID);
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMC_Init_Task_Timer                                              */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function is responsible for initializing the supplied task  */
+/*      timer.  This routine must be called from Supervisor mode in a    */
+/*      Supervisor/User mode switching kernel.                           */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      TCC_Create_Task                     Task create function         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer                               Timer control block pointer  */
+/*      information                         Information pointer - always */
+/*                                            the task pointer           */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TMC_Init_Task_Timer(TM_TCB *timer, VOID *information)
+{
+
+    /* Initialize the task timer.  */
+    timer -> tm_timer_type =      TM_TASK_TIMER;
+    timer -> tm_information =     information;
+    timer -> tm_next_timer =      NU_NULL;
+    timer -> tm_previous_timer =  NU_NULL;
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMC_Start_Task_Timer                                             */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function is responsible for starting a task timer.  Note    */
+/*      that there are some special protection considerations since      */
+/*      this function is called from the task control component.  This   */
+/*      routine must be called from Supervisor mode in a Supervisor/User */
+/*      mode switching kernel.                                           */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      TCC_Suspend_Task                    Suspend task with a timeout  */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      TMC_Start_Timer                     Start the timer              */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer                               Timer control block pointer  */
+/*      time                                Time associated with timer   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Removed protection logic since                   */
+/*                      system protect is in force at                    */
+/*                      the time this function is                        */
+/*                      called, resulting in                             */
+/*                      version 1.1                                      */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TMC_Start_Task_Timer(TM_TCB *timer, UNSIGNED time)
+{
+
+    /* Start the specified timer.  */
+    TMC_Start_Timer(timer, time);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMC_Stop_Task_Timer                                              */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function is responsible for stopping a task timer.  Note    */
+/*      that there are some special protection considerations since      */
+/*      this function is called from the task control component.  This   */
+/*      routine must be called from Supervisor mode in a Supervisor/User */
+/*      mode switching kernel.                                           */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      TCC_Resume_Task                     Resume task function         */
+/*      TCC_Terminate_Task                  Terminate task function      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      TMC_Stop_Timer                      Stop the timer               */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer                               Timer 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      Removed protection logic since                   */
+/*                      system protect is in force at                    */
+/*                      the time this function is                        */
+/*                      called, resulting in                             */
+/*                      version 1.1                                      */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TMC_Stop_Task_Timer(TM_TCB *timer)
+{
+
+    /* Stop the specified timer - if it is still active.  */
+    if (timer -> tm_next_timer)
+
+        TMC_Stop_Timer(timer);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMC_Start_Timer                                                  */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function is responsible for starting both application and   */
+/*      task timers.  This routine must be called from Supervisor mode   */
+/*      in a Supervisor/User mode switching kernel.                      */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      TMC_Control_Timer                   Control application timer    */
+/*      TMC_Start_Task_Timer                Start task timer             */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      TMT_Read_Timer                      Read current timer counter   */
+/*      TMT_Adjust_Timer                    Adjust the count-down timer  */
+/*      TMT_Enable_Timer                    Enable count-down timer      */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer                               Timer control block pointer  */
+/*      time                                Time associated with timer   */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      08-09-1993      Added logic to check for timer                   */
+/*                        expiration before or during                    */
+/*                        another LISR's access,                         */
+/*                        resulting in version 1.0a                      */
+/*      08-09-1993      Verified version 1.0a                            */
+/*      03-01-1994      Removed disable timer logic to                   */
+/*                        insure there is no timer loss,                 */
+/*                        added register logic,                          */
+/*                        resulting in version 1.1                       */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TMC_Start_Timer(TM_TCB *timer, UNSIGNED time)
+{
+
+R1 TM_TCB      *list_ptr;                   /* Working pointer timer ptr */
+UNSIGNED        elapsed;                    /* Elapsed time variable     */
+INT             done;                       /* Search finished flag      */
+
+
+    /* Note that protection over the active timer list is in force when this
+       function is called.  */
+
+    /* Determine if the active list is empty.  */
+    if (TMD_Active_Timers_List == NU_NULL)
+    {
+
+        /* Place the timer on an empty list.  */
+        timer -> tm_next_timer =      timer;
+        timer -> tm_previous_timer =  timer;
+
+        /* Link the timer to the list head.  */
+        TMD_Active_Timers_List =  timer;
+
+        /* Setup the actual count-down timer structures.  */
+        TMD_Timer_Start =  time;
+        timer -> tm_remaining_time =  time;
+
+
+        /* BUG FIX FOR NU_RESET WITH INITIAL TIME OF 0 */
+        /* Determine if there is any time remaining on the timer.
+           If so, enable the timer. Otherwise, the Timer HISR is
+           already pending, so skip starting the timer again.  */
+
+        if (time != 0)
+           /* Start the actual count-down timer.  */
+           TMT_Enable_Timer(TMD_Timer_Start);
+        else
+           TMD_Timer_State =  TM_EXPIRED;
+
+    }
+    else
+    {
+
+        /* Place the new timer into the list.  */
+
+        /* Pickup the head of the list.  */
+        list_ptr =  TMD_Active_Timers_List;
+
+        /* Determine if the timer is being added while the timer
+           expiration task is running.  If so, don't attempt to adjust
+           the expiration list.  If not, adjust the list.  */
+        if (!TMD_Active_List_Busy)
+        {
+
+            /* Calculate the elapsed amount of time from the last timer
+               request.  */
+            elapsed =  TMD_Timer_Start -  TMT_Read_Timer();
+
+            /* Adjust the first entry in the timer list and the timer
+               start value accordingly.  */
+            TMD_Timer_Start =  TMD_Timer_Start - elapsed;
+
+            /* Make sure the remaining time is never below zero.  */
+            if (list_ptr -> tm_remaining_time > elapsed)
+            {
+                list_ptr -> tm_remaining_time = list_ptr -> tm_remaining_time
+                    - elapsed;
+            }
+            else
+            {
+                list_ptr -> tm_remaining_time = 0;
+            }
+
+
+        }
+
+        /* At this point the timer list is accurate again.  Find the
+           appropriate place on the timer list for the new timer.  */
+
+        /* Determine where to place the timer in the list.  */
+        done =  NU_FALSE;
+        do
+        {
+
+            /* Determine if the timer belongs before the current timer
+               pointed to by list_ptr.  */
+            if (time < list_ptr -> tm_remaining_time)
+            {
+
+                /* Update the time of the next timer.  */
+                list_ptr -> tm_remaining_time =
+                                list_ptr -> tm_remaining_time - time;
+
+                /* Determine if an insertion at the head of the list is
+                   present.  */
+                if (list_ptr == TMD_Active_Timers_List)
+
+                    /* Move the list head to the new timer.  */
+                    TMD_Active_Timers_List =  timer;
+
+                /* Set the done flag to end the search.  */
+                done =  NU_TRUE;
+            }
+            else
+            {
+
+                /* Decrement the time by the remaining value of each timer in
+                   the list.  In this way, the list never has to be searched
+                   again.  */
+                time =  time - list_ptr -> tm_remaining_time;
+
+                /* Move the list pointer to the next timer in the list.  */
+                list_ptr =  list_ptr -> tm_next_timer;
+
+                /* Check to see if the list has wrapped around.  */
+                if (list_ptr == TMD_Active_Timers_List)
+
+                    /* Searching is done.  */
+                    done =  NU_TRUE;
+            }
+        } while (!done);
+
+        /* Link the new timer into the list.  */
+        timer -> tm_next_timer =      list_ptr;
+        timer -> tm_previous_timer =  list_ptr -> tm_previous_timer;
+        (list_ptr -> tm_previous_timer) -> tm_next_timer =  timer;
+        list_ptr -> tm_previous_timer =  timer;
+
+        /* Update the remaining time parameter.  */
+        timer -> tm_remaining_time =  time;
+
+        /* Determine if a new timer should be started.  */
+        if (!TMD_Active_List_Busy)
+        {
+
+            /* Calculate the new timer expiration.  */
+            time =  TMD_Active_Timers_List -> tm_remaining_time;
+
+            /* Determine if the new expiration is less than the current
+               time, if any.  If not, let already started time expire.  */
+            if (time <= TMD_Timer_Start)
+            {
+
+                /* Setup for a smaller timer expiration.  */
+                TMD_Timer_Start =  time;
+
+                /* Determine if there is any time remaining on the timer in
+                   the front of the list.  If so, adjust the timer.
+                   Otherwise, the Timer HISR is already pending, so skip
+                   starting the timer again.  */
+                if (TMD_Timer_Start)
+
+                    /* Still some remaining time, adjust the timer.  */
+                    TMT_Adjust_Timer(TMD_Timer_Start);
+                else
+
+                    /* Indicate that the task and application timer has
+                       expired. */
+                    TMD_Timer_State =  TM_EXPIRED;
+            }
+        }
+    }
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMC_Stop_Timer                                                   */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function is responsible for stopping both application and   */
+/*      task timers.  This routine must be called from Supervisor mode   */
+/*      in a Supervisor/User mode switching kernel.                      */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      TMC_Control_Timer                   Control application timer    */
+/*      TMC_Stop_Task_Timer                 Start task timer             */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      TMT_Disable_Timer                   Disable the count-down timer */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer                               Timer control block pointer  */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      08-09-1993      Corrected a problem associated                   */
+/*                      with stopping the last timer                     */
+/*                      on the active list, resulting                    */
+/*                      in version 1.0a                                  */
+/*      08-09-1993      Verified version 1.0a                            */
+/*                                                                       */
+/*************************************************************************/
+VOID  TMC_Stop_Timer(TM_TCB *timer)
+{
+
+    /* Note that the active timer list is already under protection.  */
+
+    /* If the next neighbor of the timer that needs to be stopped is not the
+       head of the timer list, add the remaining time field to the remaining
+       time of the next neighbor.  */
+    if ((timer -> tm_next_timer) != TMD_Active_Timers_List)
+
+        /* Adjust the next neighbor's remaining time field.  */
+        (timer -> tm_next_timer) -> tm_remaining_time =
+                   (timer -> tm_next_timer) -> tm_remaining_time +
+                                                timer -> tm_remaining_time;
+
+    /* Unlink the timer from the active list.  */
+    if (timer -> tm_next_timer == timer)
+    {
+        /* Only timer on the list.  */
+        TMD_Active_Timers_List =  NU_NULL;
+
+        /* Disable the timer.  */
+        TMT_Disable_Timer();
+    }
+    else
+    {
+
+        /* More than one timer on the list.  */
+        (timer -> tm_previous_timer) -> tm_next_timer = timer -> tm_next_timer;
+        (timer -> tm_next_timer) -> tm_previous_timer =
+                                                timer -> tm_previous_timer;
+
+        /* Determine if the timer is at the head of the list.  */
+        if (TMD_Active_Timers_List == timer)
+
+            /* Yes, move the head pointer to the next timer.  */
+            TMD_Active_Timers_List =  timer -> tm_next_timer;
+    }
+
+    /* Clear the timer's next and previous pointers.  */
+    timer -> tm_next_timer =      NU_NULL;
+    timer -> tm_previous_timer =  NU_NULL;
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMC_Timer_HISR                                                   */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function is responsible for High-Level interrupt processing */
+/*      of a timer expiration.  If an application timer has expired,     */
+/*      the timer expiration function is called.  Otherwise, if the      */
+/*      time-slice timer has expired, time-slice processing is invoked.  */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      TCC_Time_Slice                      Task time-slice processing   */
+/*      TMC_Timer_Expiration                Timer expiration processing  */
+/*      TMT_Retrieve_TS_Task                Retrieve time-sliced task ptr*/
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      08-09-1993      Added sleep, timeout, and                        */
+/*                      application timer expiration                     */
+/*                      processing to the timer HISR,                    */
+/*                      using time slice task pointer                    */
+/*                      instead of state flag,                           */
+/*                      resulting in version 1.0a                        */
+/*      08-09-1993      Verified version 1.0a                            */
+/*      03-01-1994      Modified function interface to                   */
+/*                      TCC_Time_Slice, added logic to                   */
+/*                      insure valid pointer for some                    */
+/*                      ports, resulting in version 1.1                  */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+VOID  TMC_Timer_HISR(VOID)
+{
+
+NU_TASK     *task;                          /* Time slice task.  */
+
+
+    /* Determine if the task timer has expired.  */
+    if (TMD_Timer_State == TM_EXPIRED)
+
+        /* Resume the timer task.  */
+        TMC_Timer_Expiration();
+
+    /* Determine if the time-slice timer has expired.  */
+    task =  TMT_Retrieve_TS_Task();
+    if (task)
+    {
+        NU_SUPERV_USER_VARIABLES
+
+        /* Switch to supervisor mode
+
+           Note that this HISR function can make the switch to supervisor mode
+           this is only possible because the code lives within the kernel */
+        NU_SUPERVISOR_MODE();
+
+        /* Reset the time-slice state.  */
+        TMD_Time_Slice_State =  TM_NOT_ACTIVE;
+
+        /* Process the time-slice.  */
+        TCC_Time_Slice(task);
+
+        /* Clear the time slice task pointer.  */
+        TMD_Time_Slice_Task =  NU_NULL;
+
+        /* Return to user mode */
+        NU_USER_MODE();
+    }
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMC_Timer_Expiration                                             */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function is responsible for processing all task timer       */
+/*      expirations.  This includes application timers and basic task    */
+/*      timers that are used for task sleeping and timeouts.             */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      expiration_function                 Application specified timer  */
+/*                                            expiration function        */
+/*      TCC_Task_Timeout                    Task timeout function        */
+/*      TCT_System_Protect                  Protect active timer list    */
+/*      TCT_Unprotect                       Release protection of list   */
+/*      TMC_Stop_Timer                      Stop timer                   */
+/*      TMC_Start_Timer                     Start timer                  */
+/*      TMT_Disable_Timer                   Disable timer                */
+/*      TMT_Enable_Timer                    Enable timer                 */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      08-09-1993      Changed from TMC_Timer_Task to                   */
+/*                      TMC_Timer_Expiration,                            */
+/*                      resulting in version 1.0a                        */
+/*      08-09-1993      Verified version 1.0a                            */
+/*      03-01-1994      Modified function interface to                   */
+/*                      TCC_Task_Timeout, changed                        */
+/*                      protection logic to use system                   */
+/*                      protetion, added register                        */
+/*                      logic, resulting in version 1.1                  */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*      08-25-95        Made the following changes                       */
+/*                                                                       */
+/*    +INT             type = 0;                Type of expiration       */
+/*    +VOID           *pointer = NU_NULL;       Pointer type             */
+/*    +UNSIGNED        id = 0;                  Application timer ID     */
+/*    -INT             type;                    Type of expiration       */
+/*    -VOID           *pointer;                 Pointer type             */
+/*    -UNSIGNED        id;                      Application timer ID     */
+/*                                              Expiration routine ptr   */
+/*    +VOID            (*expiration_routine)(UNSIGNED)= NU_NULL;         */
+/*    -VOID            (*expiration_routine)(UNSIGNED);                  */
+/*                                                                       */
+/*************************************************************************/
+VOID  TMC_Timer_Expiration(VOID)
+{
+
+R1 TM_TCB      *timer;                      /* Pointer to timer         */
+R2 TM_APP_TCB  *app_timer;                  /* Pointer to app timer     */
+INT             done;                       /* Expiration completion    */
+INT             type = 0;                   /* Type of expiration       */
+VOID           *pointer = NU_NULL;          /* Pointer type             */
+UNSIGNED        id = 0;                     /* Application timer ID     */
+                                            /* Expiration routine ptr   */
+VOID            (*expiration_routine)(UNSIGNED)= NU_NULL;
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Use system protect to protect the active timer list.  */
+    TCT_System_Protect();
+
+    /* Reset the timer state flag.  */
+    TMT_Disable_Timer();
+
+    /* Set the busy flag to indicate that the list is being processed.  */
+    TMD_Active_List_Busy =  NU_TRUE;
+
+    /* Update the head of the list with the timer expiration
+       value.  */
+    timer =  TMD_Active_Timers_List;
+    if (timer)
+    {
+
+        /* Adjust the active timer's remaining time value.  Note that
+           TMD_Timer_Start is never greater than the value in the first
+           timer location.  */
+        if (timer -> tm_remaining_time > TMD_Timer_Start)
+
+            /* Timer has not expired.  Simply subtract the last timer
+               value. */
+            timer -> tm_remaining_time = timer -> tm_remaining_time -
+                                                    TMD_Timer_Start;
+        else
+
+            /* Clear the remaining time field of the timer.  */
+            timer -> tm_remaining_time =  0;
+    }
+
+    /* Release protection, but keep the busy flag set to prevent
+       activating new timers.  */
+    TCT_Unprotect();
+
+
+    /* Find expired timers.  Note that the expired timers have values of
+       0 in the remaining time field.  */
+    done =  NU_FALSE;
+    do
+    {
+
+        /* Protect against list access.  */
+        TCT_System_Protect();
+
+        /* Pickup the head of the active list.  */
+        timer =  TMD_Active_Timers_List;
+
+        /* Determine if the timer now at the head of the list has
+           expired.  Processing continues until the list is empty or
+           until a non-expired timer is at the front of the list. */
+        if ((timer) && (timer -> tm_remaining_time == 0))
+        {
+
+            /* Timer has expired.  Determine which type of timer has
+               expired.  */
+            if (timer -> tm_timer_type == TM_APPL_TIMER)
+            {
+
+                /* Application timer has expired.  */
+                type =  TM_APPL_TIMER;
+
+                /* Pickup the pointer to the application timer control
+                   block.  */
+                app_timer =  (TM_APP_TCB *) timer -> tm_information;
+
+                /* Increment the number of expirations.  */
+                app_timer -> tm_expirations++;
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTimer(RT_PROF_APP_TIMER_EXPIRED,app_timer,RT_PROF_OK);
+#endif
+
+                /* Move the expiration information into local variables
+                   in case they get corrupted before this expiration can
+                   be processed.  Expirations are processed without the
+                   list protection in force.  */
+                id =                  app_timer -> tm_expiration_id;
+                expiration_routine =  app_timer -> tm_expiration_routine;
+
+                /* Clear the enabled flag and remove the timer from the
+                   list.  */
+                app_timer -> tm_enabled =  NU_FALSE;
+                TMC_Stop_Timer(timer);
+
+                /* Determine if this timer should be started again.  */
+                if (app_timer -> tm_reschedule_time)
+                {
+
+                    /* Timer needs to be rescheduled.  */
+
+                    /* Setup the enable flag to show that the timer is
+                       enabled.  */
+                    app_timer -> tm_enabled =  NU_TRUE;
+
+                    /* Call the start timer function to actually enable
+                       the timer.  This also puts it in the proper place
+                       on the list.  */
+                    TMC_Start_Timer(timer,app_timer -> tm_reschedule_time);
+                }
+            }
+            else
+            {
+
+                /* Task timer has expired (sleeps and timeouts).  */
+                type =  TM_TASK_TIMER;
+
+                /* Remove the timer from the list.  */
+                TMC_Stop_Timer(timer);
+
+                /* Save-off the task control block pointer.  */
+                pointer =  timer -> tm_information;
+            }
+        }
+        else
+
+            /* Processing is now complete- no more expired timers on the
+               list.  */
+            done =  NU_TRUE;
+
+        /* Release protection of active list.  */
+        TCT_Unprotect();
+
+        /* Determine if a timer expiration needs to be finished.  Note
+           that the actual expiration processing is done with protection
+           disabled.  This prevents deadlock situations from arising.  */
+        if (!done)
+        {
+
+            /* Determine which type of timer has expired.  */
+            if (type == TM_APPL_TIMER)
+
+                /* Call application timer's expiration function.  */
+                (*(expiration_routine)) (id);
+            else
+
+                /* Call the task timeout function in the thread control
+                   function.  */
+                TCC_Task_Timeout((NU_TASK *) pointer);
+        }
+    } while (!done);
+
+    /* Protect the active list again.  */
+    TCT_System_Protect();
+
+    /* Clear the busy flag to indicate that list processing is complete. */
+    TMD_Active_List_Busy =  NU_FALSE;
+
+    /* Determine if a new timer should be enabled.  */
+    if (TMD_Active_Timers_List)
+    {
+
+        /* Yes, a new timer should be activated.  */
+
+        /* Pickup the new timer expiration value.  */
+        TMD_Timer_Start =  TMD_Active_Timers_List -> tm_remaining_time;
+
+        /* Start the new timer.  */
+        TMT_Enable_Timer(TMD_Timer_Start);
+    }
+
+    /* Release protection of the active timer list.  */
+    TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+}
+
+
+
+
+