blob: 9afb3a2618a23dad98a760bd6777cc31e1bfb620 [file] [log] [blame]
// Copyright 2016 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.
#pragma once
#include <stdint.h>
#include <zircon/compiler.h>
#include <zircon/syscalls.h>
namespace zx {
// TODO(maniscalco): Document these classes.
class duration {
public:
constexpr duration() = default;
explicit constexpr duration(zx_duration_t value)
: value_(value) {}
static constexpr duration infinite() { return duration(ZX_TIME_INFINITE); }
constexpr zx_duration_t get() const { return value_; }
duration operator+(duration other) const {
zx_duration_t x = 0;
if (unlikely(add_overflow(value_, other.value_, &x))) {
if (x >= 0) {
return duration(INT64_MIN);
} else {
return duration(ZX_TIME_INFINITE);
}
}
return duration(x);
}
duration operator-(duration other) const {
zx_duration_t x = 0;
if (unlikely(sub_overflow(value_, other.value_, &x))) {
if (x >= 0) {
return duration(INT64_MIN);
} else {
return duration(ZX_TIME_INFINITE);
}
}
return duration(x);
}
duration operator*(int64_t multiplier) const {
zx_duration_t x = 0;
if (unlikely(mul_overflow(value_, multiplier, &x))) {
if ((value_ > 0 && multiplier > 0) || (value_ < 0 && multiplier < 0)) {
return duration(ZX_TIME_INFINITE);
} else {
return duration(INT64_MIN);
}
}
return duration(x);
}
constexpr duration operator/(int64_t divisor) const {
return duration(value_ / divisor);
}
constexpr duration operator%(duration divisor) const {
return duration(value_ % divisor.value_);
}
constexpr int64_t operator/(duration other) const {
return value_ / other.value_;
}
duration& operator+=(duration other) {
if (unlikely(add_overflow(value_, other.value_, &value_))) {
if (value_ >= 0) {
value_ = INT64_MIN;
} else {
value_ = ZX_TIME_INFINITE;
}
}
return *this;
}
duration& operator-=(duration other) {
if (unlikely(sub_overflow(value_, other.value_, &value_))) {
if (value_ >= 0) {
value_ = INT64_MIN;
} else {
value_ = ZX_TIME_INFINITE;
}
}
return *this;
}
duration& operator*=(int64_t multiplier) {
zx_duration_t x = 0;
if (unlikely(mul_overflow(value_, multiplier, &x))) {
if ((value_ > 0 && multiplier > 0) || (value_ < 0 && multiplier < 0)) {
value_ = ZX_TIME_INFINITE;
return *this;
} else {
value_ = INT64_MIN;
return *this;
}
}
value_ = x;
return *this;
}
duration& operator/=(int64_t divisor) {
value_ /= divisor;
return *this;
}
constexpr bool operator==(duration other) const { return value_ == other.value_; }
constexpr bool operator!=(duration other) const { return value_ != other.value_; }
constexpr bool operator<(duration other) const { return value_ < other.value_; }
constexpr bool operator<=(duration other) const { return value_ <= other.value_; }
constexpr bool operator>(duration other) const { return value_ > other.value_; }
constexpr bool operator>=(duration other) const { return value_ >= other.value_; }
constexpr int64_t to_nsecs() const { return value_; }
constexpr int64_t to_usecs() const { return value_ / ZX_USEC(1); }
constexpr int64_t to_msecs() const { return value_ / ZX_MSEC(1); }
constexpr int64_t to_secs() const { return value_ / ZX_SEC(1); }
constexpr int64_t to_mins() const { return value_ / ZX_MIN(1); }
constexpr int64_t to_hours() const { return value_ / ZX_HOUR(1); }
private:
zx_duration_t value_ = 0;
};
class ticks {
public:
constexpr ticks() = default;
explicit constexpr ticks(zx_ticks_t value) : value_(value) {}
// Constructs a tick object for the current tick counter in the system.
static ticks now() { return ticks(zx_ticks_get()); }
// Returns the number of ticks contained within one second.
static ticks per_second() { return ticks(zx_ticks_per_second()); }
// Acquires the number of ticks contained within this object.
constexpr zx_ticks_t get() const { return value_; }
constexpr ticks operator+(ticks other) const {
return ticks(value_ + other.value_);
}
constexpr ticks operator-(ticks other) const {
return ticks(value_ - other.value_);
}
constexpr ticks operator*(uint64_t multiplier) const {
return ticks(value_ * multiplier);
}
constexpr ticks operator/(uint64_t divisor) const {
return ticks(value_ / divisor);
}
constexpr uint64_t operator/(ticks other) const {
return value_ / other.value_;
}
ticks& operator+=(ticks other) {
value_ += other.value_;
return *this;
}
ticks& operator-=(ticks other) {
value_ -= other.value_;
return *this;
}
ticks& operator*=(uint64_t multiplier) {
value_ *= multiplier;
return *this;
}
ticks& operator/=(uint64_t divisor) {
value_ /= divisor;
return *this;
}
constexpr bool operator==(ticks other) const { return value_ == other.value_; }
constexpr bool operator!=(ticks other) const { return value_ != other.value_; }
constexpr bool operator<(ticks other) const { return value_ < other.value_; }
constexpr bool operator<=(ticks other) const { return value_ <= other.value_; }
constexpr bool operator>(ticks other) const { return value_ > other.value_; }
constexpr bool operator>=(ticks other) const { return value_ >= other.value_; }
private:
zx_ticks_t value_ = 0;
};
class time {
public:
constexpr time() = default;
explicit constexpr time(zx_time_t value)
: value_(value) {}
static constexpr time infinite() { return time(ZX_TIME_INFINITE); }
constexpr zx_time_t get() const { return value_; }
zx_time_t* get_address() { return &value_; }
duration operator-(time other) const {
zx_duration_t x = 0;
if (unlikely(sub_overflow(value_, other.value_, &x))) {
if (x >= 0) {
return duration(INT64_MIN);
} else {
return duration(ZX_TIME_INFINITE);
}
}
return duration(x);
}
time operator+(duration delta) const {
zx_time_t x = 0;
if (unlikely(add_overflow(value_, delta.get(), &x))) {
if (x >= 0) {
return time(INT64_MIN);
} else {
return time(ZX_TIME_INFINITE);
}
}
return time(x);
}
time operator-(duration delta) const {
zx_time_t x = 0;
if (unlikely(sub_overflow(value_, delta.get(), &x))) {
if (x >= 0) {
return time(INT64_MIN);
} else {
return time(ZX_TIME_INFINITE);
}
}
return time(x);
}
time& operator+=(duration delta) {
if (unlikely(add_overflow(value_, delta.get(), &value_))) {
if (value_ >= 0) {
value_ = INT64_MIN;
} else {
value_ = ZX_TIME_INFINITE;
}
}
return *this;
}
time& operator-=(duration delta) {
if (unlikely(sub_overflow(value_, delta.get(), &value_))) {
if (value_ >= 0) {
value_ = INT64_MIN;
} else {
value_ = ZX_TIME_INFINITE;
}
}
return *this;
}
constexpr bool operator==(time other) const { return value_ == other.value_; }
constexpr bool operator!=(time other) const { return value_ != other.value_; }
constexpr bool operator<(time other) const { return value_ < other.value_; }
constexpr bool operator<=(time other) const { return value_ <= other.value_; }
constexpr bool operator>(time other) const { return value_ > other.value_; }
constexpr bool operator>=(time other) const { return value_ >= other.value_; }
private:
zx_time_t value_ = 0;
};
namespace clock {
static inline time get(zx_clock_t clock_id) {
return time(zx_clock_get(clock_id));
}
} // namespace clock
constexpr inline duration nsec(int64_t n) { return duration(ZX_NSEC(n)); }
constexpr inline duration usec(int64_t n) { return duration(ZX_USEC(n)); }
constexpr inline duration msec(int64_t n) { return duration(ZX_MSEC(n)); }
constexpr inline duration sec(int64_t n) { return duration(ZX_SEC(n)); }
constexpr inline duration min(int64_t n) { return duration(ZX_MIN(n)); }
constexpr inline duration hour(int64_t n) { return duration(ZX_HOUR(n)); }
inline zx_status_t nanosleep(zx::time deadline) {
return zx_nanosleep(deadline.get());
}
inline time deadline_after(zx::duration nanoseconds) {
return time(zx_deadline_after(nanoseconds.get()));
}
} // namespace zx