ps2dev / ps2sdk

Homebrew PS2 SDK
Other
934 stars 134 forks source link

`TimerBusClock2USec` not reporting microseconds properly #416

Closed jpd002 closed 9 months ago

jpd002 commented 1 year ago

Been toying around with ps2sdk to port a modern C++ project. That one uses steady_clock to count time and I noticed that sometimes, value returned by that would sometimes be smaller than a value returned previously.

I identified the problem to be caused by a bug in TimerBusClock2USec: Seems pUsec is the amount of clocks instead of actual microseconds.

Potentially offending line: https://github.com/ps2dev/ps2sdk/blob/master/ee/kernel/include/timer_alarm.h#L70.

This is used by gettimeofday to fill in the tv_usec member and that causes it to have values outside the [0, 999999] range.

I found that problem last month, so, details are a bit hazy and I could be missing something else. I might try fixing it myself but that might take a long time, so, I just wanted to report it :)

Lemme know if you need more details!

Thanks!

uyjulian commented 1 year ago

A minimum sample test program with examples of incorrect result and expected result would help.

jpd002 commented 1 year ago

Sure, here's a simple program that will eventually fail the assertion:

#include <chrono>
#include <cassert>
#include <cstdio>

int main(int argc, char** argv)
{
    using namespace std;
    using namespace std::chrono;
    auto currTime = steady_clock::now();
    while(1)
    {
        auto newTime = steady_clock::now();
        printf("newTime: %llu\n", static_cast<uint64_t>(newTime.time_since_epoch().count()));
        assert(newTime >= currTime);
        currTime = newTime;
    }
    return 1;
}

Excerpt from output:

...
newTime: 1679545584437568000
newTime: 1679545584440128000
newTime: 1679545584442688000
newTime: 1679545584445504000
newTime: 1679545584448064000
newTime: 1679545584450880000
newTime: 1679545584453440000
newTime: 1679545438000000000
assertion "newTime >= currTime" failed: file "/work/temp/main.cpp", line 14, function: int main(int, char**)

Excepted result is that the assertion will always be valid (especially since this is a steady_clock which should be monotonic).