GCC Code Coverage Report


Directory: Utils/
File: RateLimiter.cpp
Date: 2026-09-23 21:15:08
Exec Total Coverage
Lines: 72 73 98.6%
Functions: 15 15 100.0%
Branches: 49 56 87.5%

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 19 RateLimiter ::RateLimiter(U32 counterCycle, U32 timeCycle) : m_counterCycle(counterCycle), m_timeCycle(timeCycle) {
17
1/1
✓ Branch 2 taken 19 times.
19 this->reset();
18 19 }
19
20 2 RateLimiter ::RateLimiter() : m_counterCycle(0), m_timeCycle(0) {
21
1/1
✓ Branch 2 taken 2 times.
2 this->reset();
22 2 }
23
24 1 void RateLimiter ::setCounterCycle(U32 counterCycle) {
25 1 this->m_counterCycle = counterCycle;
26 1 }
27
28 1 void RateLimiter ::setTimeCycle(U32 timeCycle) {
29 1 this->m_timeCycle = timeCycle;
30 1 }
31
32 48 void RateLimiter ::reset() {
33 48 this->resetCounter();
34 48 this->resetTime();
35 48 }
36
37 48 void RateLimiter ::resetCounter() {
38 48 this->m_counter = 0;
39 48 }
40
41 48 void RateLimiter ::resetTime() {
42
2/2
✓ Branch 2 taken 48 times.
✓ Branch 11 taken 48 times.
48 this->m_time = Fw::Time();
43 48 this->m_timeAtNegativeInfinity = true;
44 48 }
45
46 3 void RateLimiter ::setCounter(U32 counter) {
47 3 this->m_counter = counter;
48 3 }
49
50 5 void RateLimiter ::setTime(Fw::Time time) {
51 5 this->m_time = time;
52 5 this->m_timeAtNegativeInfinity = false;
53 5 }
54
55 1340151 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
4/4
✓ Branch 1 taken 410030 times.
✓ Branch 2 taken 930121 times.
✓ Branch 5 taken 110012 times.
✓ Branch 6 taken 300018 times.
1340151 if (this->m_counterCycle == 0 && this->m_timeCycle == 0) {
67 110012 return true;
68 }
69
70 // evaluate trigger criteria
71 1230139 bool shouldTrigger = false;
72
2/2
✓ Branch 1 taken 930121 times.
✓ Branch 2 taken 300018 times.
1230139 if (this->m_counterCycle > 0) {
73
3/4
✓ Branch 0 taken 930121 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 10310 times.
✓ Branch 5 taken 919811 times.
930121 shouldTrigger = shouldTrigger || this->shouldCounterTrigger();
74 }
75
2/2
✓ Branch 2 taken 1200033 times.
✓ Branch 3 taken 30106 times.
1230139 if (this->m_timeCycle > 0) {
76
10/14
✓ Branch 0 taken 1191964 times.
✓ Branch 1 taken 8069 times.
✓ Branch 5 taken 1191964 times.
✓ Branch 8 taken 1191964 times.
✓ Branch 10 taken 11824 times.
✓ Branch 11 taken 1180140 times.
✓ Branch 12 taken 1191964 times.
✓ Branch 13 taken 8069 times.
✓ Branch 16 taken 1191964 times.
✓ Branch 17 taken 8069 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
1200033 shouldTrigger = shouldTrigger || this->shouldTimeTrigger(time);
77 }
78
79 // update states
80
2/2
✓ Branch 1 taken 930121 times.
✓ Branch 2 taken 300018 times.
1230139 if (this->m_counterCycle > 0) {
81 930121 this->updateCounter(shouldTrigger);
82 }
83
2/2
✓ Branch 2 taken 1200033 times.
✓ Branch 3 taken 30106 times.
1230139 if (this->m_timeCycle > 0) {
84
2/2
✓ Branch 3 taken 1200033 times.
✓ Branch 6 taken 1200033 times.
1200033 this->updateTime(shouldTrigger, time);
85 }
86
87 1230139 return shouldTrigger;
88 }
89
90 40117 bool RateLimiter ::trigger() {
91 40117 FW_ASSERT(this->m_timeCycle == 0);
92
3/3
✓ Branch 4 taken 40117 times.
✓ Branch 7 taken 40117 times.
✓ Branch 10 taken 40117 times.
40117 return trigger(Fw::Time::zero());
93 }
94
95 930121 bool RateLimiter ::shouldCounterTrigger() {
96 930121 FW_ASSERT(this->m_counterCycle > 0);
97
98 // trigger at 0
99 930121 bool shouldTrigger = (this->m_counter == 0);
100
101 930121 return shouldTrigger;
102 }
103
104 1191964 bool RateLimiter ::shouldTimeTrigger(Fw::Time time) {
105 1191964 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
1/1
✓ Branch 5 taken 1191964 times.
1191964 Fw::Time nextTrigger = this->m_time;
110
1/1
✓ Branch 4 taken 1191964 times.
1191964 nextTrigger.add(this->m_timeCycle, 0);
111
6/7
✓ Branch 3 taken 1191964 times.
✓ Branch 5 taken 1180148 times.
✓ Branch 6 taken 11816 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1180148 times.
✓ Branch 10 taken 8 times.
✓ Branch 11 taken 1180140 times.
1191964 bool shouldTrigger = (time >= nextTrigger) || this->m_timeAtNegativeInfinity;
112
113 1191964 return shouldTrigger;
114 1191964 }
115
116 930121 void RateLimiter ::updateCounter(bool triggered) {
117 930121 FW_ASSERT(this->m_counterCycle > 0);
118
119
2/2
✓ Branch 0 taken 15649 times.
✓ Branch 1 taken 914472 times.
930121 if (triggered) {
120 // triggered, set to next state and maybe wrap (handles counterCycle == 1)
121 15649 this->m_counter = 1;
122
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 15649 times.
15649 if (this->m_counter >= this->m_counterCycle) {
123 ✗ this->m_counter = 0;
124 }
125
126 } else {
127 // otherwise, just increment and maybe wrap
128 914472 this->m_counter++;
129
2/2
✓ Branch 3 taken 10287 times.
✓ Branch 4 taken 904185 times.
914472 if (this->m_counter >= this->m_counterCycle) {
130 10287 this->m_counter = 0;
131 }
132 }
133 930121 }
134
135 1200033 void RateLimiter ::updateTime(bool triggered, Fw::Time time) {
136 1200033 FW_ASSERT(this->m_timeCycle > 0);
137
138
2/2
✓ Branch 0 taken 19893 times.
✓ Branch 1 taken 1180140 times.
1200033 if (triggered) {
139 // mark time of trigger
140 19893 this->m_time = time;
141 }
142 1200033 this->m_timeAtNegativeInfinity = false;
143 1200033 }
144
145 } // end namespace Utils
146