From aca0d3cc5d879dc997f9290a2721a876c5dbde14 Mon Sep 17 00:00:00 2001 From: David Grove Date: Wed, 9 Dec 2015 21:11:10 +0000 Subject: [PATCH 1/5] Cleanup of kevent usage - reduce kevent64 to kevent usage: implies time management in dispatch_timers_program2 moves from absolute to relative and to msecs as that's what kevent can handle right now - properly defined NOTE_xxxxx macros - configure.ac change to define HAVE_KEVENT64 Squashed commit of the following: commit dfe7b8bb653f10980a080cf31c3f58e3916f9003 Merge: e25ec26 6293e78 Author: Hubertus Franke Date: Wed Dec 9 15:38:11 2015 -0500 Merge branch 'linux-port-hdd' of github.ibm.com:ibmswift/swift-corelibs-libdispatch into linux-port-hdd commit e25ec26237ec4858d01858fa8fffd590e279502b Author: Hubertus Franke Date: Wed Dec 9 15:37:38 2015 -0500 reduce the impact of kevent64 commit 6293e783cb6daa5b01299e881e754e289c0331e2 Author: David Grove Date: Wed Dec 9 17:59:59 2015 +0000 kqueue check now also looks for kevent64 and sets config.h accordingly commit 53a8aa662fadc69edc20f94b4ac4835b2b45b261 Merge: b02031c cff30c4 Author: David Grove Date: Wed Dec 9 15:16:21 2015 +0000 Merge branch 'linux-port-hdd' of github.ibm.com:ibmswift/swift-corelibs-libdispatch into linux-port-hdd commit cff30c420e419ad6f6aac4343816b29c43c2123b Author: Hubertus Franke Date: Wed Dec 9 06:59:09 2015 -0500 check only one event is returned in kevent() call to allow type coercion commit 884bd367f29effd0d8b45383d106187a5729ab7e Author: Hubertus Franke Date: Tue Dec 8 22:58:41 2015 -0500 kevent64 shim turns time negative in absolute to relative conversion. Checked for it commit e48115bb8d61aba2dd9bc1f7f3686a16ce175b7a Author: Hubertus Franke Date: Tue Dec 8 21:49:29 2015 -0500 fix periodic timers through kevent rewrite and fix definition for linux commit b02031c5f63ca5d861578e1dfd1691473f05d960 Merge: 7f64b1c 14f0250 Author: David Grove Date: Sun Dec 6 19:21:44 2015 +0000 Merge branch 'master' of github.com:apple/swift-corelibs-libdispatch into linux-port-hdd commit 7f64b1ce5e7187d1aed701291ccd1ffb18c51127 Author: David Grove Date: Sat Dec 5 16:55:30 2015 +0000 fix mistake made in merge commit d2f10b35667ae3009786380b5b31d32212b218a0 Merge: fae40d1 394d9a1 Author: David Grove Date: Sat Dec 5 16:38:51 2015 +0000 Merge branch 'master' into linux-port-hdd commit fae40d1f124a117cba19e629675bafafafce1734 Merge: a93074c acd56f6 Author: David Grove Date: Fri Dec 4 20:49:43 2015 +0000 Merge branch 'master' into linux-port-hdd commit a93074c49638210f60590b1da8ba6d8e42a258a1 Author: David Grove Date: Fri Dec 4 20:44:13 2015 +0000 cleanups commit 10b9e9432c7e6adca23261d50268097421d809dc Author: David Grove Date: Fri Dec 4 20:36:14 2015 +0000 don't add os/base.h commit bc04960c65476146a1cfefeb7ea59a4bc825fbad Author: David Grove Date: Fri Dec 4 20:27:25 2015 +0000 WIP cleanup commit b741481765bbf53e9981a8b878a387087f6a3150 Author: David Grove Date: Fri Dec 4 20:02:14 2015 +0000 addressing commenrts from pull request commit 6de4767752218cc04b3ee77d813075d8bcb18b8c Author: David Grove Date: Fri Dec 4 18:08:40 2015 +0000 use __APPLE__ instead of HAVE_MACH commit f87caf9cab9b1e8556ac99161e516e99b3eaaa3a Author: David Grove Date: Fri Dec 4 18:05:06 2015 +0000 Copy BSD sys/queue.h to shims/sys_queue.h and remove HACK around SAFE macros commit e3652d6da8fdaaff7dff34083db42b0d12f29c60 Author: David Grove Date: Fri Dec 4 16:26:21 2015 +0000 Expand comments and reorganize; remove mistaken redefine of DISPATCH_EXPORT macros commit dd656bec9727b0487ee7336e93ffe2e847d5636d Author: David Grove Date: Thu Dec 3 22:20:46 2015 +0000 revert back to matching kevent64_s definition from OS X man page for kevent commit 02616b0cb6bb239e1a0df453bc64e8e86a4fd038 Merge: 2453edc 650f82a Author: Hubertus Franke Date: Thu Dec 3 17:04:24 2015 -0500 merged conflicts commit 2453edc4f20d008b309981d27cd681fb9c325b85 Author: Hubertus Franke Date: Thu Dec 3 17:00:27 2015 -0500 fixed kevent, running till dispatch with bugs still in queue counts commit 650f82a41478749b11353c81d810fdc13b94522b Author: David Grove Date: Thu Dec 3 01:16:32 2015 +0000 license headers on added files commit 16d8a2cde8521e133c79579ca1fdc412a6dbcf9c Author: David Grove Date: Wed Dec 2 22:26:40 2015 +0000 fix stubbed functions to have the right prototype and abort in their bodies when called commit a6ede63da17adff79ddbdb3d70ba88b7a663c1d8 Author: David Grove Date: Wed Dec 2 17:07:16 2015 +0000 update stubs and typedefs after merge of pull-request 2 from master commit f38ebb9ec0b6319a2bcd3f038d1f5c986b3bad74 Author: David Grove Date: Wed Dec 2 17:05:57 2015 +0000 remove workaround; type now defined in proper header file commit e0f0522924cfcea7742c2305eac06c07e497b4c6 Merge: 8d8bb46 39ac720 Author: David Grove Date: Wed Dec 2 16:46:42 2015 +0000 Merge branch 'master' into linux-port-hdd commit 8d8bb462e8be1e1c1b79f21f5b61863d009c4fde Author: David Grove Date: Wed Dec 2 01:40:23 2015 +0000 stub out missing functions and statics with dummy definitions commit 9f4f1032979f49e7f7102264d9cdac73ae4feea1 Author: David Grove Date: Tue Dec 1 16:02:11 2015 +0000 Update list of header files to be installed for dispatch and os. Move stubs.h to stubs_internal.h and include it from internal.h (so we don't need to install stubs to get a complete set of header files). commit 9a39fefeb1f5279bceb3592e01f4a453dbd55355 Author: David Grove Date: Mon Nov 30 21:52:38 2015 +0000 clang on linux just ignores -compatibility_version instead of failing with an unknown error message (despite the fact that ld won't actually understand the argument, so linking will actually fail in the end). This is a hack to generate workable makefiles; it may not be the right fix... commit efa2a28b8122ff02d0abccae6562260cdb9f22a1 Author: David Grove Date: Mon Nov 30 21:51:59 2015 +0000 ignore .la files commit 35984ca0a829b5be4b3be927a8ad744074010bd9 Author: David Grove Date: Mon Nov 30 21:34:28 2015 +0000 WIP on getting code to compile commit 2ab2c26d6a76273ee05cb5fa26f4eff5ad9d9910 Author: David Grove Date: Mon Nov 30 21:04:26 2015 +0000 slightly suspect changes to get semaphore.c to compile. The existing code was clearly wrong, but this might not be the right way to fix it either... commit d7fe4b08720d194fe8379f38b41c0130c241ad9b Author: David Grove Date: Mon Nov 30 20:48:04 2015 +0000 tweaks to get it to compile commit da3b73d2e60d47f705e45c2182094c08fbd5aaaa Author: David Grove Date: Mon Nov 30 19:06:27 2015 +0000 WIP on stubbing out missing pieces to get code to compile commit 4f9b58c1ed3617fda781dffe85b1cbe28837e912 Author: David Grove Date: Mon Nov 30 18:06:33 2015 +0000 synthesize declarations of missing observer types commit fdeae8a0fa231b25c43d2217f9d40d4c0c38c4d4 Author: David Grove Date: Mon Nov 30 18:05:58 2015 +0000 guard include of mach.h with HAVE_MACH commit f013a9933d05b46e03fa49db121e6610282a2e4c Author: David Grove Date: Mon Nov 30 18:05:02 2015 +0000 ignore autotools and libtool generated files commit f22bc4b5be3bc7c49e92b392192ebd915f116a15 Author: David Grove Date: Mon Nov 30 18:02:50 2015 +0000 header files to stub out types/functions for linux port --- configure.ac | 7 ++- os/linux_base.h | 49 ++++++++++++--------- src/shims/linux_stubs.c | 98 ++++++++++++++++++++++++++++++++++++++++- src/source.c | 25 +++++++++-- 4 files changed, 150 insertions(+), 29 deletions(-) diff --git a/configure.ac b/configure.ac index 3f8aea44a..b88271c0d 100644 --- a/configure.ac +++ b/configure.ac @@ -137,9 +137,14 @@ AC_SEARCH_LIBS(pthread_create, pthread) # Prefer native kqueue(2); otherwise use libkqueue if present. # AC_CHECK_HEADER(sys/event.h, [], - [PKG_CHECK_MODULES(KQUEUE, libkqueue)] + [PKG_CHECK_MODULES(KQUEUE, libkqueue) + AC_SEARCH_LIBS(kevent, kqueue) + AC_SEARCH_LIBS(kevent64, kqueue, + [AC_DEFINE(HAVE_KEVENT64, 1, [Define if kevent64 is present])], + [AC_DEFINE(HAVE_KEVENT64, 0, [Define if kevent64 is present])])] ) + # # Checks for header files. # diff --git a/os/linux_base.h b/os/linux_base.h index 971d85e00..0577654b4 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 !HAVE_KEVENT64 +// 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..ad39f933a 100644 --- a/src/shims/linux_stubs.c +++ b/src/shims/linux_stubs.c @@ -84,11 +84,105 @@ 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) +#if 0 + +// this code remains here purely for debugging purposes +// ultimately it can be deleted + +DISPATCH_NOINLINE +static const char * +_evfiltstr(short filt) +{ + switch (filt) { +#define _evfilt2(f) case (f): return #f + _evfilt2(EVFILT_READ); + _evfilt2(EVFILT_WRITE); + _evfilt2(EVFILT_AIO); + _evfilt2(EVFILT_VNODE); + _evfilt2(EVFILT_PROC); + _evfilt2(EVFILT_SIGNAL); + _evfilt2(EVFILT_TIMER); +#if HAVE_MACH + _evfilt2(EVFILT_MACHPORT); + _evfilt2(DISPATCH_EVFILT_MACH_NOTIFICATION); +#endif + _evfilt2(EVFILT_FS); + _evfilt2(EVFILT_USER); +#ifdef EVFILT_VM + _evfilt2(EVFILT_VM); +#endif +#ifdef EVFILT_SOCK + _evfilt2(EVFILT_SOCK); +#endif +#ifdef EVFILT_MEMORYSTATUS + _evfilt2(EVFILT_MEMORYSTATUS); +#endif + + _evfilt2(DISPATCH_EVFILT_TIMER); + _evfilt2(DISPATCH_EVFILT_CUSTOM_ADD); + _evfilt2(DISPATCH_EVFILT_CUSTOM_OR); + default: + return "EVFILT_missing"; + } +} + +#if 0 +#define dbg_kevent64(fmt...) do { printf(fmt); } while(0) +#define dbg_cond_kevent64(cond,fmt...) do { if (cond) printf(fmt); } while(0) +#else +#define dbg_kevent64(fmt...) do { } while(0) +#define dbg_cond_kevent64(cond,fmt...) do { } while(0) +#endif + + +int kevent64(int kq, const struct kevent64_s *changelist_c, int nchanges, struct kevent64_s *eventlist, + int nevents, unsigned int flags, const struct timespec *timeout) { - return kevent(kq,changelist,nchanges,eventlist,nevents,timeout); + // Documentation is not really clear. Instrument the code to make sure + // we can do type conversions right now between kevent64 <-> kevent, where as + // kevent64 uses the ext[2] extension. So far we only see these used in the EVFILT_TIMER. + // right now we do this in the way into kevent, we also have to assert that + // no more than 1 change or one event is passed until we get a better handle of the + // usage pattern of this. (Hubertus Franke) + + struct kevent64_s *changelist = (struct kevent64_s*) changelist_c; // so we can modify it + +#if 1 + // lets put some checks in here to make sure we do it all correct + // we can only convert kevent64_s -> kevent for a single entry since kevent64_s has ext[0:1] extension + if ((nchanges > 1) || (nevents > 1)) + LINUX_PORT_ERROR(); + if (nchanges) { + dbg_kevent64("kevent64(%s,%x,%x): cl.ext[0,1]=%lx:%ld %lx:%ld cl.data=%lx:%ld\n", + _evfiltstr(changelist->filter), changelist->flags, changelist->fflags, + changelist->ext[0], changelist->ext[0], + changelist->ext[1], changelist->ext[1], + changelist->data, changelist->data); + if ((changelist->filter == EVFILT_TIMER) && (changelist->fflags & NOTE_ABSOLUTE)) { + // NOTE_ABSOLUTE is not recognized by the current kevent we need to convert this + // into a relative. Consider fiddling with creating relative events instead (didn't work + // on first attempt). We also ignore the LEEWAY. Finally we must convert from + // NSECS to MSECS (might have to expand to deal with OTHER NOTE_xSECS flags + + //changelist->data -= _dispatch_get_nanoseconds(); + //changelist->data -= time(NULL) * NSEC_PER_SEC; + dbg_kevent64("kevent64(%s,%x) data=%lx:%ld\n", + _evfiltstr(changelist->filter),changelist->fflags, + changelist->data,changelist->data); + //changelist->data /= 1000000UL; + //if ((int64_t)(changelist->data) <= 0) changelist->data = 1; // for some reason time turns negative + } + } +#endif + // eventlist can not return more than 1 event type coersion doesn't work + int rc = kevent(kq,(struct kevent*) changelist,nchanges,(struct kevent*) eventlist,nevents,timeout); + if (rc > 1) + LINUX_PORT_ERROR(); + return rc; } +#endif + /* * Stubbed out static data */ diff --git a/src/source.c b/src/source.c index ac92b03f1..82a9c2ef1 100644 --- a/src/source.c +++ b/src/source.c @@ -1858,13 +1858,22 @@ _dispatch_timers_get_delay(uint64_t nows[], struct dispatch_timer_s timer[], return ridx; } + +#if HAVE_KEVENT64 +# define kevent_set_ext1(ke,val) (ke)->ext[1] = (val) +# define delay_add_wall(delay,at) (delay) += (at) +#else +# define kevent_set_ext1(ke,val) do { } while (0) +# define delay_add_wall(delay,at) do { } while (0) +#endif + static bool _dispatch_timers_program2(uint64_t nows[], _dispatch_kevent_qos_s *ke, unsigned int qos) { unsigned int tidx; bool poll; - uint64_t delay, leeway; + uint64_t delay, leeway, nowtime; tidx = _dispatch_timers_get_delay(nows, _dispatch_timer, &delay, &leeway, (int)qos); @@ -1881,13 +1890,21 @@ _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); + nowtime =_dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL); + delay_add_wall(delay,nowtime); + + //printf("%s: delay %ld nsecs\n",__FUNCTION__,delay); + // convert delay into msecs + delay /= 1000000L; + if ((int64_t)(delay) <= 0) delay = 1; // for some reason time turns negative + //if ((int64_t)(delay) <= 0) printf("%s: delay =%d\n",__FUNCTION__,(int64_t)delay); + if (slowpath(_dispatch_timers_force_max_leeway)) { ke->data = (int64_t)(delay + leeway); - ke->ext[1] = 0; + kevent_set_ext1(ke,0); } else { ke->data = (int64_t)delay; - ke->ext[1] = leeway; + kevent_set_ext1(ke,leeway); } ke->flags |= EV_ADD|EV_ENABLE; ke->flags &= ~EV_DELETE; From 3809a100508799dd3819962b44b9a34c5cf7f589 Mon Sep 17 00:00:00 2001 From: Hubertus Franke Date: Wed, 9 Dec 2015 16:25:48 -0500 Subject: [PATCH 2/5] moved the kevent time adjustment in _dispatch_timers_program2 to proper macro --- src/source.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/source.c b/src/source.c index 82a9c2ef1..75ab277ba 100644 --- a/src/source.c +++ b/src/source.c @@ -1861,10 +1861,15 @@ _dispatch_timers_get_delay(uint64_t nows[], struct dispatch_timer_s timer[], #if HAVE_KEVENT64 # define kevent_set_ext1(ke,val) (ke)->ext[1] = (val) -# define delay_add_wall(delay,at) (delay) += (at) +# define adjust_delay(delay,at) (delay) += (at) #else # define kevent_set_ext1(ke,val) do { } while (0) -# define delay_add_wall(delay,at) do { } while (0) +# define adjust_delay(delay,at) \ + do { \ + delay /= 1000000L; \ + if ((int64_t)(delay) <= 0) delay = 1; /* for some reason time turns negative */ \ + } while (0) + #endif static bool @@ -1891,13 +1896,7 @@ _dispatch_timers_program2(uint64_t nows[], _dispatch_kevent_qos_s *ke, TAILQ_FIRST(&_dispatch_kevent_timer[tidx].dk_sources), qos); _dispatch_trace_next_timer_program(delay, qos); nowtime =_dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL); - delay_add_wall(delay,nowtime); - - //printf("%s: delay %ld nsecs\n",__FUNCTION__,delay); - // convert delay into msecs - delay /= 1000000L; - if ((int64_t)(delay) <= 0) delay = 1; // for some reason time turns negative - //if ((int64_t)(delay) <= 0) printf("%s: delay =%d\n",__FUNCTION__,(int64_t)delay); + adjust_delay(delay,nowtime); if (slowpath(_dispatch_timers_force_max_leeway)) { ke->data = (int64_t)(delay + leeway); From 907c677c2ba3250491f7c04b95767e09dd72e4dd Mon Sep 17 00:00:00 2001 From: David Grove Date: Thu, 10 Dec 2015 11:55:53 +0000 Subject: [PATCH 3/5] fix placement of CHECK_LIBS test for kevent64 Need to run this check independent of the check for sys/event64 so that HAVE_KEVENT64 will be checked and defined on all platforms. --- configure.ac | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index b88271c0d..2e9e310cb 100644 --- a/configure.ac +++ b/configure.ac @@ -137,13 +137,12 @@ AC_SEARCH_LIBS(pthread_create, pthread) # Prefer native kqueue(2); otherwise use libkqueue if present. # AC_CHECK_HEADER(sys/event.h, [], - [PKG_CHECK_MODULES(KQUEUE, libkqueue) - AC_SEARCH_LIBS(kevent, kqueue) - AC_SEARCH_LIBS(kevent64, kqueue, - [AC_DEFINE(HAVE_KEVENT64, 1, [Define if kevent64 is present])], - [AC_DEFINE(HAVE_KEVENT64, 0, [Define if kevent64 is present])])] + [PKG_CHECK_MODULES(KQUEUE, libkqueue)] ) - +AC_SEARCH_LIBS(kevent, kqueue) +AC_SEARCH_LIBS(kevent64, kqueue, + [AC_DEFINE(HAVE_KEVENT64, 1, [Define if kevent64 is present])], + [AC_DEFINE(HAVE_KEVENT64, 0, [Define if kevent64 is present])]) # # Checks for header files. From d76ef08fe157f2b0874bb99096127ce31f17e338 Mon Sep 17 00:00:00 2001 From: Hubertus Franke Date: Thu, 10 Dec 2015 14:46:51 -0500 Subject: [PATCH 4/5] reduce impact of linux on the previous kevent changes --- configure.ac | 4 -- os/linux_base.h | 2 +- src/shims/linux_stubs.c | 99 ----------------------------------------- src/source.c | 58 +++++++++++++++--------- 4 files changed, 38 insertions(+), 125 deletions(-) diff --git a/configure.ac b/configure.ac index 2e9e310cb..3f8aea44a 100644 --- a/configure.ac +++ b/configure.ac @@ -139,10 +139,6 @@ AC_SEARCH_LIBS(pthread_create, pthread) AC_CHECK_HEADER(sys/event.h, [], [PKG_CHECK_MODULES(KQUEUE, libkqueue)] ) -AC_SEARCH_LIBS(kevent, kqueue) -AC_SEARCH_LIBS(kevent64, kqueue, - [AC_DEFINE(HAVE_KEVENT64, 1, [Define if kevent64 is present])], - [AC_DEFINE(HAVE_KEVENT64, 0, [Define if kevent64 is present])]) # # Checks for header files. diff --git a/os/linux_base.h b/os/linux_base.h index 0577654b4..f68ffc3ff 100644 --- a/os/linux_base.h +++ b/os/linux_base.h @@ -84,7 +84,7 @@ struct voucher_offsets_s { * Stub out defines for other missing types */ -#if !HAVE_KEVENT64 +#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) diff --git a/src/shims/linux_stubs.c b/src/shims/linux_stubs.c index ad39f933a..02b87e749 100644 --- a/src/shims/linux_stubs.c +++ b/src/shims/linux_stubs.c @@ -84,105 +84,6 @@ int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, LINUX_PORT_ERROR(); } -#if 0 - -// this code remains here purely for debugging purposes -// ultimately it can be deleted - -DISPATCH_NOINLINE -static const char * -_evfiltstr(short filt) -{ - switch (filt) { -#define _evfilt2(f) case (f): return #f - _evfilt2(EVFILT_READ); - _evfilt2(EVFILT_WRITE); - _evfilt2(EVFILT_AIO); - _evfilt2(EVFILT_VNODE); - _evfilt2(EVFILT_PROC); - _evfilt2(EVFILT_SIGNAL); - _evfilt2(EVFILT_TIMER); -#if HAVE_MACH - _evfilt2(EVFILT_MACHPORT); - _evfilt2(DISPATCH_EVFILT_MACH_NOTIFICATION); -#endif - _evfilt2(EVFILT_FS); - _evfilt2(EVFILT_USER); -#ifdef EVFILT_VM - _evfilt2(EVFILT_VM); -#endif -#ifdef EVFILT_SOCK - _evfilt2(EVFILT_SOCK); -#endif -#ifdef EVFILT_MEMORYSTATUS - _evfilt2(EVFILT_MEMORYSTATUS); -#endif - - _evfilt2(DISPATCH_EVFILT_TIMER); - _evfilt2(DISPATCH_EVFILT_CUSTOM_ADD); - _evfilt2(DISPATCH_EVFILT_CUSTOM_OR); - default: - return "EVFILT_missing"; - } -} - -#if 0 -#define dbg_kevent64(fmt...) do { printf(fmt); } while(0) -#define dbg_cond_kevent64(cond,fmt...) do { if (cond) printf(fmt); } while(0) -#else -#define dbg_kevent64(fmt...) do { } while(0) -#define dbg_cond_kevent64(cond,fmt...) do { } while(0) -#endif - - -int kevent64(int kq, const struct kevent64_s *changelist_c, int nchanges, struct kevent64_s *eventlist, - int nevents, unsigned int flags, const struct timespec *timeout) -{ - // Documentation is not really clear. Instrument the code to make sure - // we can do type conversions right now between kevent64 <-> kevent, where as - // kevent64 uses the ext[2] extension. So far we only see these used in the EVFILT_TIMER. - // right now we do this in the way into kevent, we also have to assert that - // no more than 1 change or one event is passed until we get a better handle of the - // usage pattern of this. (Hubertus Franke) - - struct kevent64_s *changelist = (struct kevent64_s*) changelist_c; // so we can modify it - -#if 1 - // lets put some checks in here to make sure we do it all correct - // we can only convert kevent64_s -> kevent for a single entry since kevent64_s has ext[0:1] extension - if ((nchanges > 1) || (nevents > 1)) - LINUX_PORT_ERROR(); - if (nchanges) { - dbg_kevent64("kevent64(%s,%x,%x): cl.ext[0,1]=%lx:%ld %lx:%ld cl.data=%lx:%ld\n", - _evfiltstr(changelist->filter), changelist->flags, changelist->fflags, - changelist->ext[0], changelist->ext[0], - changelist->ext[1], changelist->ext[1], - changelist->data, changelist->data); - if ((changelist->filter == EVFILT_TIMER) && (changelist->fflags & NOTE_ABSOLUTE)) { - // NOTE_ABSOLUTE is not recognized by the current kevent we need to convert this - // into a relative. Consider fiddling with creating relative events instead (didn't work - // on first attempt). We also ignore the LEEWAY. Finally we must convert from - // NSECS to MSECS (might have to expand to deal with OTHER NOTE_xSECS flags - - //changelist->data -= _dispatch_get_nanoseconds(); - //changelist->data -= time(NULL) * NSEC_PER_SEC; - dbg_kevent64("kevent64(%s,%x) data=%lx:%ld\n", - _evfiltstr(changelist->filter),changelist->fflags, - changelist->data,changelist->data); - //changelist->data /= 1000000UL; - //if ((int64_t)(changelist->data) <= 0) changelist->data = 1; // for some reason time turns negative - } - } -#endif - // eventlist can not return more than 1 event type coersion doesn't work - int rc = kevent(kq,(struct kevent*) changelist,nchanges,(struct kevent*) eventlist,nevents,timeout); - if (rc > 1) - LINUX_PORT_ERROR(); - return rc; -} - -#endif - /* * Stubbed out static data */ diff --git a/src/source.c b/src/source.c index 75ab277ba..1968873a2 100644 --- a/src/source.c +++ b/src/source.c @@ -1859,17 +1859,40 @@ _dispatch_timers_get_delay(uint64_t nows[], struct dispatch_timer_s timer[], } -#if HAVE_KEVENT64 -# define kevent_set_ext1(ke,val) (ke)->ext[1] = (val) -# define adjust_delay(delay,at) (delay) += (at) +#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 +kevent_set_delay(_dispatch_kevent_qos_s *ke, uint64_t delay,uint64_t leeway, uint64_t nows[]) +{ + _dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL); // called to return nows[] + + delay /= 1000000L; + if ((int64_t)(delay) <= 0) + delay = 1; /* if he value is negative or 0 then the dispatch will stop */ + ke->data = (int64_t)delay; +} + #else -# define kevent_set_ext1(ke,val) do { } while (0) -# define adjust_delay(delay,at) \ - do { \ - delay /= 1000000L; \ - if ((int64_t)(delay) <= 0) delay = 1; /* for some reason time turns negative */ \ - } while (0) +static void +kevent_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 @@ -1878,7 +1901,7 @@ _dispatch_timers_program2(uint64_t nows[], _dispatch_kevent_qos_s *ke, { unsigned int tidx; bool poll; - uint64_t delay, leeway, nowtime; + uint64_t delay, leeway; tidx = _dispatch_timers_get_delay(nows, _dispatch_timer, &delay, &leeway, (int)qos); @@ -1895,19 +1918,12 @@ _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); - nowtime =_dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL); - adjust_delay(delay,nowtime); - if (slowpath(_dispatch_timers_force_max_leeway)) { - ke->data = (int64_t)(delay + leeway); - kevent_set_ext1(ke,0); - } else { - ke->data = (int64_t)delay; - kevent_set_ext1(ke,leeway); - } - ke->flags |= EV_ADD|EV_ENABLE; - ke->flags &= ~EV_DELETE; + kevent_set_delay(ke,delay,leeway,nows); } + + ke->flags |= EV_ADD|EV_ENABLE; + ke->flags &= ~EV_DELETE; _dispatch_kq_update(ke); return poll; } From 8b0e8f8ac2c3d5396276fa76b0647e8fca891cc3 Mon Sep 17 00:00:00 2001 From: Hubertus Franke Date: Thu, 10 Dec 2015 18:32:57 -0500 Subject: [PATCH 5/5] address Pierre Habouzit's formatting and naming convention requests --- src/source.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/source.c b/src/source.c index 1968873a2..f5685c423 100644 --- a/src/source.c +++ b/src/source.c @@ -1860,31 +1860,35 @@ _dispatch_timers_get_delay(uint64_t nows[], struct dispatch_timer_s timer[], #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. +// 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 -kevent_set_delay(_dispatch_kevent_qos_s *ke, uint64_t delay,uint64_t leeway, uint64_t nows[]) +_dispatch_kevent_timer_set_delay(_dispatch_kevent_qos_s *ke, uint64_t delay, + uint64_t leeway, uint64_t nows[]) { - _dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL); // called to return 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 he value is negative or 0 then the dispatch will stop */ + if ((int64_t)(delay) <= 0) { + delay = 1; // if value <= 0 the dispatch will stop + } ke->data = (int64_t)delay; } #else static void -kevent_set_delay(_dispatch_kevent_qos_s *ke, uint64_t delay,uint64_t leeway, uint64_t nows[]) +_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; @@ -1918,12 +1922,10 @@ _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); - - kevent_set_delay(ke,delay,leeway,nows); + _dispatch_kevent_timer_set_delay(ke, delay, leeway, nows); + ke->flags |= EV_ADD|EV_ENABLE; + ke->flags &= ~EV_DELETE; } - - ke->flags |= EV_ADD|EV_ENABLE; - ke->flags &= ~EV_DELETE; _dispatch_kq_update(ke); return poll; }