From: Junio C Hamano Date: Tue, 19 May 2026 23:50:44 GMT Subject: Re: [PATCH 3/9] wrapper: add sleep_nanosec Message-ID: <87qzn7q7qj.fsf@gitster.g> In-Reply-To: <6a8c2093643a385641ef0b2cde33839dc98d8678.1779207350.git.siddh.raman.pant@oracle.com> Siddh Raman Pant writes: > Signed-off-by: Siddh Raman Pant > --- The space above the signed-off-by line should be utilized to explain why we want this change. For the purpose of this series, why do we want to sleep at nanosecond precision? > wrapper.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ > wrapper.h | 1 + > 2 files changed, 50 insertions(+) > > diff --git a/wrapper.c b/wrapper.c > index 16f5a63fbb61..1349255f1eb4 100644 > --- a/wrapper.c > +++ b/wrapper.c > @@ -10,6 +10,7 @@ > #include "gettext.h" > #include "strbuf.h" > #include "trace2.h" > +#include > > #ifdef HAVE_RTLGENRANDOM > /* This is required to get access to RtlGenRandom. */ > @@ -708,6 +709,54 @@ void sleep_millisec(int millisec) > poll(NULL, 0, millisec); > } > > +#ifdef GIT_WINDOWS_NATIVE > +/* No nanosleep() on Windows, so fall-back to using sleep_millisec(). */ > +int sleep_nanosec(uint64_t nanosec) > +{ > + uint64_t ns_in_1ms = 1000000ULL; /* 1 ms = 10^6 ns */ > + > + uint64_t millisec = nanosec / ns_in_1ms; > + if (nanosec % ns_in_1ms) > + millisec++; > + > + /* Chunked sleep if we can't represent in integer. */ > + while (millisec > INT_MAX) { > + sleep_millisec(INT_MAX); > + millisec -= INT_MAX; > + } > + > + sleep_millisec((int)millisec); > + > + return 0; > +} > +#else > +/* Not Windows, so use the more exact nanosleep(). */ > +int sleep_nanosec(uint64_t nanosec) > +{ > + int ret; > + struct timespec duration, remaining; > + > + /* Construct the duration by dividing the given total (1s = 10^9ns). */ > + duration.tv_sec = nanosec / 1000000000ULL; > + duration.tv_nsec = nanosec % 1000000000ULL; > + > + while(1) { > + ret = nanosleep(&duration, &remaining); > + > + /* Continue sleeping if interrupted. */ > + if (ret == -1 && errno == EINTR) { > + duration = remaining; > + continue; > + } > + > + /* Either success or an error. */ > + break; > + } > + > + return ret; > +} > +#endif /* GIT_WINDOWS_NATIVE */ > + > int xgethostname(char *buf, size_t len) > { > /* > diff --git a/wrapper.h b/wrapper.h > index 15ac3bab6e97..c39992893a81 100644 > --- a/wrapper.h > +++ b/wrapper.h > @@ -130,6 +130,7 @@ int warn_on_fopen_errors(const char *path); > int open_nofollow(const char *path, int flags); > > void sleep_millisec(int millisec); > +int sleep_nanosec(uint64_t nanosec); > > enum { > /*