-
Notifications
You must be signed in to change notification settings - Fork 7.3k
doc: Add documentation for data structures, rework timing overview #19201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Some checks failed. Please fix and resubmit. checkpatch issues
Tip: The bot edits this comment instead of posting a new one, so you can check the comment's history to see earlier messages. |
@ulfalizer the checkpatch output should be treated as preformatted text. This used to work before. |
@nashif |
|
||
Other options for timeout initialization follow the unit conventions | ||
described above: ``K_TIMEOUT_US()``, ``K_TIMEOUT_TICKS()`` and | ||
``K_TIMEOUT_CYC()`` specify timeout values that will expire after |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really related to this PR but just pondering why we have K_TIMEOUT_CYC() instead of K_TIMEOUT_CYCLE(). Saving two bytes here seems unnecessary as we have K_TIMEOUT_TICKS() which is identical length.
Kernel time is tracked in several units which are used for different | ||
purposes. | ||
|
||
Real time values, typically specified in milliseconds on microseconds, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: on -> or?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your reST-foo powers are increasing with practice. :)
The hardware clock can be used to measure time with higher precision than | ||
that provided by kernel services based on the system clock. | ||
|
||
.. _clock_limitations: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a reference to this "Clock Limitations" section coming from https://docs.zephyrproject.org/latest/reference/kernel/timing/timers.html#timer-limitations so we need to provide a target in your new clocks.rst doc with this same name, or remove the reference from doc/reference/kernel/timing/timers.rst
========== | ||
|
||
Kernel time is tracked in several units which are used for different | ||
purposes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add something like this to connect this opening sentence to the following paragraphs:
purposes: real time values, cycles, and ticks.
hardware perfectly. | ||
|
||
The kernel presents a "cycle" count via the ``k_cycle_get_32()`` API. | ||
The intent is that this counter represents the fastest cycle counter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete The intent is that
and start the sentence with This counter ...
The kernel presents a "cycle" count via the ``k_cycle_get_32()`` API. | ||
The intent is that this counter represents the fastest cycle counter | ||
that the operating system is able to present to the user (for example, | ||
a CPU cycle counter) and that the read operation is very fast. The |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change and that the read
to and the read
The intent is that this counter represents the fastest cycle counter | ||
that the operating system is able to present to the user (for example, | ||
a CPU cycle counter) and that the read operation is very fast. The | ||
expectation is that very sensitive application code might use this in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete The expectation is that very
and start the sentence with Sensitive application ...
example: a ``struct wait_q``, or a ``k_tid_t`` thread struct). | ||
|
||
Note that all variant units passed via a ``k_timeout_t`` are converted | ||
to ticks once on insertion into the list. There no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think once
can be deleted here.
Also, There are no
expected to be embedded within subsystem-defined data structures (for | ||
example: a ``struct wait_q``, or a ``k_tid_t`` thread struct). | ||
|
||
Note that all variant units passed via a ``k_timeout_t`` are converted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete Note that
and begin the sentence with All variants...
guaranteed at the tick level no matter how many events exist or how | ||
long a timeout might be. | ||
|
||
Note that the list structure means that the CPU work involved in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this first sentence to:
Because of this timeout list structure, the CPU work to manage
large numbers of timeouts is quadratic to the number of active
timeouts.
comparatively simple API. | ||
|
||
* The driver is expected to be able to "announce" new ticks to the | ||
kernel via the ``z_clock_nanounce()`` call, which passes an integer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably z_clock_announce()
counter driver can be trivially implemented also: | ||
|
||
* The driver can receive interrupts at a regular rate corresponding to | ||
the OS tick rate, calling z_clock_anounce() with an argument of one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put ticks around z_clock_announce (and fix misspelling)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this @andyross .
Just a few comments from me. In some of them I'm very picky, so you are welcome to ignore them if you do not agree.
* The kernel ``k_delayed_work`` API provides a timeout parameter | ||
indicating when a work queue item will be added to the system queue. | ||
|
||
All these values are specified using a ``k_timeout_t`` value. This is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(In the PR description) Could you add a reference to 17155 marking this one as blocked by that one?
``K_TIMEOUT_CYC()`` specify timeout values that will expire after | ||
specified numbers of microseconds, ticks and cycles, respectively. | ||
|
||
Precision of ``k_timeout_t`` values is configurable, with the default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: When you said "precision" I expected you refered to the resolution (i.e. ticks) not to the bit-width / range.
to the kernel which indicates how many ticks may elapse before the | ||
kernel must receive an announce call to trigger registered timeouts. | ||
It is legal to announce new ticks before that moment (though they | ||
must be correct) but delay after that will cause events to be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This "but delay after that will cause events to be missed" would seem to make this paragraph a bit more confusing than it should, as it is really re-stating as a negative something which was stated before.
I would just remove it.
and real world time. | ||
|
||
* The driver is expected to provide a ``z_clock_set_timeout()`` call | ||
to the kernel which indicates how many ticks may elapse before the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This paragraph was a bit difficult to understand in a first read.
(it seems you provide more clearly a list of things this function should not do, but are less clear about what this function should do.)
Would it be a bit clearer to write this line as:
"to the kernel. The kernel will use it to indicate how many.."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be nice to put a bit more of clear emphasis first in what is expected the function will do. And then, clearly demarked, after, what it should not do.
* The next timeout value passed back to the driver via | ||
``z_clock_set_timeout()`` is done identically for every CPU. So by | ||
default, every CPU will see simultaneous timer interrupts for every | ||
event, even though by definition only one of them. This is probably |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence seems to be cut mid way (verb missing): ", even though by definition only one of them"
a correct default for timing sensitive applications (because it | ||
minimizes the chance that an errant ISR or interrupt lock will delay | ||
a timeout), but may be a performance problem in some cases. The | ||
current architecture expects that any such optimization. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence also seems to need rephrasing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I think this is good, it is premature as it documents a system that has #17155 merged into it. Exactly what will be provided by that PR is still in discussion as there has been no response to review comments yet.
|
||
For asynchronous timekeeping, the kernel defines a "ticks" concept. A | ||
"tick" is the internal count in which the kernel does all its internal | ||
uptime and timeout bookeeping. Interrupts are expected to be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be "Timeout interrupts..."
"near" (round to nearest). Finally the output precision can be | ||
specified as either 32 or 64 bits. | ||
|
||
For example: ``k_ms_to_ticks_ceil32()`` will convert a millisecond |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section only applies to #17155 (and the names and API provided are in dispute). I think once this gets through review it should be made part of that PR.
2145d21
to
30651c7
Compare
|
||
For asynchronous timekeeping, the kernel defines a "ticks" concept. A | ||
"tick" is the internal count in which the kernel does all its internal | ||
uptime and timeout bookeeping. Interrupts are expected to be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Timer interrupts...
All Zephyr ``k_timeout_t`` events specified using the API above are | ||
managed in a single, global queue of events. Each event is stored in | ||
a double-linked list, with an attendant delta count in ticks from the | ||
previous event. The action to take on an event is specified as a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the time reference for first event in the list?
kernel must receive an announce call to trigger registered timeouts. | ||
It is legal to announce new ticks before that moment (though they | ||
must be correct) but delay after that will cause events to be | ||
missed. Note that the timeout value passed here is in a delta from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed? I would say "delayed"...
It is legal to announce new ticks before that moment (though they | ||
must be correct) but delay after that will cause events to be | ||
missed. Note that the timeout value passed here is in a delta from | ||
current time, but that does not absolve the driver of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current time? As far as I remember all system clock API uses last announcement as a reference...
* The driver is expected to provide a ``z_clock_elapsed()`` call which | ||
provides a current indication of how many ticks have elapsed (as | ||
compared to a real world clock) since the last call to | ||
``z_clock_announce()``, which the kernel needs to test newly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since last announced tick. The call to z_clock_announce() is always delayed (by interrupt/driver latency).
30651c7
to
cefe32b
Compare
Rework the timer documentation so it reflects current design, adding significant detail on internals and the orhogonalized unit support in the existing code. Also add a new document describing the list, tree and ring buffer data structures under lib/os. We had doxygen references for this stuff, but never had an overview document. Signed-off-by: Andy Ross <[email protected]>
cefe32b
to
6cfab82
Compare
New version to address comments. Also includes some very nice diagrams from @laurenmurphyx64 in the data structures section. Cleaned up some phrasing in the pre-existing k_timer docs to better reflect current conventions (and to fix that broken link, which is how I got there). |
expires for the first time. This is a ``k_timeout_t`` value that | ||
may be initialized via different units. | ||
|
||
* A :dfn:`period` specifying the time interval between all timer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to update the two code examples below:
k_timer_start(&my_status_timer, K_MSEC(200), 0);
and
k_timer_start(&my_sync_timer, K_MSEC(500), 0);
Close this, updated work is in #24742 |
Another documentation PR bringing the timeout subsystem up to date with current code and adding a few pages detailing the various data structures we provide in lib/os.
As before, this reflects my preschool-level understanding of RST and is going to need significant technical cleanup before merge. And there are a few diagrams (that I also need to get help on) that need to be added in a few spots too.