Skip to content

Commit da9e55d

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 ecd53e4 commit da9e55d

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

doc/kernel/timeutil.rst

+111
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,90 @@ 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+
/* error-handling code */
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
168+
:c:func:`timespec_add`, :c:func:`timespec_sub`, and :c:func:`timespec_negate`,
169+
respectively. Like :c:func:`timespec_normalize`, these functions will output
170+
a normalized ``timespec`` when doing so would not result in overflow.
171+
On success, these functions return ``true``. If overflow would occur, the
172+
functions return ``false``.
173+
174+
.. code-block:: c
175+
176+
/* a += b */
177+
if (!timespec_add(&a, &b)) {
178+
/* overflow */
179+
}
180+
181+
/* a -= b */
182+
if (!timespec_sub(&a, &b)) {
183+
/* overflow */
184+
}
185+
186+
/* a = -a */
187+
if (!timespec_negate(&a)) {
188+
/* overflow */
189+
}
190+
191+
.. doxygengroup:: timeutil_timespec_apis
192+
193+
109194
.. _timeutil_concepts:
110195

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

0 commit comments

Comments
 (0)