fix(libkernel): read the process start before the clock in process time
sceKernelGetProcessTime and sceKernelGetProcessTimeCounter subtracted GetStartNanos() from GetMonotonicNanos() in one expression. GCC reads the clock first, so on the first call in a process the start was captured after it and the result wrapped to about 2^64. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
73ac9ef7f4
commit
383770ff65
|
|
@ -84,6 +84,16 @@ if(BUILD_TESTING)
|
|||
set_tests_properties(guest_posix_sem_init guest_posix_sem_post PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
|
||||
endif()
|
||||
add_test_executable(guest_process_time_tests ${LIBS_INCLUDE_DIR}/tests/GuestProcessTime.cpp)
|
||||
target_include_directories(guest_process_time_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_process_time_tests PRIVATE libkernel libc)
|
||||
configure_windows_unwind(guest_process_time_tests)
|
||||
add_test(NAME guest_process_time COMMAND guest_process_time_tests)
|
||||
add_test(NAME guest_process_time_counter COMMAND guest_process_time_tests counter)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_process_time guest_process_time_counter PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel>")
|
||||
endif()
|
||||
add_library(guest_module_fixture SHARED ${LIBS_INCLUDE_DIR}/tests/GuestModuleFixture.cpp)
|
||||
target_include_directories(guest_module_fixture PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
add_custom_command(TARGET guest_module_fixture POST_BUILD
|
||||
|
|
|
|||
|
|
@ -147,11 +147,13 @@ static const bool g_timerSelfTest = [] {
|
|||
extern "C" {
|
||||
|
||||
std::uint64_t APS5_VABI sceKernelGetProcessTime() {
|
||||
return (GetMonotonicNanos() - GetStartNanos()) / 1000ULL;
|
||||
const std::uint64_t start = GetStartNanos();
|
||||
return (GetMonotonicNanos() - start) / 1000ULL;
|
||||
}
|
||||
|
||||
std::uint64_t APS5_VABI sceKernelGetProcessTimeCounter() {
|
||||
return GetMonotonicNanos() - GetStartNanos();
|
||||
const std::uint64_t start = GetStartNanos();
|
||||
return GetMonotonicNanos() - start;
|
||||
}
|
||||
|
||||
std::uint64_t APS5_VABI sceKernelGetProcessTimeCounterFrequency() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
#include "prx/libkernel/Time/include/Time.hpp"
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
static void Require(bool condition, const char* message) {
|
||||
if (!condition) {
|
||||
std::fprintf(stderr, "%s\n", message);
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
constexpr std::uint64_t minuteMicros = 60ULL * 1000 * 1000;
|
||||
if (argc > 1 && std::strcmp(argv[1], "counter") == 0) {
|
||||
Require(sceKernelGetProcessTimeCounter() < minuteMicros * 1000, "first process time counter wrapped");
|
||||
return 0;
|
||||
}
|
||||
const std::uint64_t first = sceKernelGetProcessTime();
|
||||
Require(first < minuteMicros, "first process time wrapped");
|
||||
Require(sceKernelGetProcessTime() >= first, "process time went backwards");
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue