GCC Code Coverage Report


Directory: ./
File: Utils/RateLimiter.cpp
Date: 2026-09-03 21:13:48
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 17 RateLimiter ::RateLimiter(U32 counterCycle, U32 timeCycle) : m_counterCycle(counterCycle), m_timeCycle(timeCycle) {
17
1/1
✓ Branch 2 taken 17 times.
17 this->reset();
18 17 }
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 45 void RateLimiter ::reset() {
33 45 this->resetCounter();
34 45 this->resetTime();
35 45 }
36
37 45 void RateLimiter ::resetCounter() {
38 45 this->m_counter = 0;
39 45 }
40
41 45 void RateLimiter ::resetTime() {
42
2/2
✓ Branch 2 taken 45 times.
✓ Branch 11 taken 45 times.
45 this->m_time = Fw::Time();
43 45 this->m_timeAtNegativeInfinity = true;
44 45 }
45
46 3 void RateLimiter ::setCounter(U32 counter) {
47 3 this->m_counter = counter;
48 3 }
49
50 4 void RateLimiter ::setTime(Fw::Time time) {
51 4 this->m_time = time;
52 4 this->m_timeAtNegativeInfinity = false;
53 4 }
54
55 1340138 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 410023 times.
✓ Branch 2 taken 930115 times.
✓ Branch 5 taken 110012 times.
✓ Branch 6 taken 300011 times.
1340138 if (this->m_counterCycle == 0 && this->m_timeCycle == 0) {
67 110012 return true;
68 }
69
70 // evaluate trigger criteria
71 1230126 bool shouldTrigger = false;
72
2/2
✓ Branch 1 taken 930115 times.
✓ Branch 2 taken 300011 times.
1230126 if (this->m_counterCycle > 0) {
73
3/4
✓ Branch 0 taken 930115 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 10308 times.
✓ Branch 5 taken 919807 times.
930115 shouldTrigger = shouldTrigger || this->shouldCounterTrigger();
74 }
75
2/2
✓ Branch 2 taken 1200020 times.
✓ Branch 3 taken 30106 times.
1230126 if (this->m_timeCycle > 0) {
76
10/14
✓ Branch 0 taken 1191953 times.
✓ Branch 1 taken 8067 times.
✓ Branch 5 taken 1191953 times.
✓ Branch 8 taken 1191953 times.
✓ Branch 10 taken 11819 times.
✓ Branch 11 taken 1180134 times.
✓ Branch 12 taken 1191953 times.
✓ Branch 13 taken 8067 times.
✓ Branch 16 taken 1191953 times.
✓ Branch 17 taken 8067 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
1200020 shouldTrigger = shouldTrigger || this->shouldTimeTrigger(time);
77 }
78
79 // update states
80
2/2
✓ Branch 1 taken 930115 times.
✓ Branch 2 taken 300011 times.
1230126 if (this->m_counterCycle > 0) {
81 930115 this->updateCounter(shouldTrigger);
82 }
83
2/2
✓ Branch 2 taken 1200020 times.
✓ Branch 3 taken 30106 times.
1230126 if (this->m_timeCycle > 0) {
84
2/2
✓ Branch 3 taken 1200020 times.
✓ Branch 6 taken 1200020 times.
1200020 this->updateTime(shouldTrigger, time);
85 }
86
87 1230126 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 930115 bool RateLimiter ::shouldCounterTrigger() {
96 930115 FW_ASSERT(this->m_counterCycle > 0);
97
98 // trigger at 0
99 930115 bool shouldTrigger = (this->m_counter == 0);
100
101 930115 return shouldTrigger;
102 }
103
104 1191953 bool RateLimiter ::shouldTimeTrigger(Fw::Time time) {
105 1191953 FW_ASSERT(this->m_timeCycle > 0);
106
107 // trigger at prev trigger time + time cycle seconds OR when time is at negative infinity
108
1/1
✓ Branch 4 taken 1191953 times.
1191953 Fw::Time timeCycle = Fw::Time(this->m_timeCycle, 0);
109
1/1
✓ Branch 5 taken 1191953 times.
1191953 Fw::Time nextTrigger = Fw::Time::add(this->m_time, timeCycle);
110
6/7
✓ Branch 3 taken 1191953 times.
✓ Branch 5 taken 1180141 times.
✓ Branch 6 taken 11812 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1180141 times.
✓ Branch 10 taken 7 times.
✓ Branch 11 taken 1180134 times.
1191953 bool shouldTrigger = (time >= nextTrigger) || this->m_timeAtNegativeInfinity;
111
112 1191953 return shouldTrigger;
113 1191953 }
114
115 930115 void RateLimiter ::updateCounter(bool triggered) {
116 930115 FW_ASSERT(this->m_counterCycle > 0);
117
118
2/2
✓ Branch 0 taken 15646 times.
✓ Branch 1 taken 914469 times.
930115 if (triggered) {
119 // triggered, set to next state and maybe wrap (handles counterCycle == 1)
120 15646 this->m_counter = 1;
121
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 15646 times.
15646 if (this->m_counter >= this->m_counterCycle) {
122 this->m_counter = 0;
123 }
124
125 } else {
126 // otherwise, just increment and maybe wrap
127 914469 this->m_counter++;
128
2/2
✓ Branch 3 taken 10286 times.
✓ Branch 4 taken 904183 times.
914469 if (this->m_counter >= this->m_counterCycle) {
129 10286 this->m_counter = 0;
130 }
131 }
132 930115 }
133
134 1200020 void RateLimiter ::updateTime(bool triggered, Fw::Time time) {
135 1200020 FW_ASSERT(this->m_timeCycle > 0);
136
137
2/2
✓ Branch 0 taken 19886 times.
✓ Branch 1 taken 1180134 times.
1200020 if (triggered) {
138 // mark time of trigger
139 19886 this->m_time = time;
140 }
141 1200020 this->m_timeAtNegativeInfinity = false;
142 1200020 }
143
144 } // end namespace Utils
145