diff --git a/src/common/threads.cpp b/src/common/threads.cpp index db3f285fc..fa5e28e48 100644 --- a/src/common/threads.cpp +++ b/src/common/threads.cpp @@ -2,7 +2,6 @@ #include "common/assert.h" -#include #include #include #include // IWYU pragma: keep @@ -26,8 +25,7 @@ #ifdef KYTY_WIN_CS #include // IWYU pragma: keep // IWYU pragma: no_include -constexpr DWORD KYTY_CS_SPIN_COUNT = 4000; -constexpr uint64_t KYTY_SLEEP_SPIN_LIMIT_100NS = 500; // 50 us +constexpr DWORD KYTY_CS_SPIN_COUNT = 4000; #ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION #define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002 @@ -38,30 +36,6 @@ static void SleepHighResolution100ns(uint64_t units_100ns) { return; } - // Keep spinning only where a kernel transition is - // likely to cost more than the requested delay; ordinary millisecond sleeps use the - // per-thread high-resolution waitable timer below. - if (units_100ns <= KYTY_SLEEP_SPIN_LIMIT_100NS) { - LARGE_INTEGER frequency {}; - LARGE_INTEGER start {}; - if (QueryPerformanceFrequency(&frequency) != 0 && QueryPerformanceCounter(&start) != 0 && - frequency.QuadPart > 0) { - const auto wait_ticks = - static_cast((static_cast(units_100ns) * - static_cast(frequency.QuadPart)) / - 10000000.0L); - const auto deadline = start.QuadPart + std::max(wait_ticks, 1); - LARGE_INTEGER now {}; - do { - if (QueryPerformanceCounter(&now) == 0) { - break; - } - YieldProcessor(); - } while (now.QuadPart < deadline); - return; - } - } - thread_local HANDLE timer = CreateWaitableTimerExW( nullptr, nullptr, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS); if (timer == nullptr) { @@ -131,14 +105,13 @@ static SleepConditionVariableCS_func_t ResolveSleepConditionVariableCS() { #endif #ifdef KYTY_POSIX_HIGH_RES_SLEEP -// Spin for very short waits; use an absolute deadline for longer waits. +// An absolute deadline preserves the requested sleep across signal interruptions. static void SleepHighResolutionNanos(uint64_t nanos) { if (nanos == 0) { return; } constexpr uint64_t NANOS_PER_SEC = 1000000000; - constexpr uint64_t SPIN_LIMIT_NS = 50000; // below this a context switch dominates timespec deadline {}; if (clock_gettime(CLOCK_MONOTONIC, &deadline) != 0) { @@ -150,17 +123,6 @@ static void SleepHighResolutionNanos(uint64_t nanos) { deadline.tv_sec += static_cast(target_nsec / NANOS_PER_SEC); deadline.tv_nsec = static_cast(target_nsec % NANOS_PER_SEC); - if (nanos <= SPIN_LIMIT_NS) { - timespec now {}; - do { - if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) { - return; - } - } while (now.tv_sec < deadline.tv_sec || - (now.tv_sec == deadline.tv_sec && now.tv_nsec < deadline.tv_nsec)); - return; - } - while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, nullptr) == EINTR) { } } diff --git a/src/kernel/pthread.cpp b/src/kernel/pthread.cpp index 1c3dd849a..2e2b0a9a9 100644 --- a/src/kernel/pthread.cpp +++ b/src/kernel/pthread.cpp @@ -512,15 +512,6 @@ static void SchedulerBackoffOnce() { #endif } -static bool SleepMicroSchedulerBackoff(uint64_t microseconds) { - if (microseconds > 1) { - return false; - } - - SchedulerBackoffOnce(); - return true; -} - static void SleepMicroWithSignalPoll(uint64_t microseconds) { if (microseconds == 0) { KernelDispatchPendingSignalForCurrentThread(); @@ -529,9 +520,7 @@ static void SleepMicroWithSignalPoll(uint64_t microseconds) { while (microseconds > 0) { const auto step = std::min(microseconds, SIGNAL_APC_POLL_MICROS); - if (!SleepMicroSchedulerBackoff(step)) { - Common::Thread::SleepMicro(step); - } + Common::Thread::SleepMicro(step); microseconds -= step; KernelDispatchPendingSignalForCurrentThread(); } @@ -3842,28 +3831,16 @@ void KYTY_SYSV_ABI KernelSetThreadDtors(thread_dtors_func_t dtors) { } int KYTY_SYSV_ABI KernelUsleep(KernelUseconds microseconds) { - Common::Timer t; - t.Start(); SleepMicroWithSignalPoll(microseconds); - // double ts = t.GetTimeS(); - // LOGF("\tactual: %g microseconds\n", ts * 1000000.0); return OK; } unsigned int KYTY_SYSV_ABI KernelSleep(unsigned int seconds) { - PRINT_NAME(); - LOGF("\tsleep: %u\n", seconds); - Common::Timer t; - t.Start(); SleepMicroWithSignalPoll(static_cast(seconds) * 1000000ull); - double ts = t.GetTimeS(); - LOGF("\tactual: %g seconds\n", ts); return OK; } int KYTY_SYSV_ABI KernelNanosleep(const KernelTimespec* rqtp, KernelTimespec* rmtp) { - PRINT_NAME(); - if (rqtp == nullptr) { return KERNEL_ERROR_EFAULT; } @@ -3880,13 +3857,7 @@ int KYTY_SYSV_ABI KernelNanosleep(const KernelTimespec* rqtp, KernelTimespec* rm uint64_t nanos = static_cast(rqtp->tv_sec) * 1000000000ull + static_cast(rqtp->tv_nsec); - LOGF("\tnanosleep: %" PRIu64 "\n", nanos); - - Common::Timer t; - t.Start(); SleepNanoWithSignalPoll(nanos); - double ts = t.GetTimeS(); - LOGF("\tactual: %g nanoseconds\n", ts * 1000000000.0); if (rmtp != nullptr) { rmtp->tv_sec = 0;