+int
+_pthread_workqueue_override_start_direct_check_owner(mach_port_t thread, pthread_priority_t priority, mach_port_t *ulock_addr)
+{
+#if !TARGET_OS_IPHONE
+ static boolean_t kernel_supports_owner_check = TRUE;
+ if (!kernel_supports_owner_check) {
+ ulock_addr = NULL;
+ }
+#endif
+
+ for (;;) {
+ int res = __bsdthread_ctl(BSDTHREAD_CTL_QOS_OVERRIDE_DISPATCH, thread, priority, ulock_addr);
+ if (res == -1) { res = errno; }
+#if !TARGET_OS_IPHONE
+ if (ulock_addr && res == EINVAL) {
+ if ((uintptr_t)ulock_addr % _Alignof(_Atomic uint32_t)) {
+ // do not mute bad ulock addresses related errors
+ return EINVAL;
+ }
+ // backward compatibility for the XBS chroot
+ // BSDTHREAD_CTL_QOS_OVERRIDE_DISPATCH used to return EINVAL if
+ // arg3 was non NULL.
+ kernel_supports_owner_check = FALSE;
+ ulock_addr = NULL;
+ continue;
+ }
+#endif
+ if (ulock_addr && res == EFAULT) {
+ // kernel wants us to redrive the call, so while we refault the
+ // memory, also revalidate the owner
+ uint32_t uval = os_atomic_load(ulock_addr, relaxed);
+ if (ulock_owner_value_to_port_name(uval) != thread) {
+ return ESTALE;
+ }
+ continue;
+ }
+
+ return res;
+ }
+}
+