[PDK-6649] OSAL: nonos: Fix TimerP_delete to update gTimerAnyMask
authorDon Dominic <a0486429@ti.com>
Tue, 16 Mar 2021 10:31:07 +0000 (16:01 +0530)
committerSujith Shivalingappa <sujith.s@ti.com>
Tue, 16 Mar 2021 12:13:13 +0000 (07:13 -0500)
- TimerP_delete was not resetting the the timer's bit field in the gTimerAnyMask
  - Hence the mask was getting exhausted after log2(TIMERP_AVAILABLE_MASK+1) no.of TimerP_create
  - This resulted in TimerP_create failures even when there are unused timers
- Update the timer's bit field in the mask while deleting the timer to resolve this
- For v0/v1, Global Timer Structure's used flag was cleared only when Timer ISR is non-NULL
  - Fixed this to clear irrespective of Timer ISR

- Also updated the UT with a test to catch this failure
 - This tests TimerP_create and TimerP_delete repeatedly for more no.of times than that in the mask,
   to make sure freeing up of resources was successful
 - The test which was failing earlier, now works fine with the updates in source

Signed-off-by: Don Dominic <a0486429@ti.com>
packages/ti/osal/src/nonos/timer/v0/TimerP_nonos.c
packages/ti/osal/src/nonos/timer/v1/TimerP_nonos.c
packages/ti/osal/src/nonos/timer/v2/TimerP_nonos.c
packages/ti/osal/test/src/main_osal_test.c

index 298f81767a6cac322e7ef8bd7986ab38cba1a89c..853439417dbdcfca6acd1ef9df92406ab08e9bc5 100644 (file)
@@ -543,6 +543,7 @@ TimerP_Status TimerP_delete(TimerP_Handle handle)
 {
       /* Release or free the memory */
       uint32_t key;
 {
       /* Release or free the memory */
       uint32_t key;
+      uint32_t id;
       TimerP_Status ret = TimerP_OK;
       int index = ((uint32_t) handle - (uint32_t) gTimerStructs); /* struct subtraction */
       TimerP_Struct *timer = (TimerP_Struct *) handle;
       TimerP_Status ret = TimerP_OK;
       int index = ((uint32_t) handle - (uint32_t) gTimerStructs); /* struct subtraction */
       TimerP_Struct *timer = (TimerP_Struct *) handle;
@@ -555,7 +556,18 @@ TimerP_Status TimerP_delete(TimerP_Handle handle)
         /* clear the ISR that was set before */
         if(timer->hwi != NULL_PTR) {
           HwiP_delete(timer->hwi);
         /* clear the ISR that was set before */
         if(timer->hwi != NULL_PTR) {
           HwiP_delete(timer->hwi);
-          gTimerStructs[index].used  = false;
+        }
+        /* reset the timer's bit field in the mask and clear the used flag */
+        gTimerStructs[index].used = (bool)false;
+        id = gTimerStructs[index].timerId;
+        uint32_t shift = ((uint32_t) 1u) << id;
+        if(((gTimerAnyMask & shift)) == 0U)
+        {
+          gTimerAnyMask |= shift;
+        }
+        else
+        {
+          ret = TimerP_FAILURE;        
         }
       }
       else
         }
       }
       else
index db8d39ca8a72489a9227cea23a8d2fac188918f7..d9c5b83145a70a20271cab1891be5609a6a40493 100755 (executable)
@@ -734,6 +734,7 @@ TimerP_Status TimerP_delete(TimerP_Handle handle)
 {
     /* Release or free the memory */
     uint32_t key;
 {
     /* Release or free the memory */
     uint32_t key;
+    uint32_t id;
     uint32_t index = (uint32_t)(( ((uintptr_t) handle) - ((uintptr_t) gTimerStructs) )/sizeof(TimerP_Struct)); /* struct subtraction */
     TimerP_Status ret = TimerP_OK;
     TimerP_Struct *timer = (TimerP_Struct *) handle;
     uint32_t index = (uint32_t)(( ((uintptr_t) handle) - ((uintptr_t) gTimerStructs) )/sizeof(TimerP_Struct)); /* struct subtraction */
     TimerP_Status ret = TimerP_OK;
     TimerP_Struct *timer = (TimerP_Struct *) handle;
@@ -744,9 +745,22 @@ TimerP_Status TimerP_delete(TimerP_Handle handle)
     if((timer != NULL_PTR) && ((gTimerStructs[index].used) == (bool)true))
     {
       /* clear the ISR that was set before */
     if((timer != NULL_PTR) && ((gTimerStructs[index].used) == (bool)true))
     {
       /* clear the ISR that was set before */
-      if(timer->hwi != NULL_PTR) {
+      if(timer->hwi != NULL_PTR) 
+      {
         (void)HwiP_delete(timer->hwi);
         (void)HwiP_delete(timer->hwi);
-        gTimerStructs[index].used = (bool)false;
+      }
+      
+      /* reset the timer's bit field in the mask and clear the used flag */
+      gTimerStructs[index].used = (bool)false;
+      id = gTimerStructs[index].timerId;
+      uint32_t shift = ((uint32_t) 1u) << id;
+      if(((gTimerAnyMask & shift)) == 0U)
+      {
+        gTimerAnyMask |= shift;
+      }
+      else
+      {
+        ret = TimerP_FAILURE;  
       }
 
       /* Found the osal timer object to delete */
       }
 
       /* Found the osal timer object to delete */
@@ -754,7 +768,6 @@ TimerP_Status TimerP_delete(TimerP_Handle handle)
       {
         gOsalTimerAllocCnt--;
       }
       {
         gOsalTimerAllocCnt--;
       }
-      ret = TimerP_OK; 
     } 
     else
     {
     } 
     else
     {
index 5b4615be983fad5d3b0c8e675a8e6ffa4aee2b18..748aa86940269b88844b4398050394203aedf5b0 100644 (file)
@@ -155,10 +155,10 @@ static void  TimerP_rtiTimerInitDevice(const TimerP_Struct *timer, uint32_t base
     (void)RTITmrClear(baseAddr, RTI_TMR_CNT_BLK_INDEX_0, RTI_TMR_CMP_BLK_INDEX_0);
   }
 
     (void)RTITmrClear(baseAddr, RTI_TMR_CNT_BLK_INDEX_0, RTI_TMR_CMP_BLK_INDEX_0);
   }
 
-  if (timer->hwi != NULL_PTR) {\r
-    /* clear any previously latched timer interrupts */\r
-    Osal_ClearInterrupt(timer->eventId, timer->intNum);\r
-    Osal_DisableInterrupt(timer->eventId, timer->intNum);\r
+  if (timer->hwi != NULL_PTR) {
+    /* clear any previously latched timer interrupts */
+    Osal_ClearInterrupt(timer->eventId, timer->intNum);
+    Osal_DisableInterrupt(timer->eventId, timer->intNum);
   }
 
   HwiP_restore(key);
   }
 
   HwiP_restore(key);
@@ -573,6 +573,7 @@ TimerP_Status TimerP_delete(TimerP_Handle handle)
 {
   /* Release or free the memory */
   uint32_t key;
 {
   /* Release or free the memory */
   uint32_t key;
+  uint32_t id;
   uint32_t index = (uint32_t)(( ((uintptr_t) handle) - ((uintptr_t) gTimerStructs) )/sizeof(TimerP_Struct)); /* struct subtraction */
   TimerP_Status ret = TimerP_OK;
   TimerP_Struct *timer = (TimerP_Struct *) handle;
   uint32_t index = (uint32_t)(( ((uintptr_t) handle) - ((uintptr_t) gTimerStructs) )/sizeof(TimerP_Struct)); /* struct subtraction */
   TimerP_Status ret = TimerP_OK;
   TimerP_Struct *timer = (TimerP_Struct *) handle;
@@ -587,13 +588,23 @@ TimerP_Status TimerP_delete(TimerP_Handle handle)
       (void)HwiP_delete(timer->hwi);
     }
 
       (void)HwiP_delete(timer->hwi);
     }
 
+    /* reset the timer's bit field in the mask and clear the used flag */
     gTimerStructs[index].used = (bool)false;
     gTimerStructs[index].used = (bool)false;
+    id = gTimerStructs[index].timerId;
+    uint32_t shift = ((uint32_t) 1u) << id;
+    if(((gTimerAnyMask & shift)) == 0U)
+    {
+      gTimerAnyMask |= shift;
+    }
+    else
+    {
+      ret = TimerP_FAILURE;    
+    }
     /* Found the osal timer object to delete */
     if (gOsalTimerAllocCnt > 0U)
     {
       gOsalTimerAllocCnt--;
     }
     /* Found the osal timer object to delete */
     if (gOsalTimerAllocCnt > 0U)
     {
       gOsalTimerAllocCnt--;
     }
-    ret = TimerP_OK;
   }
   else
   {
   }
   else
   {
index 878caf895f07d9d4365c85952b1e5aad9dd2bd15..23b4126bd5f509e0404fc9cd8d5df3f72998a550 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
 
 #include <stdio.h>
 #include <string.h>
+#include <math.h>
 
 /* TI-RTOS Header files */
 #include <ti/osal/osal.h>
 
 /* TI-RTOS Header files */
 #include <ti/osal/osal.h>
+#include <ti/osal/soc/osal_soc.h>
 #include "OSAL_log.h"
 
 #include "OSAL_board.h"
 #include "OSAL_log.h"
 
 #include "OSAL_board.h"
@@ -771,6 +773,27 @@ bool OSAL_timer_test()
         ret = false;
       }
     }
         ret = false;
       }
     }
+
+    for (i = 0; i < (log2(TIMERP_AVAILABLE_MASK+1U)+1U); i++)
+    {
+        TimerP_Params_init(&timerParams);
+        timerParams.runMode    = TimerP_RunMode_CONTINUOUS;
+        timerParams.startMode  = TimerP_StartMode_USER;
+        timerParams.periodType = TimerP_PeriodType_MICROSECS;
+        timerParams.period     = OSAL_TEST_TIMER_PERIOD;
+        handle = TimerP_create(TimerP_ANY, NULL, &timerParams);
+        /* don't expect the handle to be null */
+        if (handle == NULL_PTR)
+        {
+            OSAL_log("\n Error: Timer Create failed for %d th time \n", i);
+            ret = false;
+        }
+        if (TimerP_delete(handle) != TimerP_OK)
+        {
+            OSAL_log("\n Error: Timer Delete failed for %d th time \n", i);
+            ret = false;
+        }
+    }    
     return (ret);
 }
 
     return (ret);
 }