Skip to content

Commit c228df1

Browse files
committed
doc: kernel: timeutil: add documentation for timespec apis
Add documentation in the timeutil group for recently added functions for validating, comparing, and manipulating `struct timespec` objects. Signed-off-by: Chris Friedt <[email protected]>
1 parent 94dbad5 commit c228df1

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

doc/kernel/timeutil.rst

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ The time utilities API supports:
2828

2929
* :ref:`converting between time representations <timeutil_repr>`
3030
* :ref:`synchronizing and aligning time scales <timeutil_sync>`
31+
* :ref:`comparing, adding, and subtracting representations <timeutil_manip>`
3132

3233
For terminology and concepts that support these functions see
3334
:ref:`timeutil_concepts`.
@@ -106,6 +107,88 @@ process:
106107

107108
.. doxygengroup:: timeutil_sync_apis
108109

110+
.. _timeutil_manip:
111+
112+
``timespec`` Manipulation
113+
=========================
114+
115+
Checking the validity of a ``timespec`` can be done with :c:func:`timespec_is_valid`.
116+
117+
.. code-block:: c
118+
119+
struct timespec ts = {
120+
.tv_sec = 0,
121+
.tv_nsec = -1, /* out of range! */
122+
};
123+
124+
if (!timespec_is_valid(&ts)) {
125+
/* error-handing code */
126+
}
127+
128+
In some cases, invalid ``timespec`` objects may be re-normalized using
129+
:c:func:`timespec_normalize`.
130+
131+
.. code-block:: c
132+
133+
if (timespec_normalize(&ts)) {
134+
/* this indicates overflow, but is not reachable with the definition of ts above */
135+
}
136+
137+
/* ts should be normalized */
138+
__ASSERT(timespec_is_valid(&ts) == true, "expected normalized timespec");
139+
140+
It is possible to compare two ``timespec`` objects for equality using :c:func:`timespec_equal`.
141+
142+
.. code-block:: c
143+
144+
if (timespec_equal(then, now)) {
145+
/* time is up! */
146+
}
147+
148+
It is possible to compare and fully order (valid) ``timespec`` objects using
149+
:c:func:`timespec_compare`.
150+
151+
.. code-block:: c
152+
153+
int cmp = timespec_compare(a, b);
154+
155+
switch (cmp) {
156+
case 0:
157+
/* a == b */
158+
break;
159+
case -1:
160+
/* a < b */
161+
break;
162+
case +1:
163+
/* a > b */
164+
break;
165+
}
166+
167+
It is possible to add, subtract, and negate ``timespec`` objects using :c:func:`timespec_add`,
168+
:c:func:`timespec_sub`, and :c:func:`timespec_negate`, respectively. Like
169+
:c:func:`timespec_normalize`, these functions will output a normalized ``timespec`` when
170+
doing so would not result in overflow. If overflow would occur, the functions return ``true``.
171+
172+
.. code-block:: c
173+
174+
/* a += b */
175+
if (timespec_add(&a, &b)) {
176+
/* overflow */
177+
}
178+
179+
/* a -= b */
180+
if (timespec_sub(&a, &b)) {
181+
/* overflow */
182+
}
183+
184+
/* a = -a */
185+
if (timespec_negate(&a)) {
186+
/* overflow */
187+
}
188+
189+
.. doxygengroup:: timeutil_timespec_apis
190+
191+
109192
.. _timeutil_concepts:
110193

111194
Concepts Underlying Time Support in Zephyr
@@ -236,3 +319,29 @@ The mechanism used to populate synchronization points is not relevant: it may
236319
involve reading from a local high-precision RTC peripheral, exchanging packets
237320
over a network using a protocol like NTP or PTP, or processing NMEA messages
238321
received a GPS with or without a 1pps signal.
322+
323+
``timespec`` Concepts
324+
=====================
325+
326+
Originally from POSIX, ``struct timespec`` has been a part of the C standard
327+
since C11. The definition of ``struct timespec`` is as shown below.
328+
329+
.. code-block:: c
330+
331+
struct timespec {
332+
time_t tv_sec; /* seconds */
333+
long tv_nsec; /* nanoseconds */
334+
};
335+
336+
.. _note:
337+
338+
The C standard does not define the size of ``time_t``. However, Zephyr
339+
uses 64-bits for ``time_t``. The ``long`` type is required to be at least
340+
32-bits, but usually matches the word size of the architecture. Both
341+
elements of ``struct timespec`` are signed integers. ``time_t`` is defined
342+
to be 64-bits both for historical reasons and to be robust enough to
343+
represent times in the future.
344+
345+
The ``tv_nsec`` field is only valid with values in the range ``[0, 999999999]``. The
346+
``tv_sec`` field is the number of seconds since the epoch. If ``struct timespec`` is
347+
used to express a difference, the ``tv_sec`` field may fall into a negative range.

0 commit comments

Comments
 (0)