Skip to content

Commit de21714

Browse files
fix: Trying to fix the accuracy issue of sleep
1 parent a1c9b30 commit de21714

1 file changed

Lines changed: 29 additions & 10 deletions

File tree

src/vibrant/thread.h

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -919,18 +919,37 @@ inline void original::thread::sleep(const time::duration& d)
919919
throw sysError("Failed to sleep thread (clock_nanosleep returned " +
920920
formatString(code) + ", errno: " + formatString(errno) + ").");
921921
#elif ORIGINAL_PLATFORM_MACOS
922-
const timespec ts = d.toTimespec();
923-
timespec rem = ts;
924-
int code;
922+
timespec ts = d.toTimespec();
923+
const integer total_ns = static_cast<integer>(ts.tv_sec) * static_cast<integer>(1000000000) + ts.tv_nsec;
924+
timespec start {};
925+
timespec now {};
926+
clock_gettime(CLOCK_MONOTONIC, &start);
927+
928+
integer target_ns = static_cast<integer>(start.tv_sec) * static_cast<integer>(1000000000) +
929+
static_cast<integer>(start.tv_nsec) + total_ns;
930+
while (true)
931+
{
932+
clock_gettime(CLOCK_MONOTONIC, &now);
925933

926-
do {
927-
errno = 0;
928-
code = nanosleep(&rem, &rem);
929-
} while (code == -1 && errno == EINTR);
934+
integer now_ns = static_cast<integer>(now.tv_sec) * static_cast<integer>(1000000000) +
935+
static_cast<integer>(now.tv_nsec);
930936

931-
if (code != 0)
932-
throw sysError("Failed to sleep thread (nanosleep returned " +
933-
formatString(code) + ", errno: " + formatString(errno) + ").");
937+
if (now_ns >= target_ns)
938+
return;
939+
940+
integer remaining = target_ns - now_ns;
941+
942+
timespec req;
943+
req.tv_sec = remaining / static_cast<integer>(1000000000);
944+
req.tv_nsec = remaining % static_cast<integer>(1000000000);
945+
946+
int ret = nanosleep(&req, nullptr);
947+
948+
if (ret == 0)
949+
return;
950+
if (errno != EINTR)
951+
return;
952+
}
934953
#elif ORIGINAL_PLATFORM_WINDOWS
935954

936955
Sleep(d.toDWMilliseconds());

0 commit comments

Comments
 (0)