openMSX
EmuDuration.hh
Go to the documentation of this file.
1 #ifndef EMUDURATION_HH
2 #define EMUDURATION_HH
3 
4 #include "serialize.hh"
5 #include <cassert>
6 #include <cstdint>
7 #include <limits>
8 #include <type_traits>
9 
10 namespace openmsx {
11 
12 // constants
13 constexpr uint64_t MAIN_FREQ = 3579545ULL * 960;
14 constexpr unsigned MAIN_FREQ32 = MAIN_FREQ;
15 static_assert(MAIN_FREQ < (1ull << 32), "must fit in 32 bit");
16 
17 
19 {
20 public:
21  // This is only a very small class (one 64-bit member). On 64-bit CPUs
22  // it's cheaper to pass this by value. On 32-bit CPUs pass-by-reference
23  // is cheaper.
24 #ifdef __x86_64
25  using param = const EmuDuration;
26 #else
27  using param = const EmuDuration&;
28 #endif
29 
30  // friends
31  friend class EmuTime;
32 
33  // constructors
34  constexpr EmuDuration() = default;
35  constexpr explicit EmuDuration(uint64_t n) : time(n) {}
36  constexpr explicit EmuDuration(double duration)
37  : time(uint64_t(duration * MAIN_FREQ)) {}
38 
39  static constexpr EmuDuration sec(unsigned x)
40  { return EmuDuration(x * MAIN_FREQ); }
41  static constexpr EmuDuration msec(unsigned x)
42  { return EmuDuration(x * MAIN_FREQ / 1000); }
43  static constexpr EmuDuration usec(unsigned x)
44  { return EmuDuration(x * MAIN_FREQ / 1000000); }
45  static constexpr EmuDuration hz(unsigned x)
46  { return EmuDuration(MAIN_FREQ / x); }
47 
48  // conversions
49  constexpr double toDouble() const { return double(time) / MAIN_FREQ32; }
50  constexpr uint64_t length() const { return time; }
51 
52  // comparison operators
53  constexpr bool operator==(EmuDuration::param d) const
54  { return time == d.time; }
55  constexpr bool operator!=(EmuDuration::param d) const
56  { return time != d.time; }
57  constexpr bool operator< (EmuDuration::param d) const
58  { return time < d.time; }
59  constexpr bool operator<=(EmuDuration::param d) const
60  { return time <= d.time; }
61  constexpr bool operator> (EmuDuration::param d) const
62  { return time > d.time; }
63  constexpr bool operator>=(EmuDuration::param d) const
64  { return time >= d.time; }
65 
66  // arithmetic operators
68  { return EmuDuration(time % d.time); }
70  { return EmuDuration(time + d.time); }
71  constexpr EmuDuration operator*(unsigned fact) const
72  { return EmuDuration(time * fact); }
73  constexpr EmuDuration operator/(unsigned fact) const
74  { return EmuDuration(time / fact); }
75  constexpr EmuDuration divRoundUp(unsigned fact) const
76  { return EmuDuration((time + fact - 1) / fact); }
77  constexpr unsigned operator/(EmuDuration::param d) const
78  {
79  uint64_t result = time / d.time;
80 #ifdef DEBUG
81  // we don't even want this overhead in devel builds
82  assert(result == unsigned(result));
83 #endif
84  return unsigned(result);
85  }
86  constexpr unsigned divUp(EmuDuration::param d) const {
87  uint64_t result = (time + d.time - 1) / d.time;
88 #ifdef DEBUG
89  assert(result == unsigned(result));
90 #endif
91  return unsigned(result);
92  }
93  constexpr double div(EmuDuration::param d) const
94  { return double(time) / d.time; }
95 
96  constexpr EmuDuration& operator*=(unsigned fact)
97  { time *= fact; return *this; }
98  constexpr EmuDuration& operator*=(double fact)
99  { time = uint64_t(time * fact); return *this; }
100  constexpr EmuDuration& operator/=(double fact)
101  { time = uint64_t(time / fact); return *this; }
102 
103  // ticks
104  // TODO: Used in WavAudioInput. Keep or use DynamicClock instead?
105  constexpr unsigned getTicksAt(unsigned freq) const
106  {
107  uint64_t result = time / (MAIN_FREQ32 / freq);
108 #ifdef DEBUG
109  // we don't even want this overhead in devel builds
110  assert(result == unsigned(result));
111 #endif
112  return unsigned(result);
113  }
114 
115  static constexpr EmuDuration zero()
116  {
117  return EmuDuration(uint64_t(0));
118  }
119 
120  static constexpr EmuDuration infinity()
121  {
123  }
124 
125  template<typename Archive>
126  void serialize(Archive& ar, unsigned /*version*/)
127  {
128  ar.serialize("time", time);
129  }
130 
131 private:
132  uint64_t time = 0;
133 };
134 
135 template<> struct SerializeAsMemcpy<EmuDuration> : std::true_type {};
136 
137 
138 template<typename T> class EmuDurationCompactStorage
139 {
140 public:
142  : time(T(e.length()))
143  {
144  assert(e.length() <= std::numeric_limits<T>::max());
145  }
146 
147  constexpr operator EmuDuration() const
148  {
149  return EmuDuration(uint64_t(time));
150  }
151 private:
152  T time;
153 };
154 
158 
159 namespace detail {
160  // via intermediate variable to work around gcc-10 warning
161  inline constexpr uint64_t max32 = std::numeric_limits<uint32_t>::max();
162  inline constexpr uint64_t max16 = std::numeric_limits<uint16_t>::max();
163  inline constexpr uint64_t max8 = std::numeric_limits<uint8_t >::max();
164 }
165 template<uint64_t MAX>
166 using EmuDurationStorageFor = std::conditional_t<(MAX > detail::max32), EmuDuration,
167  std::conditional_t<(MAX > detail::max16), EmuDuration32,
168  std::conditional_t<(MAX > detail::max8 ), EmuDuration16,
169  EmuDuration8>>>;
170 } // namespace openmsx
171 
172 #endif
openmsx::EmuDuration32
EmuDurationCompactStorage< uint32_t > EmuDuration32
Definition: EmuDuration.hh:155
openmsx::EmuDuration::operator<=
constexpr bool operator<=(EmuDuration::param d) const
Definition: EmuDuration.hh:59
openmsx::EmuDuration::operator/
constexpr unsigned operator/(EmuDuration::param d) const
Definition: EmuDuration.hh:77
serialize.hh
openmsx::EmuDuration::serialize
void serialize(Archive &ar, unsigned)
Definition: EmuDuration.hh:126
openmsx::EmuDuration
Definition: EmuDuration.hh:19
openmsx::EmuDuration::infinity
static constexpr EmuDuration infinity()
Definition: EmuDuration.hh:120
openmsx::EmuDuration::operator/
constexpr EmuDuration operator/(unsigned fact) const
Definition: EmuDuration.hh:73
openmsx::MAIN_FREQ32
constexpr unsigned MAIN_FREQ32
Definition: EmuDuration.hh:14
openmsx::EmuDuration::operator*=
constexpr EmuDuration & operator*=(double fact)
Definition: EmuDuration.hh:98
gl::length
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:348
detail
Definition: join.hh:10
openmsx::EmuDuration::toDouble
constexpr double toDouble() const
Definition: EmuDuration.hh:49
openmsx::EmuDuration::length
constexpr uint64_t length() const
Definition: EmuDuration.hh:50
openmsx::EmuDurationCompactStorage
Definition: EmuDuration.hh:139
openmsx::detail::max16
constexpr uint64_t max16
Definition: EmuDuration.hh:162
openmsx::EmuDuration::operator<
constexpr bool operator<(EmuDuration::param d) const
Definition: EmuDuration.hh:57
openmsx::EmuDuration::div
constexpr double div(EmuDuration::param d) const
Definition: EmuDuration.hh:93
openmsx::EmuDuration::EmuDuration
constexpr EmuDuration()=default
openmsx::EmuDuration::operator!=
constexpr bool operator!=(EmuDuration::param d) const
Definition: EmuDuration.hh:55
openmsx::EmuDuration::EmuDuration
constexpr EmuDuration(double duration)
Definition: EmuDuration.hh:36
openmsx::EmuDurationCompactStorage::EmuDurationCompactStorage
constexpr EmuDurationCompactStorage(EmuDuration e)
Definition: EmuDuration.hh:141
openmsx::EmuDuration::operator+
constexpr EmuDuration operator+(EmuDuration::param d) const
Definition: EmuDuration.hh:69
openmsx::EmuDuration::operator>
constexpr bool operator>(EmuDuration::param d) const
Definition: EmuDuration.hh:61
openmsx::EmuDuration::getTicksAt
constexpr unsigned getTicksAt(unsigned freq) const
Definition: EmuDuration.hh:105
openmsx::detail::max32
constexpr uint64_t max32
Definition: EmuDuration.hh:161
openmsx::EmuDuration::operator/=
constexpr EmuDuration & operator/=(double fact)
Definition: EmuDuration.hh:100
openmsx::EmuDuration::operator%
constexpr EmuDuration operator%(EmuDuration::param d) const
Definition: EmuDuration.hh:67
openmsx::detail::max8
constexpr uint64_t max8
Definition: EmuDuration.hh:163
openmsx::EmuDuration::divUp
constexpr unsigned divUp(EmuDuration::param d) const
Definition: EmuDuration.hh:86
openmsx::EmuDuration::divRoundUp
constexpr EmuDuration divRoundUp(unsigned fact) const
Definition: EmuDuration.hh:75
openmsx::EmuDuration::hz
static constexpr EmuDuration hz(unsigned x)
Definition: EmuDuration.hh:45
openmsx::x
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:1419
openmsx::EmuDuration::operator>=
constexpr bool operator>=(EmuDuration::param d) const
Definition: EmuDuration.hh:63
openmsx::EmuDuration::sec
static constexpr EmuDuration sec(unsigned x)
Definition: EmuDuration.hh:39
openmsx::SerializeAsMemcpy
Definition: serialize.hh:617
openmsx::EmuDuration::msec
static constexpr EmuDuration msec(unsigned x)
Definition: EmuDuration.hh:41
openmsx::EmuDuration::operator==
constexpr bool operator==(EmuDuration::param d) const
Definition: EmuDuration.hh:53
gl::max
vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:292
openmsx::MAIN_FREQ
constexpr uint64_t MAIN_FREQ
Definition: EmuDuration.hh:13
openmsx::EmuDuration::usec
static constexpr EmuDuration usec(unsigned x)
Definition: EmuDuration.hh:43
openmsx::EmuDuration::EmuDuration
constexpr EmuDuration(uint64_t n)
Definition: EmuDuration.hh:35
openmsx::EmuDuration::operator*
constexpr EmuDuration operator*(unsigned fact) const
Definition: EmuDuration.hh:71
openmsx::EmuDurationStorageFor
std::conditional_t<(MAX > detail::max32), EmuDuration, std::conditional_t<(MAX > detail::max16), EmuDuration32, std::conditional_t<(MAX > detail::max8), EmuDuration16, EmuDuration8 > >> EmuDurationStorageFor
Definition: EmuDuration.hh:169
openmsx::EmuDuration::EmuTime
friend class EmuTime
Definition: EmuDuration.hh:31
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
openmsx::EmuDuration::zero
static constexpr EmuDuration zero()
Definition: EmuDuration.hh:115
openmsx::EmuDuration::operator*=
constexpr EmuDuration & operator*=(unsigned fact)
Definition: EmuDuration.hh:96