Introduces a specialized syscall for yield.
|Date submitted (year-month-day)||2021-11-29|
|Date reviewed (year-month-day)||2021-10-13|
We propose adding a new syscall
zx_thread_legacy_yield , that causes
the calling thread to yield the cpu to another waiting thread. Additionally,
we would remove the special case of
zx_nanosleep when the deadline is
equal to zero. The
legacy in the syscall's name exists as an indication
of the availability of more suitable mechanisms to achieve the desired
The behavior of
zx_nanosleep deviates from how deadlines are treated in all
other syscalls, that is if the deadline is before the current time, then it
returns immediately. Currently, this is a special case where a deadline value
of zero means yield.
Furthermore, it is impossible to determine at runtime, whether the deadline
was intentionally set to zero or was the result of a calculation. This would
zx_nanosleep works, reducing the special cases a developer
needs to be aware of. A deadline can be manually set to zero, in order to
cause the thread to yield, while it can also be zero as the result of the
next wake up (which means to continue right now).
Who has a stake in whether this RFC is accepted? (This section is optional but encouraged.)
The person appointed by FEC to shepherd this RFC through the RFC process.
Socialization: The design was initially discussed in a design doc.
This proposal consist of the following changes to the Zircon syscall API:
- Addition of
- Simplification of
zx_thread_legacy_yield is defined as:
/// Yields cpu to another waiting thread. /// `options`: Reserved for future extension. Must be zero. /// @blocking zx_status_t zx_thread_legacy_yield(uint32_t options);
zx_thread_legacy_yield is called on a user space application,
the calling thread yields the cpu. The
options parameter could be
used to introduce hints later.
options equal to zero is
guaranteed to return
zx_nanosleep is called with a deadline that is greater than the time in
the monotonic clock, then calling thread is put to sleep until the deadline
(plus slack) is met. On the other hand, when the deadline has a
value equal or prior to the time in the monotonic clock, then it returns
immediately. But if the deadline is zero, it will cause the calling thread
to yield. After introducing
zx_thread_legacy_yield the goal is to remove
the special handling of zero deadlines.
syscalls_zx_nanosleep_zero_duration kernel counter must be
syscalls_zx_thread_legacy_yield counter is introduced.
zx_nanosleep(0) has 2 callsites(which provide an implementation of
sched_yield) outside the fuchsia tree, and 7 callsites in-tree.
Which involves splitting the work in four CLs.
- Introduce new syscall
- Migrate in-tree users to
- Migrate out of tree users.
- Remove yield overload from
CL (1) will include documentation, language binding updates, and CL (4) will update the documentation as well. (1) and (2) could be merged into a single CL, but separating implementation from migration seems like a cleaner path.
There is no known impact on performance, other than a slight improvement in
zx_nanosleep path, since a branch is removed.
The users of
zx_nanosleep(0) are not limited to the stem repository.
The behavior of the existing code and the new code will be exactly the same,
zx_nanosleep(0) (now) is equivalent to
In order to prevent any security issues from arising,
remain unchanged until all use cases of
zx_nanosleep(0) have been migrated
This proposal has no impact on privacy.
The nature of
zx_thread_legacy_yield makes it hard to test reliably, but
very least we can verify that the return codes match the expectations.
We will add additional documentation for
update the entry for
zx_nanosleep to remove the mention of zero deadline
being a special case.
Drawbacks, alternatives, and unknowns
The biggest drawback and concern is the existence of
zx_thread_legacy_yield encouranging busy waits patterns, but
sched_yield provides this mechanism already. These concerns can be mitigated
through proper documentation and best practices. Since the target users of
this syscall are drivers, any other usage should be looked at carefully.
Another alternative that was considered was changing the magic value to
INT_MIN ). This would indeed address the calculated deadline
problem, while still leaving a special case. This alternative would require
updating out of tree user as well, which is why it requires the same effort as
adding a new syscall. The biggest drawback is that doing so, will leave
zx_nanosleep deadline handling being special from another operations that
deal with deadlines, such as
Prior art and references
zx_nanosleepuses 0 as a special value, to indicate "yield". The problem is that there is code that effectively does a deadline calculation which can compute 0, in this case the intention is not to yield, quite the opposite: execute the next statement "now".
yieldis usually an indication of something done wrong. Unfortunately it is not uncommon to see it in drivers whose hardware lacks the proper signaling mode.