-
-
Notifications
You must be signed in to change notification settings - Fork 170
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement clock_gettime
syscall
#495
Conversation
Making your own std::chrono clock is fairly trivial: #include <3ds.h>
#include <chrono>
#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ratio>
class system_clock
{
public:
using rep = std::uint64_t;
using period = std::milli;
using duration = std::chrono::duration<rep, period>;
using time_point = std::chrono::time_point<system_clock>;
static constexpr bool is_steady = false;
static std::time_t to_time_t(time_point const &t) noexcept
{
return std::time_t(std::chrono::duration_cast<std::chrono::seconds>(now().time_since_epoch()).count());
}
static time_point from_time_t(std::time_t t) noexcept
{
return time_point(duration(t));
}
static time_point now() noexcept
{
// convert 1900-01-01 epoch to unix epoch
return time_point(duration(osGetTime() - 2208988800000ULL));
}
};
class high_resolution_clock
{
public:
using rep = std::uint64_t;
using period = std::ratio<1, SYSCLOCK_ARM11>;
using duration = std::chrono::duration<rep, period>;
using time_point = std::chrono::time_point<high_resolution_clock>;
static constexpr bool is_steady = true;
static time_point now() noexcept
{
return time_point(duration(svcGetSystemTick()));
};
};
using steady_clock = high_resolution_clock;
int main(int argc, char* argv[])
{
auto const start = high_resolution_clock::now();
gfxInitDefault();
consoleInit(GFX_TOP, NULL);
while (aptMainLoop())
{
gspWaitForVBlank();
gfxSwapBuffers();
hidScanInput();
u32 kDown = hidKeysDown();
if (kDown & KEY_START)
break;
if (kDown & KEY_A)
{
auto const now = high_resolution_clock::now();
std::printf("Tick %" PRIu64 ", %lf seconds since start\n",
now.time_since_epoch().count(),
std::chrono::duration<double>(now - start).count());
}
if (kDown & KEY_B)
{
auto const now = system_clock::to_time_t(system_clock::now());
std::printf("%s", std::ctime(&now));
}
}
gfxExit();
return 0;
} |
Thanks for the tip on using a custom implementation, but that seems to me to be the wrong route to take in this case. If we are not interested in implementing Your use of the Overall, I think it's best to just implement the syscalls, as it's the most portable and solves the chrono issue in the same instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately GCC aliases high_resolution_clock to system_clock. If you actually want a high-resolution clock on 3DS with this code then use steady_clock.
f9f4680
to
75473c5
Compare
This implements the syscalls for `clock_gettime` and `clock_getres`. We support two clocks: CLOCK_REALTIME and CLOCK_MONOTONIC. I've opted to use the existing `osGetTime()` code for the realtime clock, because it's known to work. For CLOCK_MONOTONIC I've used `svcGetSystemTick()` directly, as it has a higher resolution. We can ignore the drift and so on, because it's supposed to be just the number of ticks since last boot.
75473c5
to
f933d9e
Compare
Any update on this? |
This implements the syscalls for
clock_gettime
andclock_getres
. Wesupport two clocks: CLOCK_REALTIME and CLOCK_MONOTONIC. I've opted to
use the existing
osGetTime()
code for the realtime clock, because it'sknown to work.
For CLOCK_MONOTONIC I've used
svcGetSystemTick()
directly, as it has ahigher resolution. We can ignore the drift and so on, because it's
supposed to be just the number of ticks since last boot.
Implementing the
clock_gettime
syscall allowsstd::chrono
to work, which is the primary reason I started looking at this.There are two points that I am a bit unsure about:
osGetTimeRef()
function andosTimeRef_s.value_tick
in the monotonic timer? As far as I understand this is just an offset as to when a reference point was set, and is not needed here, but I could be wrong here.Last, I want to thank you for creating such a library so awesome that even beginner like me can explore the 3ds!