1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <zircon/types.h>
8 
9 enum slack_mode : uint32_t {
10     TIMER_SLACK_CENTER, // slack is centered around deadline
11     TIMER_SLACK_LATE,   // slack interval is [deadline, deadline + slack)
12     TIMER_SLACK_EARLY,  // slack interval is (deadline - slack, deadline]
13 };
14 
15 // TimerSlack specifies how much a timer or event is allowed to deviate from its deadline.
16 class TimerSlack {
17 public:
18     // Create a TimerSlack object with the specified |amount| and |mode|.
19     //
20     // |amount| must be >= 0. 0 means "no slack" (i.e. no coalescing is allowed).
TimerSlack(zx_duration_t amount,slack_mode mode)21     constexpr TimerSlack(zx_duration_t amount, slack_mode mode)
22         : amount_(amount), mode_(mode) {
23         DEBUG_ASSERT(amount_ >= 0);
24     }
25 
amount()26     zx_duration_t amount() const { return amount_; }
27 
mode()28     slack_mode mode() const { return mode_; }
29 
30     bool operator==(const TimerSlack& rhs) const {
31         return amount_ == rhs.amount_ &&
32                mode_ == rhs.mode_;
33     }
34 
35     bool operator!=(const TimerSlack& rhs) const {
36         return !operator==(rhs);
37     }
38 
39 private:
40     zx_duration_t amount_;
41     slack_mode mode_;
42 };
43 
44 // TimerSlack is passed by value so make sure it'll fit in two 64-bit registers.
45 static_assert(sizeof(TimerSlack) <= 16);
46 
47 // Used to indicate that a given deadline is not eligible for coalescing.
48 //
49 // Not intended to be used for timers/events that originate on behalf of usermode.
50 static constexpr TimerSlack kNoSlack = TimerSlack(0, TIMER_SLACK_CENTER);
51