zx_clock_update

摘要

调整时钟对象。

声明

#include <zircon/syscalls.h>

zx_status_t zx_clock_update(zx_handle_t handle,
                            uint64_t options,
                            const void* args);

权限

handle 的类型必须为 ZX_OBJ_TYPE_CLOCK 且包含 ZX_RIGHT_WRITE

说明

时钟维护人员可以动态控制三个不同的参数。 它们分别是

  • 时钟的当前值。
  • 时钟的速率调整,以 PPM 与标称的偏差表示。
  • 时钟的当前估计错误边界。

当时钟维护人员希望更改上述一个或多个参数时, 可以使用 zx_clock_update 系统调用来实现。更新时钟的参数是 从系统中所有其他用户的角度来看,这是原子操作。

时钟维护人员执行的第一个更新操作必须包含一个有效的 值。此更新是启动时钟并定义其初始 值。在此更新操作成功之前,ZX_CLOCK_STARTED 信号将被取消断言,此后,该信号被断言,并持续 整个时钟的生命周期

要更新时钟,用户需要填写 zx_clock_update_args_v2_t 结构,然后传递 结构添加到更新调用,设置 options 中的位,指示 结构的显式版本(第 2 版),以及其中哪些字段 有效值,且应设置。定义的 options 位为

  • 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

结构的版本使用 ZX_CLOCK_ARGS_VERSION(...) 传递 宏,特别是对于版本 2 结构,请使用 ZX_CLOCK_ARGS_VERSION(2)

例如:

#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;
  }
}

明确提供的引用时间。

添加 V2 更新结构后,现在是可能实现的( 限制),以显式控制用于时钟更新的参考时间 操作。请注意,如果请求成功,则实际的新引用 <->合成 由用户的更新参数指定的转换将替换旧转换 转换。zx_clock_update提供显式 参考时间不会影响实际转换的更新时间, 在调用 zx_clock_update 期间始终生效。

提供的图表 RFC-0077 可能有助于了解下述操作的影响。

合成值使用明确提供的参考时间进行更新。

当用户使用显式声明更新时钟的合成值 (S) 时 它们通过提供的参考时间 (R) 来指定相应的时间点 ([R, S]), 新转换将通过哪个值。换句话说,新转换 明确指定“当参考时间轴上的时间 R 时, 是合成时间轴上的时间 S”。

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

价格调整会根据明确提供的参考时间进行更新。

T(R) 成为将引用时间 R 转换为合成时间的函数 更新操作前的时钟时间。当用户调整某个广告的费率时 具有明确提供的参考时间 (R) 的时钟,则用于指定 时钟新转换 T'(R) 的斜率,以便 T'(R) = T(R)。 换句话说,在参考时间 R,新转换将通过 合成时间与旧转换相同,但不同 斜率。

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

备注、规则和限制。

  • 显式引用值不是必需的。您仍然可以忽略 更新操作期间的引用值。更新操作将 只需在处理操作时使用当前参考时间即可。
  • 为时钟更新操作提供显式引用值时, 综合值和/或费率调整值都必须是 。试图仅在 显式引用值。
  • 显式提供一个对更新操作的引用值, 因为这几乎总是意味着不连续。
  • 明确为单调更新操作提供引用值 允许时钟,但在时钟行为保持单调时允许 。
  • 更新操作期间明确提供的引用值, 会导致在参考时间“now”执行读取违反配置 时钟的退避时间会导致操作被拒绝。
  • 更新单调时钟时,不能同时影响 综合值更新和费率调整。

详情请参阅 RFC-0077 可能有助于理解其中一些规则和限制背后的推理过程。

返回值

成功后返回 ZX_OK

错误

  • ZX_ERR_BAD_HANDLEhandle 是无效句柄或 不是 ZX_OBJ_TYPE_CLOCK 的对象类型。
  • ZX_ERR_ACCESS_DENIEDhandle 缺少 ZX_RIGHT_WRITE 右侧。
  • ZX_ERR_INVALID_ARGS:所做的更新请求与 时钟的属性。如需了解详情,请参阅 DESCRIPTION 部分 允许的时钟更新操作。否则, 参数结构不正确。

另请参阅