@@ -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