blob: 56c545d94d4ae6bc6497acc894147cf997d8e0a8 [file] [edit]
// Copyright 2019 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#ifndef ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_CLOCK_DISPATCHER_H_
#define ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_CLOCK_DISPATCHER_H_
#include <lib/fasttime/clock.h>
#include <lib/page/size.h>
#include <sys/types.h>
#include <zircon/rights.h>
#include <zircon/syscalls/clock.h>
#include <zircon/types.h>
#include <object/dispatcher.h>
#include <object/handle.h>
namespace internal {
struct FuchsiaKernelOsal;
}
class ClockDispatcher final : public SoloDispatcher<ClockDispatcher, ZX_DEFAULT_CLOCK_RIGHTS> {
public:
static inline constexpr uint64_t kMappedSize = kPageSize;
static zx_status_t Create(uint64_t options, const zx_clock_create_args_v1_t& create_args,
KernelHandle<ClockDispatcher>* handle, zx_rights_t* rights);
~ClockDispatcher() final;
zx_obj_type_t get_type() const final { return ZX_OBJ_TYPE_CLOCK; }
[[nodiscard]] zx_status_t get_name(char (&out_name)[ZX_MAX_NAME_LEN]) const final;
[[nodiscard]] zx_status_t set_name(const char* name, size_t len) final;
zx_status_t Read(zx_time_t* out_now);
zx_status_t GetDetails(zx_clock_details_v1_t* out_details);
template <typename UpdateArgsType>
zx_status_t Update(uint64_t options, const UpdateArgsType& args);
const fbl::RefPtr<VmObjectPaged>& vmo() { return vmo_; }
bool is_mappable() const { return clock_transformation_->is_mappable(); }
private:
ClockDispatcher(uint64_t options, zx_time_t backstop_time, fbl::RefPtr<VmObjectPaged> vmo);
// Supply the kernel specific implementation of ArchYield and reference timer
// accessors in order to use libfasttime's implementation of the
// ClockTransformation class.
struct ClockTransformationAdapter {
static inline void ArchYield() { arch::Yield(); }
static zx_instant_mono_ticks_t GetMonoTicks() { return current_mono_ticks(); }
static zx_instant_boot_ticks_t GetBootTicks() { return current_boot_ticks(); }
};
static zx_time_t GetCurrentTime(bool boot_time) {
return boot_time ? current_boot_time() : current_mono_time();
}
using ClockTransformationType = ::fasttime::ClockTransformation<ClockTransformationAdapter>;
static_assert(sizeof(ClockTransformationType) <= kMappedSize);
static_assert(alignof(ClockTransformationType) <= kMappedSize);
alignas(ClockTransformationType) uint8_t local_storage_[sizeof(ClockTransformationType)];
const fbl::RefPtr<VmObjectPaged> vmo_;
ClockTransformationType* clock_transformation_{nullptr};
fbl::Name<ZX_MAX_NAME_LEN> name_;
};
#endif // ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_CLOCK_DISPATCHER_H_