LCOV - code coverage report
Current view: top level - vnsw/agent/services/multicast/agent_map - task_timer_api.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 75 94 79.8 %
Date: 2026-08-03 02:19:58 Functions: 10 13 76.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <string>
       6             : #include "base/timer.h"
       7             : 
       8             : #include "task_map.h"
       9             : #include "task_timer_map.h"
      10             : 
      11             : #ifdef __cplusplus
      12             : extern "C" {
      13             : #endif
      14             : #include "task_timer_api.h"
      15             : #ifdef __cplusplus
      16             : }
      17             : #endif
      18             : 
      19             : extern bool task_timer_callback(void *agent_timer_map);
      20             : extern bool task_timer_cleanup(void *data);
      21             : 
      22           1 : void task_timer_init(task *tp)
      23             : {
      24           1 :     tp->cleanup_timer = NULL;
      25           1 :     thread_new_circular_thread(&tp->deleted_timers);
      26           1 : }
      27             : 
      28           1 : void task_timer_cleanup_deleted(task *tp)
      29             : {
      30           1 :     TaskMap *agent_task = (TaskMap *)tp->agent_task;
      31             : 
      32             :     Timer * cleanup_timer;
      33           1 :     cleanup_timer = TimerManager::CreateTimer(agent_task->io_,
      34             :                                     "Cleanup Timer",
      35             :                                     TaskScheduler::GetInstance()->
      36             :                                     GetTaskId(agent_task->name_),
      37             :                                     agent_task->instance_, true);
      38           1 :     tp->cleanup_timer = (void *)cleanup_timer;
      39           1 :     cleanup_timer->Start(0, boost::bind(task_timer_cleanup, tp));
      40           1 : }
      41             : 
      42           8 : task_timer *task_timer_create_idle_leaf(task *tp, const char *name,
      43             :                 flag_t flags, task_timer *parent,
      44             :                 timer_callback tjob, void *data)
      45             : {
      46           8 :     task_timer *timer = (task_timer *)malloc(sizeof(task_timer));
      47           8 :     if (!timer) {
      48           0 :         return NULL;
      49             :     }
      50             : 
      51           8 :     TaskMap *agent_task = (TaskMap *)tp->agent_task;
      52           8 :     TimerMap *timer_map = new TimerMap();
      53             : 
      54           8 :     timer_map->timer_name_ = name;
      55           8 :     timer_map->timer_ = timer;
      56           8 :     timer_map->agent_timer_ = TimerManager::CreateTimer(agent_task->io_,
      57           8 :                                     timer_map->timer_name_,
      58             :                                     TaskScheduler::GetInstance()->
      59             :                                     GetTaskId(agent_task->name_),
      60             :                                     agent_task->instance_, false);
      61             : 
      62           8 :     timer->tp = tp;
      63           8 :     timer->callback = tjob;
      64           8 :     timer->agent_timer_map = timer_map;
      65           8 :     timer->tdata = data;
      66             : 
      67           8 :     return timer;
      68             : }
      69             : 
      70           8 : void task_timer_delete(task_timer *timer)
      71             : {
      72           8 :     TimerMap *timer_map = (TimerMap *)timer->agent_timer_map;
      73             : 
      74           8 :     if (!TimerManager::DeleteTimer(timer_map->agent_timer_)) {
      75           1 :         thread_circular_add_top(&timer->tp->deleted_timers,
      76             :                                     &timer->deleted_entry);
      77           1 :         task_timer_cleanup_deleted(timer->tp);
      78           1 :         return;
      79             :     }
      80             : 
      81           7 :     delete timer_map;
      82             : 
      83           7 :     free(timer);
      84             : 
      85           7 :     return;
      86             : }
      87             : 
      88           0 : void task_timer_smear_auto_parent_timers(task_timer_root *root)
      89             : {
      90           0 :     return;
      91             : }
      92             : 
      93           4 : void task_timer_uset_alt_root_auto_parent_oneshot(task_timer_root *root,
      94             :                 task_timer *timer, utime_t *offset, u_int jitter)
      95             : {
      96           4 :     TimerMap *timer_map = (TimerMap *)timer->agent_timer_map;
      97             : 
      98           4 :     Timer *agent_timer = timer_map->agent_timer_;
      99             : 
     100           4 :     timer->timeout = offset->ut_sec*1000 + offset->ut_usec/1000;
     101             : 
     102           4 :     task_timer_reset(timer);
     103             :     // If running in the timer context, Agent Timer cannot be started
     104             :     // again. Will inform Agent Timer to restart based on the 'oneshot'
     105             :     // and 'rescheduled' flags in the function 'task_timer_callback'.
     106           4 :     if (agent_timer->fired()) {
     107           0 :         agent_timer->Reschedule(timer->timeout);
     108           0 :         timer->rescheduled = TRUE;
     109             :     } else {
     110           4 :         agent_timer->Start(timer->timeout,
     111             :                     boost::bind(task_timer_callback, timer_map));
     112             :     }
     113             : 
     114           4 :     timer->oneshot = TRUE;
     115             : 
     116           4 :     return;
     117             : }
     118             : 
     119           5 : void task_timer_reset(task_timer *timer)
     120             : {
     121           5 :     TimerMap *timer_map = (TimerMap *)timer->agent_timer_map;
     122           5 :     Timer *agent_timer = (Timer *)timer_map->agent_timer_;
     123             : 
     124           5 :     agent_timer->Cancel();
     125             : 
     126           5 :     return;
     127             : }
     128             : 
     129           4 : task_timer_root *task_timer_get_auto_parent_root(void)
     130             : {
     131           4 :     return NULL;
     132             : }
     133             : 
     134           1 : void *task_timer_data(task_timer *timer)
     135             : {
     136           1 :     return timer->tdata;
     137             : }
     138             : 
     139           0 : void task_timer_utime_left(task_timer *timer, utime_t *remaining)
     140             : {
     141           0 :     TimerMap *timer_map = (TimerMap *)timer->agent_timer_map;
     142           0 :     Timer *agent_timer = (Timer *)timer_map->agent_timer_;
     143             : 
     144           0 :     int elapsed = timer->timeout - agent_timer->GetElapsedTime();
     145             : 
     146           0 :     remaining->ut_usec = elapsed*1000;
     147           0 :     remaining->ut_sec = 0;
     148             : 
     149           0 :     return;
     150             : }
     151             : 
     152           0 : boolean task_timer_running(task_timer *timer)
     153             : {
     154           0 :     TimerMap *timer_map = (TimerMap *)timer->agent_timer_map;
     155           0 :     Timer *agent_timer = (Timer *)timer_map->agent_timer_;
     156             : 
     157           0 :     return agent_timer->running() ? TRUE : FALSE;
     158             : }
     159             : 
     160           1 : bool task_timer_callback(void *agent_timer_map)
     161             : {
     162           1 :     TimerMap *timer_map = (TimerMap *)agent_timer_map;
     163           1 :     task_timer *timer = (task_timer *)timer_map->timer_;
     164             : 
     165           1 :     timer->callback(timer, 0);
     166           1 :     bool reschedule = false;
     167           1 :     if (timer->rescheduled == TRUE) {
     168           0 :         reschedule = true;
     169           0 :         timer->rescheduled = FALSE;
     170             :     }
     171           1 :     if (!reschedule) {
     172           1 :         reschedule = (!timer->oneshot ? true : false);
     173             :     }
     174             : 
     175           1 :     return reschedule;
     176             : }
     177             : 
     178           1 : bool task_timer_cleanup(void *data)
     179             : {
     180           1 :     task *tp = (task *)data;
     181           1 :     task_timer *timer = NULL;
     182           1 :     task_thread *thread_ptr = NULL;
     183             : 
     184             :     while (TRUE) {
     185           2 :         thread_ptr = thread_circular_top(&tp->deleted_timers);
     186           2 :         if (!thread_ptr) break;
     187             : 
     188           1 :         timer = task_timer_list_entry(thread_ptr);
     189           1 :         thread_remove(thread_ptr);
     190           1 :         TimerMap *timer_map = (TimerMap *)timer->agent_timer_map;
     191           1 :         if (!TimerManager::DeleteTimer(timer_map->agent_timer_)) {
     192           0 :             assert(0);
     193             :         }
     194           1 :         delete timer_map;
     195             : 
     196           1 :         free(timer);
     197           1 :     }
     198             : 
     199           1 :     tp->cleanup_timer = NULL;
     200           1 :     return false;
     201             : }
     202             : 

Generated by: LCOV version 1.14