blob: 73ba76d4cb67392b1d3a16b5009a996b9a66813a [file] [log] [blame] [view]
<!--
Copyright 2022 The Fuchsia Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
DO NOT EDIT. Generated from FIDL library zx by zither, a Fuchsia platform tool.
See //docs/reference/syscalls/README.md#documentation-generation for
regeneration instructions.
-->
# zx_clock_update
## Summary
Make adjustments to a clock object.
## Declaration
```c
#include <zircon/syscalls.h>
zx_status_t zx_clock_update(zx_handle_t handle,
uint64_t options,
const void* args);
```
## Rights
*handle* must be of type **ZX_OBJ_TYPE_CLOCK** and have **ZX_RIGHT_WRITE**.
## Description
Three different parameters may be dynamically controlled by a clock maintainer.
They are
+ The clock's current value.
+ The clock's rate adjustment, expressed in PPM deviation from nominal.
+ The clock's current estimated error bounds.
When a clock maintainer wishes to change one or more of these parameters, they
may do so using the `zx_clock_update` syscall. Updating a clock's parameters is
an atomic operation from the perspective of all other users in the system.
The first update operation performed by a clock maintainer must include a valid
value. This update is the update that starts the clock and defines its initial
value. Before this update operation has succeeded, the **ZX_CLOCK_STARTED**
signal will be de-asserted, and afterwards it will be asserted and remain so for
the lifetime of the clock.
In order to update a clock, a user fills out the fields of a
`zx_clock_update_args_v2_t` structure that they wish to adjust, then passes the
structure to the update call, setting the bits in `options` which indicate both
the explicit version of the structure (version 2), and which of these fields are
valid and should be set. Defined `options` bits are
+ **ZX_CLOCK_UPDATE_OPTION_SYNTHETIC_VALUE_VALID**
+ **ZX_CLOCK_UPDATE_OPTION_REFERENCE_VALUE_VALID**
+ **ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID**
+ **ZX_CLOCK_UPDATE_OPTION_ERROR_BOUND_VALID**
The version of the structure is passed using the `ZX_CLOCK_ARGS_VERSION(...)`
macro, specifically `ZX_CLOCK_ARGS_VERSION(2)` for the version 2 structure.
For example
```c
#include <zircon/syscalls.h>
#include <zircon/syscalls/clock.h>
void MaintainMyClock(zx_handle_t the_clock) {
zx_clock_update_args_v2_t args;
zx_status_t status;
// Set the clock's value to 1500. Note that this also starts the clock.
args.synthetic_value = 1500;
status = zx_clock_update(the_clock,
ZX_CLOCK_ARGS_VERSION(2) | ZX_CLOCK_UPDATE_OPTION_SYNTHETIC_VALUE_VALID,
&args);
if (status != ZX_OK) {
// Panic!
return;
}
// Make the clock run 23 PPM slower than nominal relative to clock monotonic.
args.rate_adjust = -23;
status = zx_clock_update(the_clock,
ZX_CLOCK_ARGS_VERSION(2) | ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID,
&args);
if (status != ZX_OK) {
// Halt and catch fire
return;
}
// Set the clock to 100,000, make it run 50 PPM faster than nominal, and specify an error bound of
// +/- 400mSec, all at the same time.
const uint64_t options = ZX_CLOCK_ARGS_VERSION(2) |
ZX_CLOCK_UPDATE_OPTION_SYNTHETIC_VALUE_VALID |
ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID |
ZX_CLOCK_UPDATE_OPTION_ERROR_BOUND_VALID;
args.synthetic_value = 100000;
args.rate_adjust = 50;
args.error_bound = ZX_MSEC(400);
status = zx_clock_update(the_clock, options, &args);
if (status != ZX_OK) {
// Burn down, fall over, and then sink into the swamp.
return;
}
}
```
### Explicitly provided reference times. {#explicit-reference-time}
With the addition of the V2 update structure, it is now possible (with some
limitations) to explicitly control the reference time used for a clock update
operation. Note that, upon success, the actual new reference <-> synthetic
transformation specified by the user's update arguments will replace the old
transformation during the call to `zx_clock_update`. Supplying an explicit
reference time does _not_ affect when the actual transformation is updated, it
will always take effect during the call to `zx_clock_update`.
Diagrams provided in
[RFC-0077](/docs/contribute/governance/rfcs/0077_zx_clock_update_accuracy.md)
may help to understand the effects of the operations described below.
#### Synthetic value updates with an explicitly provided reference time.
When users update the synthetic value (`S`) of a clock with an explicitly
provided reference time (`R`), they are specifying a point (`[R, S]`) through
which the new transformation will pass. In other words, the new transformation
explicitly specifies that "when it is time R on the reference timeline, it will
be time S on the synthetic timeline".
```c
#include <zircon/syscalls.h>
#include <zircon/syscalls/clock.h>
// Set the syntheic value of the clock to be "synth" at the explicitly provided
// reference time "ref". In other words, upon success, this update operation will
// cause the clock's transformation from reference to synthetic time to
// specifically pass through the point (ref, synth)
zx_status_t SetSynthAtRef(zx_handle_t the_clock, zx_time_t ref, zx_time_t synth) {
zx_clock_update_args_v2_t args;
uint64_t options = ZX_CLOCK_ARGS_VERSION(2) |
ZX_CLOCK_UPDATE_OPTION_REFERENCE_VALUE_VALID |
ZX_CLOCK_UPDATE_OPTION_SYNTHETIC_VALUE_VALID;
// Note that these options are equivalent, they just use a shorthand to
// specify that both values are valid.
options = ZX_CLOCK_ARGS_VERSION(2) | ZX_CLOCK_UPDATE_OPTION_BOTH_VALUES_VALID;
args.reference_value = ref;
args.synthetic_value = synth;
return zx_clock_update(the_clock, options, args);
}
```
#### Rate adjustment updates with an explicitly provided reference time.
Let `T(R)` be the function which transforms a reference time `R` to a synthetic
time for a clock before an update operation. When users adjust the rate of a
clock with an explicitly provided reference time (`R`), they are specifying the
slope of the new transformation `T'(R)` for the clock, such that `T'(R) = T(R)`.
In other words, at reference time `R`, the new transformation will pass through
the same synthetic time that the old transformation did, but with a different
slope.
```c
#include <zircon/syscalls.h>
#include <zircon/syscalls/clock.h>
zx_status_t SetRateAtRef(zx_handle_t the_clock, zx_time_t ref, int32_t ppm_adj) {
zx_clock_update_args_v2_t args;
const uint64_t options = ZX_CLOCK_ARGS_VERSION(2) |
ZX_CLOCK_UPDATE_OPTION_REFERENCE_VALUE_VALID |
ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID;
args.reference_value = ref;
args.rate_adjust = ppm_adj;
return zx_clock_update(the_clock, options, args);
}
```
#### Notes, rules, and limitations.
- Explicit reference values are _not required_. It is still possible to omit
the reference value during an update operation. The update operation will
simply use the current reference time when the operation is processed.
- When providing an explicit reference value for a clock update operation,
either a synthetic value, or a rate adjustment, or both, must also be
provided. It is not legal to attempt to update only the error bounds at an
explicit reference value.
- Explicitly providing a reference value to an update operation for a continuous
clock is never allowed as it would virtually always imply a discontinuity.
- Explicitly providing a reference value to an update operation for a monotonic
clock _is_ allowed, but _only_ if the behavior of the clock remains monotonic
after the update.
- An explicitly provided reference value during an update operation which would
cause a read performed at a reference time of "now" to violate the configured
backstop time of the clock will cause the operation to be rejected.
- When updating a monotonic clock, it is not possible to effect both a
synthetic value update and a rate adjustment simultaneously.
Details provided in
[RFC-0077](/docs/contribute/governance/rfcs/0077_zx_clock_update_accuracy.md)
may help to understand the reasoning behind some of these rules and limitations.
## Return value
On success, returns **ZX_OK**.
## Errors
- **ZX_ERR_BAD_HANDLE** : *handle* is either an invalid handle, or a handle to
an object type that is not **ZX_OBJ_TYPE_CLOCK**.
- **ZX_ERR_ACCESS_DENIED** : *handle* lacks the **ZX_RIGHT_WRITE** right.
- **ZX_ERR_INVALID_ARGS** : The update request made is incompatible with the
properties of the clock. See the **DESCRIPTION** section for details of
permissible clock update operations. Otherwise, the version/pointer of
the arguments structure is incorrect.
## See also
- [RFC-0077](/docs/contribute/governance/rfcs/0077_zx_clock_update_accuracy.md)
- [clock transformations]
- [clocks]
- [`zx_clock_create()`]
- [`zx_clock_get_details()`]
- [`zx_clock_read()`]
[clock transformations]: /docs/concepts/kernel/clock_transformations.md
[clocks]: /docs/reference/kernel_objects/clock.md
[`zx_clock_create()`]: clock_create.md
[`zx_clock_get_details()`]: clock_get_details.md
[`zx_clock_read()`]: clock_read.md