1#include <cstdlib>
2#include <limits>
3
4#ifdef NNSDK
5#include <nn/os.h>
6#endif
7
8#include <time/seadTickSpan.h>
9
10namespace sead
11{
12#ifdef NNSDK
13const s64 TickSpan::cFrequency = nn::os::GetSystemTickFrequency();
14#else
15#error "Unknown platform"
16#endif
17
18s64 TickSpan::toNanoSeconds() const
19{
20 const s64 abs_span = std::abs(x: mSpan);
21 const s64 max = std::numeric_limits<s64>::max();
22
23 // Try to get as much precision as possible without overflowing.
24
25 if (abs_span < max / 1'000'000'000)
26 return 1'000'000'000 * mSpan / cFrequency;
27
28 if (abs_span < max / 1'000'000)
29 return 1000 * (1'000'000 * mSpan / cFrequency);
30
31 if (abs_span < max / 1000)
32 return 1'000'000 * (1000 * mSpan / cFrequency);
33
34 return 1'000'000'000 * (mSpan / cFrequency);
35}
36
37void TickSpan::setNanoSeconds(s64 nsec)
38{
39 const s64 threshold = std::numeric_limits<s64>::max() / cFrequency;
40 const s64 abs_ns = std::abs(x: nsec);
41
42 if (abs_ns <= threshold)
43 mSpan = cFrequency * nsec / 1'000'000'000;
44 else if (abs_ns <= 1000 * threshold)
45 mSpan = cFrequency * (nsec / 1000) / 1'000'000;
46 else if (abs_ns <= 1'000'000 * threshold)
47 mSpan = cFrequency * (nsec / 1'000'000) / 1000;
48 else
49 mSpan = cFrequency * (nsec / 1'000'000'000);
50}
51
52} // namespace sead
53