Skip to content

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

Closed
wants to merge 1 commit into from

Conversation

andyross
Copy link
Collaborator

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.

@andyross andyross requested a review from dbkinder as a code owner September 16, 2019 21:01
@andyross andyross added the DNM This PR should not be merged (Do Not Merge) label Sep 16, 2019
@zephyrbot
Copy link
Collaborator

zephyrbot commented Sep 16, 2019

Some checks failed. Please fix and resubmit.

checkpatch issues

-:406: ERROR:TRAILING_WHITESPACE: trailing whitespace
#406: FILE: doc/reference/kernel/timing/clocks.rst:231:
+  $

-:410: WARNING:TYPO_SPELLING: 'auxilliary' may be misspelled - perhaps 'auxiliary'?
#410: FILE: doc/reference/kernel/timing/clocks.rst:235:
+An auxilliary job of the timing subsystem is to provide tick counters

-:890: WARNING:TYPO_SPELLING: 'teh' may be misspelled - perhaps 'the'?
#890: FILE: doc/reference/misc/data_structures.rst:382:
+will copy bytes out of teh ring buffer in the order that they were

- total: 1 errors, 2 warnings, 927 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

NOTE: Whitespace errors detected.
      You may wish to use scripts/cleanpatch or scripts/cleanfile

Your patch has style problems, please review.

NOTE: Ignored message types: AVOID_EXTERNS BRACES CONFIG_EXPERIMENTAL CONST_STRUCT DATE_TIME FILE_PATH_CHANGES MINMAX NETWORKING_BLOCK_COMMENT_STYLE PRINTK_WITHOUT_KERN_LEVEL SPLIT_STRING VOLATILE

NOTE: If any of the errors are false positives, please report
      them to the maintainers.

Tip: The bot edits this comment instead of posting a new one, so you can check the comment's history to see earlier messages.

@nashif
Copy link
Member

nashif commented Sep 16, 2019

@ulfalizer the checkpatch output should be treated as preformatted text. This used to work before.

@ulfalizer
Copy link
Collaborator

@nashif
Yeah, noticed it. Will add a fix once I'm done with some other stuff.

@ulfalizer
Copy link
Collaborator

ulfalizer commented Sep 16, 2019


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
Copy link
Member

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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: on -> or?

Copy link
Contributor

@dbkinder dbkinder left a 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:
Copy link
Contributor

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.
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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)

Copy link
Member

@aescolar aescolar left a 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
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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.."

Copy link
Member

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
Copy link
Member

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.
Copy link
Member

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

Copy link
Collaborator

@pabigot pabigot left a 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
Copy link
Collaborator

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
Copy link
Collaborator

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.


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
Copy link
Collaborator

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
Copy link
Collaborator

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
Copy link
Collaborator

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
Copy link
Collaborator

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
Copy link
Collaborator

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).

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]>
@andyross
Copy link
Collaborator Author

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
Copy link
Member

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);

@andyross
Copy link
Collaborator Author

Close this, updated work is in #24742

@andyross andyross closed this Apr 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Documentation DNM This PR should not be merged (Do Not Merge)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants