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

Generated by: LCOV version 1.14