GCC Code Coverage Report


Directory: ./
File: RateLimiter.cpp
Date: 2026-09-23 22:13:33
Exec Total Coverage
Lines: 0 73 0.0%
Functions: 0 15 0.0%
Branches: 0 50 0.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title RateLimiter.cpp
3 // \author vwong
4 // \brief cpp file for a rate limiter utility class
5 //
6 // \copyright
7 // Copyright (C) 2009-2020 California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 // ======================================================================
11
12 #include <Utils/RateLimiter.hpp>
13
14 namespace Utils {
15
16 ✗ RateLimiter ::RateLimiter(U32 counterCycle, U32 timeCycle) : m_counterCycle(counterCycle), m_timeCycle(timeCycle) {
17 ✗ this->reset();
18 ✗ }
19
20 ✗ RateLimiter ::RateLimiter() : m_counterCycle(0), m_timeCycle(0) {
21 ✗ this->reset();
22 ✗ }
23
24 ✗ void RateLimiter ::setCounterCycle(U32 counterCycle) {
25 ✗ this->m_counterCycle = counterCycle;
26 ✗ }
27
28 ✗ void RateLimiter ::setTimeCycle(U32 timeCycle) {
29 ✗ this->m_timeCycle = timeCycle;
30 ✗ }
31
32 ✗ void RateLimiter ::reset() {
33 ✗ this->resetCounter();
34 ✗ this->resetTime();
35 ✗ }
36
37 ✗ void RateLimiter ::resetCounter() {
38 ✗ this->m_counter = 0;
39 ✗ }
40
41 ✗ void RateLimiter ::resetTime() {
42 ✗ this->m_time = Fw::Time();
43 ✗ this->m_timeAtNegativeInfinity = true;
44 ✗ }
45
46 ✗ void RateLimiter ::setCounter(U32 counter) {
47 ✗ this->m_counter = counter;
48 ✗ }
49
50 ✗ void RateLimiter ::setTime(Fw::Time time) {
51 ✗ this->m_time = time;
52 ✗ this->m_timeAtNegativeInfinity = false;
53 ✗ }
54
55 ✗ bool RateLimiter ::trigger(Fw::Time time) {
56 // NB: this implements a 4-bit decision, logically equivalent to this pseudo-code
57 //
58 // A = HAS_COUNTER, B = HAS_TIME, C = COUNTER_TRIGGER, D = TIME_TRIGGER
59 //
60 // if (!A && !B) => true
61 // if (A && B) => C || D
62 // if (A) => C
63 // if (B) => D
64 // false
65 //
66 ✗ if (this->m_counterCycle == 0 && this->m_timeCycle == 0) {
67 ✗ return true;
68 }
69
70 // evaluate trigger criteria
71 ✗ bool shouldTrigger = false;
72 ✗ if (this->m_counterCycle > 0) {
73 ✗ shouldTrigger = shouldTrigger || this->shouldCounterTrigger();
74 }
75 ✗ if (this->m_timeCycle > 0) {
76 ✗ shouldTrigger = shouldTrigger || this->shouldTimeTrigger(time);
77 }
78
79 // update states
80 ✗ if (this->m_counterCycle > 0) {
81 ✗ this->updateCounter(shouldTrigger);
82 }
83 ✗ if (this->m_timeCycle > 0) {
84 ✗ this->updateTime(shouldTrigger, time);
85 }
86
87 ✗ return shouldTrigger;
88 }
89
90 ✗ bool RateLimiter ::trigger() {
91 ✗ FW_ASSERT(this->m_timeCycle == 0);
92 ✗ return trigger(Fw::Time::zero());
93 }
94
95 ✗ bool RateLimiter ::shouldCounterTrigger() {
96 ✗ FW_ASSERT(this->m_counterCycle > 0);
97
98 // trigger at 0
99 ✗ bool shouldTrigger = (this->m_counter == 0);
100
101 ✗ return shouldTrigger;
102 }
103
104 ✗ bool RateLimiter ::shouldTimeTrigger(Fw::Time time) {
105 ✗ FW_ASSERT(this->m_timeCycle > 0);
106
107 // trigger at prev trigger time + time cycle seconds OR when time is at negative infinity
108 // Member add keeps the time base/context of m_time so it stays comparable with time
109 ✗ Fw::Time nextTrigger = this->m_time;
110 ✗ nextTrigger.add(this->m_timeCycle, 0);
111 ✗ bool shouldTrigger = (time >= nextTrigger) || this->m_timeAtNegativeInfinity;
112
113 ✗ return shouldTrigger;
114 ✗ }
115
116 ✗ void RateLimiter ::updateCounter(bool triggered) {
117 ✗ FW_ASSERT(this->m_counterCycle > 0);
118
119 ✗ if (triggered) {
120 // triggered, set to next state and maybe wrap (handles counterCycle == 1)
121 ✗ this->m_counter = 1;
122 ✗ if (this->m_counter >= this->m_counterCycle) {
123 ✗ this->m_counter = 0;
124 }
125
126 } else {
127 // otherwise, just increment and maybe wrap
128 ✗ this->m_counter++;
129 ✗ if (this->m_counter >= this->m_counterCycle) {
130 ✗ this->m_counter = 0;
131 }
132 }
133 ✗ }
134
135 ✗ void RateLimiter ::updateTime(bool triggered, Fw::Time time) {
136 ✗ FW_ASSERT(this->m_timeCycle > 0);
137
138 ✗ if (triggered) {
139 // mark time of trigger
140 ✗ this->m_time = time;
141 }
142 ✗ this->m_timeAtNegativeInfinity = false;
143 ✗ }
144
145 } // end namespace Utils
146