GCC Code Coverage Report


Directory: Svc/LinuxTimer/
File: LinuxTimerFd.cpp
Date: 2026-11-03 21:19:10
Exec Total Coverage
Lines: 30 38 78.9%
Functions: 1 1 100.0%
Branches: 16 32 50.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title LinuxTimerImpl.cpp
3 // \author tim
4 // \brief cpp file for LinuxTimer component implementation class
5 //
6 // \copyright
7 // Copyright 2009-2015, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12
13 #include <sys/timerfd.h>
14 #include <unistd.h>
15 #include <Fw/FPrimeBasicTypes.hpp>
16 #include <Fw/Logger/Logger.hpp>
17 #include <Svc/LinuxTimer/LinuxTimer.hpp>
18 #include <cerrno>
19 #include <cstring>
20 #include <limits>
21
22 namespace Svc {
23
24 1 void LinuxTimer::startTimer(const Fw::TimeInterval& interval) {
25 int fd;
26 1 struct itimerspec itval;
27
28 /* Create the timer */
29 1 fd = timerfd_create(CLOCK_MONOTONIC, 0);
30
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (fd == -1) {
31 ✗ Fw::Logger::log("timer create error: %s\n", strerror(errno));
32 ✗ return;
33 }
34 // Ensure the interval fits in time_t before narrowing: on 32-bit targets time_t cannot
35 // represent every U32, and converting an out-of-range value is implementation-defined.
36 1 FW_ASSERT(interval.getSeconds() <= static_cast<U32>(std::numeric_limits<time_t>::max()));
37
1/1
✓ Branch 4 taken 1 times.
1 time_t seconds_value = static_cast<time_t>(interval.getSeconds());
38 1 itval.it_interval.tv_sec = static_cast<time_t>(seconds_value);
39
1/1
✓ Branch 4 taken 1 times.
1 itval.it_interval.tv_nsec = static_cast<long>(interval.getUSeconds() * 1000);
40 1 itval.it_value.tv_sec = static_cast<time_t>(seconds_value);
41
1/1
✓ Branch 4 taken 1 times.
1 itval.it_value.tv_nsec = static_cast<long>(interval.getUSeconds() * 1000);
42
43 1 const int settimeStatus = timerfd_settime(fd, 0, &itval, nullptr);
44
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (settimeStatus == -1) {
45 ✗ Fw::Logger::log("timer settime error: %s\n", strerror(errno));
46 }
47
48 while (true) {
49 6 unsigned long long missed;
50
1/1
✓ Branch 1 taken 6 times.
6 int ret = static_cast<int>(read(fd, &missed, sizeof(missed)));
51
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 if ((-1 == ret) && (errno != EINTR)) {
52 // A non-interrupt read error will not clear itself; stop rather than spin on it
53 ✗ Fw::Logger::log("timer read error: %s\n", strerror(errno));
54 ✗ (void)::close(fd);
55 ✗ return;
56 }
57
1/1
✓ Branch 6 taken 6 times.
6 this->m_mutex.lock();
58
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 bool quit = this->m_quit;
59
1/1
✓ Branch 6 taken 6 times.
6 this->m_mutex.unLock();
60
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (quit) {
61 1 itval.it_interval.tv_sec = 0;
62 1 itval.it_interval.tv_nsec = 0;
63 1 itval.it_value.tv_sec = 0;
64 1 itval.it_value.tv_nsec = 0;
65
66 1 (void)timerfd_settime(fd, 0, &itval, nullptr); // best-effort disarm on shutdown
67
1/1
✓ Branch 1 taken 1 times.
1 (void)::close(fd);
68 1 return;
69 }
70
1/1
✓ Branch 6 taken 5 times.
5 Os::RawTime::Status rawTimeStatus = this->m_rawTime.now();
71
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
5 if ((rawTimeStatus != Os::RawTime::Status::OP_OK) && !this->m_rawTimeErrorLogged) {
72 // Latch the report so a persistent failure does not flood the console at the timer rate
73 ✗ this->m_rawTimeErrorLogged = true;
74 ✗ Fw::Logger::log("timer raw time error: %d\n", static_cast<I32>(rawTimeStatus));
75 }
76
1/1
✓ Branch 8 taken 5 times.
5 this->CycleOut_out(0, this->m_rawTime);
77 5 }
78 }
79
80 } // end namespace Svc
81