mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-02 12:56:05 +00:00
kern_clock_nanosleep limits the sleep to INT32_MAX / 2 seconds and sleeps for that long (sys/kern/kern_time.c:543-547). The guest multiplied tv_sec by 1e9 in 64 bits, so a request of 18446744074 seconds or more wrapped to a short sleep: nanosleep with tv_sec = INT64_MAX returned after about 0.1 s. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
59 lines
1.9 KiB
C++
59 lines
1.9 KiB
C++
#include "SceTypes.hpp"
|
|
#include "prx/libkernel/Pthread/include/Pthread.hpp"
|
|
#include <atomic>
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <source_location>
|
|
#include <thread>
|
|
|
|
extern "C" {
|
|
int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, PthreadEntry entry, void* arg, const char* name);
|
|
int APS5_VABI nanosleep_nid_postfix(const KernelTimespec* rqtp, KernelTimespec* rmtp);
|
|
int APS5_VABI sceKernelNanosleep(const KernelTimespec* rqtp, KernelTimespec* rmtp);
|
|
}
|
|
|
|
static void Require(bool value, std::source_location location = std::source_location::current()) {
|
|
if (value) return;
|
|
std::fprintf(stderr, "%s:%u: requirement failed\n", location.file_name(), location.line());
|
|
std::abort();
|
|
}
|
|
|
|
static constexpr auto ObservationTime = std::chrono::milliseconds(1500);
|
|
static std::atomic<bool> started{false};
|
|
static std::atomic<bool> returned{false};
|
|
static std::int64_t requestedSeconds = 0;
|
|
static bool posix = true;
|
|
|
|
static void* APS5_VABI Sleeper(void*) {
|
|
const KernelTimespec request{requestedSeconds, 0};
|
|
started.store(true);
|
|
if (posix) nanosleep_nid_postfix(&request, nullptr);
|
|
else sceKernelNanosleep(&request, nullptr);
|
|
returned.store(true);
|
|
return nullptr;
|
|
}
|
|
|
|
static void SleepsPastTheObservation(std::int64_t seconds, bool usePosix) {
|
|
started.store(false);
|
|
returned.store(false);
|
|
requestedSeconds = seconds;
|
|
posix = usePosix;
|
|
Pthread thread = nullptr;
|
|
Require(scePthreadCreate(&thread, nullptr, Sleeper, nullptr, nullptr) == 0);
|
|
while (!started.load()) std::this_thread::yield();
|
|
std::this_thread::sleep_for(ObservationTime);
|
|
Require(!returned.load());
|
|
}
|
|
|
|
int main() {
|
|
for (const bool usePosix : {true, false}) {
|
|
SleepsPastTheObservation(INT64_MAX, usePosix);
|
|
SleepsPastTheObservation(18446744074LL, usePosix);
|
|
SleepsPastTheObservation(std::int64_t{1} << 40, usePosix);
|
|
}
|
|
std::fflush(nullptr);
|
|
std::_Exit(0);
|
|
}
|