GCC Code Coverage Report


Directory: ./
File: Svc/LinuxTimer/LinuxTimerFd.cpp
Date: 2026-09-03 21:13:48
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
21 namespace Svc {
22
23 1 void LinuxTimer::startTimer(const Fw::TimeInterval& interval) {
24 int fd;
25 1 struct itimerspec itval;
26
27 /* Create the timer */
28 1 fd = timerfd_create(CLOCK_MONOTONIC, 0);
29
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (fd == -1) {
30 Fw::Logger::log("timer create error: %s\n", strerror(errno));
31 return;
32 }
33
1/1
✓ Branch 4 taken 1 times.
1 time_t seconds_value = static_cast<time_t>(interval.getSeconds());
34 // Ensure an overflow did not occur
35 1 FW_ASSERT(seconds_value == interval.getSeconds());
36 1 itval.it_interval.tv_sec = static_cast<time_t>(seconds_value);
37
1/1
✓ Branch 4 taken 1 times.
1 itval.it_interval.tv_nsec = static_cast<long>(interval.getUSeconds() * 1000);
38 1 itval.it_value.tv_sec = static_cast<time_t>(seconds_value);
39
1/1
✓ Branch 4 taken 1 times.
1 itval.it_value.tv_nsec = static_cast<long>(interval.getUSeconds() * 1000);
40
41 1 const int settimeStatus = timerfd_settime(fd, 0, &itval, nullptr);
42
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (settimeStatus == -1) {
43 Fw::Logger::log("timer settime error: %s\n", strerror(errno));
44 }
45
46 while (true) {
47 6 unsigned long long missed;
48
1/1
✓ Branch 1 taken 6 times.
6 int ret = static_cast<int>(read(fd, &missed, sizeof(missed)));
49
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)) {
50 // A non-interrupt read error will not clear itself; stop rather than spin on it
51 Fw::Logger::log("timer read error: %s\n", strerror(errno));
52 (void)::close(fd);
53 return;
54 }
55
1/1
✓ Branch 6 taken 6 times.
6 this->m_mutex.lock();
56
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 bool quit = this->m_quit;
57
1/1
✓ Branch 6 taken 6 times.
6 this->m_mutex.unLock();
58
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (quit) {
59 1 itval.it_interval.tv_sec = 0;
60 1 itval.it_interval.tv_nsec = 0;
61 1 itval.it_value.tv_sec = 0;
62 1 itval.it_value.tv_nsec = 0;
63
64 1 (void)timerfd_settime(fd, 0, &itval, nullptr); // best-effort disarm on shutdown
65
1/1
✓ Branch 1 taken 1 times.
1 (void)::close(fd);
66 1 return;
67 }
68
1/1
✓ Branch 6 taken 5 times.
5 Os::RawTime::Status rawTimeStatus = this->m_rawTime.now();
69
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) {
70 // Latch the report so a persistent failure does not flood the console at the timer rate
71 this->m_rawTimeErrorLogged = true;
72 Fw::Logger::log("timer raw time error: %d\n", static_cast<I32>(rawTimeStatus));
73 }
74
1/1
✓ Branch 8 taken 5 times.
5 this->CycleOut_out(0, this->m_rawTime);
75 5 }
76 }
77
78 } // end namespace Svc
79