• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mcallegari / qlcplus / 11543761974

27 Oct 2024 09:00PM UTC coverage: 31.98% (-0.003%) from 31.983%
11543761974

push

github

mcallegari
qmlui: more unique naming handling

14032 of 43877 relevant lines covered (31.98%)

27056.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.68
/engine/src/mastertimer-unix.cpp
1
/*
2
  Q Light Controller Plus
3
  mastertimer-unix.cpp
4

5
  Copyright (C) Heikki Junnila
6
                Christopher Staite
7
                Massimo Callegari
8

9
  Licensed under the Apache License, Version 2.0 (the "License");
10
  you may not use this file except in compliance with the License.
11
  You may obtain a copy of the License at
12

13
      http://www.apache.org/licenses/LICENSE-2.0.txt
14

15
  Unless required by applicable law or agreed to in writing, software
16
  distributed under the License is distributed on an "AS IS" BASIS,
17
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
  See the License for the specific language governing permissions and
19
  limitations under the License.
20
*/
21

22
#include <sys/time.h>
23
#include <stdlib.h>
24
#include <unistd.h>
25
#include <stdio.h>
26
#include <fcntl.h>
27
#include <errno.h>
28

29
#include <QDebug>
30

31
#include "mastertimer-unix.h"
32
#include "mastertimer.h"
33

34
/****************************************************************************
35
 * MasterTimerPrivate
36
 ****************************************************************************/
37

38
MasterTimerPrivate::MasterTimerPrivate(MasterTimer* masterTimer)
210✔
39
    : QThread(masterTimer)
40
    , m_run(false)
210✔
41
{
42
    Q_ASSERT(masterTimer != NULL);
43
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
44
    host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
45
#endif
46
}
210✔
47

48
MasterTimerPrivate::~MasterTimerPrivate()
420✔
49
{
50
    stop();
210✔
51
}
420✔
52

53
void MasterTimerPrivate::stop()
215✔
54
{
55
    m_run = false;
215✔
56
    wait();
215✔
57
}
215✔
58

59
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
60
int MasterTimerPrivate::compareTime(mach_timespec_t *time1, mach_timespec_t *time2)
61
#else
62
int MasterTimerPrivate::compareTime(struct timespec *time1, struct timespec *time2)
168✔
63
#endif
64
{
65
    if (time1->tv_sec < time2->tv_sec)
168✔
66
    {
67
        qDebug() << "Time is late by" << (time2->tv_sec - time1->tv_sec) << "seconds";
68
        return -1;
69
    }
70
    else if (time1->tv_sec > time2->tv_sec)
168✔
71
        return 1;
72
    else if (time1->tv_nsec < time2->tv_nsec)
168✔
73
    {
74
        qDebug() << "Time is late by" << (time2->tv_nsec - time1->tv_nsec) << "nanoseconds";
75
        return -1;
76
    }
77
    else if (time1->tv_nsec > time2->tv_nsec)
168✔
78
        return 1;
79
    else
80
        return 0;
×
81
}
82

83
void MasterTimerPrivate::run()
5✔
84
{
85
    /* Don't start another thread */
86
    if (m_run == true)
5✔
87
        return;
88

89
    MasterTimer* mt = qobject_cast <MasterTimer*> (parent());
90
    Q_ASSERT(mt != NULL);
91

92
    /* How long to wait each loop, in nanoseconds */
93
    int nsTickTime = 1000000000L / mt->frequency();
5✔
94

95
    /* Allocate this from stack here so that GCC doesn't have
96
       to do it everytime implicitly when gettimeofday() is called */
97
    int ret = 0;
98

99
    /* Allocate all the memory at the start so we don't waste any time */
100
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
101
    mach_timespec_t* finish = static_cast<mach_timespec_t*> (malloc(sizeof(mach_timespec_t)));
102
    mach_timespec_t* current = static_cast<mach_timespec_t*> (malloc(sizeof(mach_timespec_t)));
103
#else
104
    struct timespec* finish = static_cast<struct timespec*> (malloc(sizeof(struct timespec)));
5✔
105
    struct timespec* current = static_cast<struct timespec*> (malloc(sizeof(struct timespec)));
5✔
106
#endif
107
    struct timespec* sleepTime = static_cast<struct timespec*> (malloc(sizeof(struct timespec)));
5✔
108
    struct timespec* remainingTime = static_cast<struct timespec*> (malloc(sizeof(struct timespec)));
5✔
109

110
    sleepTime->tv_sec = 0;
5✔
111

112
    /* This is the start time for the timer */
113
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
114
    ret = clock_get_time(cclock, finish);
115
#else
116
    ret = clock_gettime(CLOCK_MONOTONIC, finish);
5✔
117
#endif
118
    if (ret == -1)
5✔
119
    {
120
        qWarning() << Q_FUNC_INFO << "Unable to get the time accurately:"
×
121
                   << strerror(errno) << "- Stopping MasterTimerPrivate";
×
122
        m_run = false;
×
123
    }
124
    else
125
    {
126
        m_run = true;
5✔
127
    }
128

129
    while (m_run == true)
173✔
130
    {
131
        /* Add nsTickTime to the finish time, to calculate the end timestamp of this loop */
132
        finish->tv_sec += (finish->tv_nsec + nsTickTime) / 1000000000L;
168✔
133
        finish->tv_nsec = (finish->tv_nsec + nsTickTime) % 1000000000L;
168✔
134

135
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
136
        ret = clock_get_time(cclock, current);
137
#else
138
        ret = clock_gettime(CLOCK_MONOTONIC, current);
168✔
139
#endif
140
        if (ret == -1)
168✔
141
        {
142
            qWarning() << Q_FUNC_INFO << "Unable to get the current time:"
×
143
                       << strerror(errno);
×
144
            m_run = false;
×
145
            break;
×
146
        }
147

148
        /* Check if we're running late. This means that a tick is not enough
149
         * to process all the running Functions :'( */
150
        if (compareTime(finish, current) <= 0)
168✔
151
        {
152
            qDebug() << Q_FUNC_INFO << "MasterTimer is running late!";
153
            /* No need to sleep. Immediately process the next tick */
154
            mt->timerTick();
×
155
            /* Now the finish time needs to be recalibrated */
156
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
157
            clock_get_time(cclock, finish);
158
#else
159
            clock_gettime(CLOCK_MONOTONIC, finish);
×
160
#endif
161
            continue;
×
162
        }
163

164
        /* Do a rough sleep using the kernel to return control.
165
           We know that this will never be seconds as we are dealing
166
           with jumps of under a second every time. */
167
        sleepTime->tv_sec = finish->tv_sec - current->tv_sec;
168✔
168
        if (finish->tv_nsec < current->tv_nsec)
168✔
169
        {
170
            sleepTime->tv_nsec = finish->tv_nsec + 1000000000L - current->tv_nsec ;
×
171
            sleepTime->tv_sec--; /* Decrease a second. */
×
172
        }
173
        else
174
            sleepTime->tv_nsec = finish->tv_nsec - current->tv_nsec;
168✔
175

176
        //qDebug() << Q_FUNC_INFO << "Sleeping ns:" << sleepTime->tv_nsec;
177

178
        ret = nanosleep(sleepTime, remainingTime);
168✔
179
        while (ret == -1 && sleepTime->tv_nsec > 100)
168✔
180
        {
181
            sleepTime->tv_nsec = remainingTime->tv_nsec;
×
182
            ret = nanosleep(sleepTime, remainingTime);
×
183
        }
184

185
#if 0
186
        /* Now take full CPU for precision (only a few nanoseconds,
187
           at maximum 100 nanoseconds) */
188
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
189
        ret = clock_get_time(cclock, current);
190
#else
191
        ret = clock_gettime(CLOCK_MONOTONIC, current);
192
#endif
193
        sleepTime->tv_nsec = finish->tv_nsec - current->tv_nsec;
194

195
        while (sleepTime->tv_nsec > 5)
196
        {
197
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
198
            ret = clock_get_time(cclock, current);
199
#else
200
            ret = clock_gettime(CLOCK_MONOTONIC, current);
201
#endif
202
            sleepTime->tv_nsec = finish->tv_nsec - current->tv_nsec;
203
            qDebug() << "Full CPU wait:" << sleepTime->tv_nsec;
204
        }
205
#endif
206
        /* Execute the next timer event */
207
        mt->timerTick();
168✔
208
    }
209

210
    free(finish);
5✔
211
    free(current);
5✔
212
    free(sleepTime);
5✔
213
    free(remainingTime);
5✔
214
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc