diff --git a/os/linux_base.h b/os/linux_base.h index 971d85e00..f68ffc3ff 100644 --- a/os/linux_base.h +++ b/os/linux_base.h @@ -20,6 +20,7 @@ #define __OS_LINUX_BASE__ // #include +#include // marker for hacks we have made to make progress #define __LINUX_PORT_HDD__ 1 @@ -76,34 +77,41 @@ struct voucher_offsets_s { }; +// Print a warning when an unported code path executes. +#define LINUX_PORT_ERROR() do { printf("LINUX_PORT_ERROR_CALLED %s:%d: %s\n",__FILE__,__LINE__,__FUNCTION__); } while (0) + /* * Stub out defines for other missing types */ -// Pulled from OS X man page for kevent -struct kevent64_s { - uint64_t ident; /* identifier for this event */ - int16_t filter; /* filter for event */ - uint16_t flags; /* general flags */ - uint32_t fflags; /* filter-specific flags */ - int64_t data; /* filter-specific data */ - uint64_t udata; /* opaque user data identifier */ - uint64_t ext[2]; /* filter-specific extensions */ -}; - +#if __linux__ +// we fall back to use kevent +#define kevent64_s kevent +#define kevent64(kq,cl,nc,el,ne,f,to) kevent(kq,cl,nc,el,ne,to) +#endif -// PAGE_SIZE and SIZE_T_MAX should not be hardcoded like this here. -#define PAGE_SIZE (4096) +// SIZE_T_MAX should not be hardcoded like this here. #define SIZE_T_MAX (0x7fffffff) // Define to 0 the NOTE_ values that are not present on Linux. // Revisit this...would it be better to ifdef out the uses instead?? -#define NOTE_VM_PRESSURE 0 -#define NOTE_ABSOLUTE 0 -#define NOTE_NSECONDS 0 -#define NOTE_LEEWAY 0 -#define NOTE_CRITICAL 0 -#define NOTE_BACKGROUND 0 + +// The following values are passed as part of the EVFILT_TIMER requests + +#define IGNORE_KEVENT64_EXT /* will force the kevent64_s.ext[] to not be used -> leeway ignored */ + +#define NOTE_SECONDS 0x01 +#define NOTE_USECONDS 0x02 +#define NOTE_NSECONDS 0x04 +#define NOTE_ABSOLUTE 0x08 +#define NOTE_CRITICAL 0x10 +#define NOTE_BACKGROUND 0x20 +#define NOTE_LEEWAY 0x40 + +// need to catch the following usage if it happens .. +// we simply return '0' as a value probably not correct + +#define NOTE_VM_PRESSURE ({LINUX_PORT_ERROR(); 0;}) /* * Stub out misc linking and compilation attributes @@ -135,8 +143,5 @@ struct kevent64_s { #define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(a,b,c,d,msg) // -// Print a warning when an unported code path executes. -#define LINUX_PORT_ERROR() do { printf("LINUX_PORT_ERROR_CALLED %s:%d: %s\n",__FILE__,__LINE__,__FUNCTION__); } while (0) - #endif /* __OS_LINUX_BASE__ */ diff --git a/src/shims/linux_stubs.c b/src/shims/linux_stubs.c index 52eb92c22..02b87e749 100644 --- a/src/shims/linux_stubs.c +++ b/src/shims/linux_stubs.c @@ -84,11 +84,6 @@ int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, LINUX_PORT_ERROR(); } -int kevent64(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents,unsigned int flags, const struct timespec *timeout) -{ - return kevent(kq,changelist,nchanges,eventlist,nevents,timeout); -} - /* * Stubbed out static data */ diff --git a/src/source.c b/src/source.c index ac92b03f1..f5685c423 100644 --- a/src/source.c +++ b/src/source.c @@ -1858,6 +1858,47 @@ _dispatch_timers_get_delay(uint64_t nows[], struct dispatch_timer_s timer[], return ridx; } + +#ifdef __linux__ +// in linux we map the _dispatch_kevent_qos_s to struct kevent instead +// of struct kevent64. We loose the kevent.ext[] members and the time +// out is based on relavite msec based time vs. absolute nsec based time. +// For now we make the adjustments right here until the solution +// to either extend libkqueue with a proper kevent64 API or removing kevent +// all together and move to a lower API (e.g. epoll or kernel_module. +// Also leeway is ignored. + +static void +_dispatch_kevent_timer_set_delay(_dispatch_kevent_qos_s *ke, uint64_t delay, + uint64_t leeway, uint64_t nows[]) +{ + // call to return nows[] + _dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL); + // adjust nsec based delay to msec based and ignore leeway + delay /= 1000000L; + if ((int64_t)(delay) <= 0) { + delay = 1; // if value <= 0 the dispatch will stop + } + ke->data = (int64_t)delay; +} + +#else + +static void +_dispatch_kevent_timer_set_delay(_dispatch_kevent_qos_s *ke, uint64_t delay, + uint64_t leeway, uint64_t nows[]) +{ + delay += _dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL); + if (slowpath(_dispatch_timers_force_max_leeway)) { + ke->data = (int64_t)(delay + leeway); + ke->ext[1] = 0; + } else { + ke->data = (int64_t)delay; + ke->ext[1] = leeway; + } +} +#endif + static bool _dispatch_timers_program2(uint64_t nows[], _dispatch_kevent_qos_s *ke, unsigned int qos) @@ -1881,14 +1922,7 @@ _dispatch_timers_program2(uint64_t nows[], _dispatch_kevent_qos_s *ke, _dispatch_trace_next_timer_set( TAILQ_FIRST(&_dispatch_kevent_timer[tidx].dk_sources), qos); _dispatch_trace_next_timer_program(delay, qos); - delay += _dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL); - if (slowpath(_dispatch_timers_force_max_leeway)) { - ke->data = (int64_t)(delay + leeway); - ke->ext[1] = 0; - } else { - ke->data = (int64_t)delay; - ke->ext[1] = leeway; - } + _dispatch_kevent_timer_set_delay(ke, delay, leeway, nows); ke->flags |= EV_ADD|EV_ENABLE; ke->flags &= ~EV_DELETE; }