From ed6ad13bc8f2b33c493a72db9915f3681002e8d0 Mon Sep 17 00:00:00 2001 From: Rhys Kidd Date: Sun, 1 Oct 2017 18:56:05 -0400 Subject: [PATCH] Fix missing workq_ops operations (macOS) Related to discussion in bz#383723. Patch based upon one provided by Andy Maloney. --- NEWS | 1 + coregrind/m_syswrap/syswrap-darwin.c | 69 +++++++++++++++++++++------- include/vki/vki-darwin.h | 21 +++++---- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/NEWS b/NEWS index eccbd199a4..4d6d84026a 100644 --- a/NEWS +++ b/NEWS @@ -55,6 +55,7 @@ where XXXXXX is the bug number as listed below. 384096 Mention AddrCheck at Memcheck's command line option --undef-value-errors=no 384526 reduce number of spill instructions generated by VEX register allocator v3 384584 Callee saved registers listed first for AMD64, X86, and PPC architectures +n-i-bz Fix missing workq_ops operations (macOS) Release 3.13.0 (15 June 2017) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/coregrind/m_syswrap/syswrap-darwin.c b/coregrind/m_syswrap/syswrap-darwin.c index 06708247b4..e8097e3ece 100644 --- a/coregrind/m_syswrap/syswrap-darwin.c +++ b/coregrind/m_syswrap/syswrap-darwin.c @@ -833,6 +833,7 @@ Bool ML_(sync_mappings)(const HChar* when, const HChar* where, UWord num) Bool where_iuct = STREQ(where, "iokit_user_client_trap"); Bool where_MwcN = STREQ(where, "ML_(wqthread_continue_NORETURN)"); Bool where_woQR = STREQ(where, "workq_ops(QUEUE_REQTHREADS)"); + Bool where_woQ2 = STREQ(where, "workq_ops(QUEUE_REQTHREADS2)"); Bool where_woTR = STREQ(where, "workq_ops(THREAD_RETURN)"); Bool where_ke64 = STREQ(where, "kevent64"); # undef STREQ @@ -840,8 +841,8 @@ Bool ML_(sync_mappings)(const HChar* when, const HChar* where, UWord num) vg_assert( 1 >= ( (where_mmr ? 1 : 0) + (where_mmrU ? 1 : 0) + (where_iuct ? 1 : 0) + (where_MwcN ? 1 : 0) - + (where_woQR ? 1 : 0) + (where_woTR ? 1 : 0) - + (where_ke64 ? 1 : 0) + + (where_woQR ? 1 : 0) + (where_woQ2 ? 1 : 0) + + (where_woTR ? 1 : 0) + (where_ke64 ? 1 : 0) )); // merely to stop gcc complaining of non-use in the case where // there's no filter: @@ -892,6 +893,11 @@ Bool ML_(sync_mappings)(const HChar* when, const HChar* where, UWord num) // upd 14434 diff 102+,0- check = CheckEvery20; } +/* if (when_after && where_woQ2 && num == 0x00000000) { + // after workq_ops(QUEUE_REQTHREADS2) 0x00000000 + // upd XXXX diff XX+,0- + check = CheckEvery20; + } */ else if (when_after && where_woTR && num == 0x00000000) { // after workq_ops(THREAD_RETURN) 0x00000000 @@ -954,6 +960,11 @@ Bool ML_(sync_mappings)(const HChar* when, const HChar* where, UWord num) // upd 1099 diff 37+,0- check = CheckEvery20; } +/* if (when_after && where_woQ2 && num == 0x00000000) { + // after workq_ops(QUEUE_REQTHREADS2) 0x00000000 + // upd XXXX diff XX+,0- + check = CheckEvery20; + } */ else if (when_after && where_woTR && num == 0x00000000) { // after workq_ops(THREAD_RETURN) 0x00000000 @@ -2089,12 +2100,17 @@ PRE(workq_open) static const HChar *workqop_name(int op) { switch (op) { - case VKI_WQOPS_QUEUE_ADD: return "QUEUE_ADD"; - case VKI_WQOPS_QUEUE_REMOVE: return "QUEUE_REMOVE"; - case VKI_WQOPS_THREAD_RETURN: return "THREAD_RETURN"; - case VKI_WQOPS_THREAD_SETCONC: return "THREAD_SETCONC"; - case VKI_WQOPS_QUEUE_NEWSPISUPP: return "QUEUE_NEWSPISUPP"; - case VKI_WQOPS_QUEUE_REQTHREADS: return "QUEUE_REQTHREADS"; + case VKI_WQOPS_QUEUE_ADD: return "QUEUE_ADD"; + case VKI_WQOPS_QUEUE_REMOVE: return "QUEUE_REMOVE"; + case VKI_WQOPS_THREAD_RETURN: return "THREAD_RETURN"; + case VKI_WQOPS_THREAD_SETCONC: return "THREAD_SETCONC"; + case VKI_WQOPS_QUEUE_NEWSPISUPP: return "QUEUE_NEWSPISUPP"; + case VKI_WQOPS_QUEUE_REQTHREADS: return "QUEUE_REQTHREADS"; + case VKI_WQOPS_QUEUE_REQTHREADS2: return "QUEUE_REQTHREADS2"; + case VKI_WQOPS_THREAD_KEVENT_RETURN: return "THREAD_KEVENT_RETURN"; + case VKI_WQOPS_SET_EVENT_MANAGER_PRIORITY: return "SET_EVENT_MANAGER_PRIORITY"; + case VKI_WQOPS_THREAD_WORKLOOP_RETURN: return "THREAD_WORKLOOP_RETURN"; + case VKI_WQOPS_SHOULD_NARROW: return "SHOULD_NARROW"; default: return "?"; } } @@ -2113,14 +2129,6 @@ PRE(workq_ops) // GrP fixme need anything here? // GrP fixme may block? break; - case VKI_WQOPS_QUEUE_NEWSPISUPP: - // JRS don't think we need to do anything here -- this just checks - // whether some newer functionality is supported - break; - case VKI_WQOPS_QUEUE_REQTHREADS: - // JRS uh, looks like it queues up a bunch of threads, or some such? - *flags |= SfMayBlock; // the kernel sources take a spinlock, so play safe - break; case VKI_WQOPS_THREAD_RETURN: { // The interesting case. The kernel will do one of two things: // 1. Return normally. We continue; libc proceeds to stop the thread. @@ -2137,6 +2145,32 @@ PRE(workq_ops) *flags |= SfMayBlock; // GrP fixme true? break; } + case VKI_WQOPS_THREAD_SETCONC: + // RK fixme need anything here? + // RK fixme may block? + break; + case VKI_WQOPS_QUEUE_NEWSPISUPP: + // JRS don't think we need to do anything here -- this just checks + // whether some newer functionality is supported + break; + case VKI_WQOPS_QUEUE_REQTHREADS: + case VKI_WQOPS_QUEUE_REQTHREADS2: + // JRS uh, looks like it queues up a bunch of threads, or some such? + *flags |= SfMayBlock; // the kernel sources take a spinlock, so play safe + break; + case VKI_WQOPS_THREAD_KEVENT_RETURN: + // RK fixme need anything here? + // perhaps similar to VKI_WQOPS_THREAD_RETURN above? + break; + case VKI_WQOPS_SET_EVENT_MANAGER_PRIORITY: + // RK fixme this just sets scheduling priorities - don't think we need + // to do anything here + break; + case VKI_WQOPS_THREAD_WORKLOOP_RETURN: + case VKI_WQOPS_SHOULD_NARROW: + // RK fixme need anything here? + // RK fixme may block? + break; default: VG_(printf)("UNKNOWN workq_ops option %ld\n", ARG1); break; @@ -2153,6 +2187,9 @@ POST(workq_ops) case VKI_WQOPS_QUEUE_REQTHREADS: ML_(sync_mappings)("after", "workq_ops(QUEUE_REQTHREADS)", 0); break; + case VKI_WQOPS_QUEUE_REQTHREADS2: + ML_(sync_mappings)("after", "workq_ops(QUEUE_REQTHREADS2)", 0); + break; default: break; } diff --git a/include/vki/vki-darwin.h b/include/vki/vki-darwin.h index 72b66bf91e..53d14f3227 100644 --- a/include/vki/vki-darwin.h +++ b/include/vki/vki-darwin.h @@ -847,14 +847,19 @@ struct ByteRangeLockPB2 #define VKI_FSIOC_SYNC_VOLUME _IOW('A', 1, uint32_t) -// Libc/pthreads/pthread.c - -#define VKI_WQOPS_QUEUE_ADD 1 -#define VKI_WQOPS_QUEUE_REMOVE 2 -#define VKI_WQOPS_THREAD_RETURN 4 -#define VKI_WQOPS_THREAD_SETCONC 8 -#define VKI_WQOPS_QUEUE_NEWSPISUPP 16 /* check for newer SPI support */ -#define VKI_WQOPS_QUEUE_REQTHREADS 32 /* request number of threads of a prio */ +// libpthread/kern/workqueue_internal.h + +#define VKI_WQOPS_QUEUE_ADD 1 +#define VKI_WQOPS_QUEUE_REMOVE 2 +#define VKI_WQOPS_THREAD_RETURN 4 /* parks the thread back into the kernel */ +#define VKI_WQOPS_THREAD_SETCONC 8 +#define VKI_WQOPS_QUEUE_NEWSPISUPP 16 /* check for newer SPI support */ +#define VKI_WQOPS_QUEUE_REQTHREADS 32 /* request number of threads of a prio */ +#define VKI_WQOPS_QUEUE_REQTHREADS2 48 /* request a number of threads in a given priority bucket */ +#define VKI_WQOPS_THREAD_KEVENT_RETURN 64 /* parks the thread after delivering the passed kevent array */ +#define VKI_WQOPS_SET_EVENT_MANAGER_PRIORITY 128 /* max() in the provided priority in the the priority of the event manager */ +#define VKI_WQOPS_THREAD_WORKLOOP_RETURN 256 /* parks the thread after delivering the passed kevent array */ +#define VKI_WQOPS_SHOULD_NARROW 512 /* checks whether we should narrow our concurrency */ #include -- 2.47.2