Skip to content

Commit 584b73a

Browse files
cfriedtnashif
authored andcommitted
timeutil: make timespec_normalize() a regular function
Since the timespec_normalize() function is not branchless, and since it can also generate a fair bit of code, make the function non-inline and place it in timeutil.c instead. This should save some code space on most systems. Signed-off-by: Chris Friedt <[email protected]>
1 parent d02235c commit 584b73a

File tree

2 files changed

+53
-47
lines changed

2 files changed

+53
-47
lines changed

include/zephyr/sys/timeutil.h

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -415,51 +415,7 @@ static inline bool timespec_is_valid(const struct timespec *ts)
415415
*
416416
* @return `true` if the operation completes successfully, otherwise `false`.
417417
*/
418-
static inline bool timespec_normalize(struct timespec *ts)
419-
{
420-
__ASSERT_NO_MSG(ts != NULL);
421-
422-
long sec;
423-
424-
if (ts->tv_nsec >= (long)NSEC_PER_SEC) {
425-
sec = ts->tv_nsec / (long)NSEC_PER_SEC;
426-
} else if (ts->tv_nsec < 0) {
427-
sec = DIV_ROUND_UP((unsigned long)-ts->tv_nsec, NSEC_PER_SEC);
428-
} else {
429-
sec = 0;
430-
}
431-
432-
if ((ts->tv_nsec < 0) && (ts->tv_sec < 0) && (ts->tv_sec - SYS_TIME_T_MIN < sec)) {
433-
/*
434-
* When `tv_nsec` is negative and `tv_sec` is already most negative,
435-
* further subtraction would cause integer overflow.
436-
*/
437-
return false;
438-
}
439-
440-
if ((ts->tv_nsec >= (long)NSEC_PER_SEC) && (ts->tv_sec > 0) &&
441-
(SYS_TIME_T_MAX - ts->tv_sec < sec)) {
442-
/*
443-
* When `tv_nsec` is >= `NSEC_PER_SEC` and `tv_sec` is already most
444-
* positive, further addition would cause integer overflow.
445-
*/
446-
return false;
447-
}
448-
449-
if (ts->tv_nsec >= (long)NSEC_PER_SEC) {
450-
ts->tv_sec += sec;
451-
ts->tv_nsec -= sec * (long)NSEC_PER_SEC;
452-
} else if (ts->tv_nsec < 0) {
453-
ts->tv_sec -= sec;
454-
ts->tv_nsec += sec * (long)NSEC_PER_SEC;
455-
} else {
456-
/* no change: SonarQube was complaining */
457-
}
458-
459-
__ASSERT_NO_MSG(timespec_is_valid(ts));
460-
461-
return true;
462-
}
418+
bool timespec_normalize(struct timespec *ts);
463419

464420
/**
465421
* @brief Add one timespec to another

lib/utils/timeutil.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@
1010
* http://howardhinnant.github.io/date_algorithms.html#days_from_civil
1111
*/
1212

13-
#include <zephyr/types.h>
1413
#include <errno.h>
15-
#include <stddef.h>
1614
#include <stdbool.h>
15+
#include <stddef.h>
16+
#include <stdint.h>
17+
#include <time.h>
18+
19+
#include <zephyr/sys/__assert.h>
20+
#include <zephyr/sys/clock.h>
1721
#include <zephyr/sys/timeutil.h>
1822

1923
/** Convert a civil (proleptic Gregorian) date to days relative to
@@ -188,3 +192,49 @@ int32_t timeutil_sync_skew_to_ppb(float skew)
188192

189193
return (ppb64 == ppb32) ? ppb32 : INT32_MIN;
190194
}
195+
196+
bool timespec_normalize(struct timespec *ts)
197+
{
198+
__ASSERT_NO_MSG(ts != NULL);
199+
200+
long sec;
201+
202+
if (ts->tv_nsec >= (long)NSEC_PER_SEC) {
203+
sec = ts->tv_nsec / (long)NSEC_PER_SEC;
204+
} else if (ts->tv_nsec < 0) {
205+
sec = DIV_ROUND_UP((unsigned long)-ts->tv_nsec, NSEC_PER_SEC);
206+
} else {
207+
sec = 0;
208+
}
209+
210+
if ((ts->tv_nsec < 0) && (ts->tv_sec < 0) && (ts->tv_sec - SYS_TIME_T_MIN < sec)) {
211+
/*
212+
* When `tv_nsec` is negative and `tv_sec` is already most negative,
213+
* further subtraction would cause integer overflow.
214+
*/
215+
return false;
216+
}
217+
218+
if ((ts->tv_nsec >= (long)NSEC_PER_SEC) && (ts->tv_sec > 0) &&
219+
(SYS_TIME_T_MAX - ts->tv_sec < sec)) {
220+
/*
221+
* When `tv_nsec` is >= `NSEC_PER_SEC` and `tv_sec` is already most
222+
* positive, further addition would cause integer overflow.
223+
*/
224+
return false;
225+
}
226+
227+
if (ts->tv_nsec >= (long)NSEC_PER_SEC) {
228+
ts->tv_sec += sec;
229+
ts->tv_nsec -= sec * (long)NSEC_PER_SEC;
230+
} else if (ts->tv_nsec < 0) {
231+
ts->tv_sec -= sec;
232+
ts->tv_nsec += sec * (long)NSEC_PER_SEC;
233+
} else {
234+
/* no change: SonarQube was complaining */
235+
}
236+
237+
__ASSERT_NO_MSG(timespec_is_valid(ts));
238+
239+
return true;
240+
}

0 commit comments

Comments
 (0)