Skip to content

Commit 8816044

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 1681d88 commit 8816044

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

doc/kernel/timeutil.rst

+110
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,89 @@ 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_overflow`.
130+
131+
.. code-block:: c
132+
133+
if (timespec_normalize_overflow(&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_overflow`, :c:func:`timespec_sub_overflow`, and
169+
:c:func:`timespec_negate_overflow`, respectively. Like :c:func:`timespec_normalize_overflow`,
170+
these functions will output a normalized ``timespec`` when doing so would not result in overflow.
171+
If overflow would occur, the functions return ``true``.
172+
173+
.. code-block:: c
174+
175+
/* a += b */
176+
if (timespec_add_overflow(&a, &b)) {
177+
/* overflow */
178+
}
179+
180+
/* a -= b */
181+
if (timespec_sub_overflow(&a, &b)) {
182+
/* overflow */
183+
}
184+
185+
/* a = -a */
186+
if (timespec_negate_overflow(&a)) {
187+
/* overflow */
188+
}
189+
190+
.. doxygengroup:: timeutil_timespec_apis
191+
192+
109193
.. _timeutil_concepts:
110194

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

0 commit comments

Comments
 (0)