mirror of
https://github.com/darlinghq/darling-libkqueue.git
synced 2024-12-03 17:30:43 +00:00
Add NOTE_MACHTIME
support
This is actually used in libdispatch for pretty much all non-wall-clock timers, so as you might imagine, it's used quite frequently and we were processing it incorrectly, leading to stalls in some programs that use such timers for short intervals/deadlines.
This commit is contained in:
parent
599a9e8316
commit
7e2ade452a
@ -16,6 +16,7 @@
|
||||
|
||||
#include "private.h"
|
||||
#include <sys/time.h>
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
#ifndef HAVE_SYS_TIMERFD_H
|
||||
|
||||
@ -94,11 +95,15 @@ static void convert_to_itimerspec(struct itimerspec *dst, uint64_t src, bool one
|
||||
gettimeofday(&now, NULL);
|
||||
}
|
||||
|
||||
// for all these NOTE_ABSOLUTE __builtin_sub_overflow checks:
|
||||
// not sure if we can just use `0` or if that's a special/reserved value, so let's use `1` to be safe
|
||||
|
||||
if (fflags & NOTE_SECONDS)
|
||||
{
|
||||
dbg_printf("...timer is in seconds: %llu\n", src);
|
||||
if (fflags & NOTE_ABSOLUTE)
|
||||
src -= now.tv_sec;
|
||||
if (__builtin_sub_overflow(src, now.tv_sec, &src))
|
||||
src = 1;
|
||||
|
||||
sec = src;
|
||||
nsec = 0;
|
||||
@ -107,7 +112,8 @@ static void convert_to_itimerspec(struct itimerspec *dst, uint64_t src, bool one
|
||||
{
|
||||
dbg_printf("...timer is in useconds: %llu\n", src);
|
||||
if (fflags & NOTE_ABSOLUTE)
|
||||
src -= (now.tv_sec * 1000000ull) + now.tv_usec;
|
||||
if (__builtin_sub_overflow(src, (now.tv_sec * 1000000ull) + now.tv_usec, &src))
|
||||
src = 1;
|
||||
|
||||
sec = src / 1000000;
|
||||
nsec = (src % 1000000) * 1000;
|
||||
@ -116,11 +122,26 @@ static void convert_to_itimerspec(struct itimerspec *dst, uint64_t src, bool one
|
||||
{
|
||||
dbg_printf("...timer is in nseconds: %llu\n", src);
|
||||
if (fflags & NOTE_ABSOLUTE)
|
||||
src -= (now.tv_sec * 1000000000ull) + now.tv_usec*1000;
|
||||
if (__builtin_sub_overflow(src, (now.tv_sec * 1000000000ull) + now.tv_usec*1000, &src))
|
||||
src = 1;
|
||||
|
||||
sec = src / 1000000000;
|
||||
nsec = src % 1000000000;
|
||||
}
|
||||
else if (fflags & NOTE_MACHTIME)
|
||||
{
|
||||
dbg_printf("...timer is in Mach-time-units: %llu\n", src);
|
||||
if (fflags & NOTE_ABSOLUTE)
|
||||
if (__builtin_sub_overflow(src, mach_absolute_time(), &src))
|
||||
src = 1;
|
||||
|
||||
mach_timebase_info_data_t timebase;
|
||||
mach_timebase_info(&timebase);
|
||||
// the timebase info is in nanoseconds
|
||||
uint64_t mach_nsec = (src * timebase.numer) / (timebase.denom);
|
||||
sec = mach_nsec / 1000000000;
|
||||
nsec = mach_nsec % 1000000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_printf("...timer is in mseconds: %llu\n", src);
|
||||
|
Loading…
Reference in New Issue
Block a user