pthread_kern->psynch_wait_update_owner(kwq, kwq->kw_owner,
&kwq->kw_turnstile);
ksyn_wqunlock(kwq);
- _kwq_cleanup_old_owner(&old_owner);
goto out;
}
old_owner = _kwq_set_owner(kwq, current_thread(), 0);
pthread_kern->psynch_wait_update_owner(kwq, kwq->kw_owner,
&kwq->kw_turnstile);
-
+
ksyn_wqunlock(kwq);
- _kwq_cleanup_old_owner(&old_owner);
*retval = updatebits;
goto out;
}
pthread_kern->thread_deallocate_safe(tid_th);
tid_th = THREAD_NULL;
}
+ assert(old_owner == THREAD_NULL);
error = ksyn_wait(kwq, KSYN_QUEUE_WRITE, mgen, ins_flags, 0, 0,
psynch_mtxcontinue, kThreadWaitPThreadMutex);
// ksyn_wait drops wait queue lock
if (tid_th) {
thread_deallocate(tid_th);
}
+ if (old_owner) {
+ thread_deallocate(old_owner);
+ }
return error;
}
#define __QOS_AVAILABLE_10_11 __API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.0), watchos(2.0))
#undef __QOS_AVAILABLE_10_12
#define __QOS_AVAILABLE_10_12 __API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
+#undef __QOS_AVAILABLE_10_15_1
+#define __QOS_AVAILABLE_10_15_1 __API_AVAILABLE(macos(10.15.1), ios(13.2), tvos(13.2), watchos(6.2))
#endif
#endif
+// This enum matches workq_set_self_flags in
+// xnu's workqueue_internal.h.
__QOS_ENUM(_pthread_set_flags, unsigned int,
_PTHREAD_SET_SELF_QOS_FLAG __QOS_AVAILABLE_10_10 = 0x1,
_PTHREAD_SET_SELF_VOUCHER_FLAG __QOS_AVAILABLE_10_10 = 0x2,
_PTHREAD_SET_SELF_FIXEDPRIORITY_FLAG __QOS_AVAILABLE_10_11 = 0x4,
_PTHREAD_SET_SELF_TIMESHARE_FLAG __QOS_AVAILABLE_10_11 = 0x8,
_PTHREAD_SET_SELF_WQ_KEVENT_UNBIND __QOS_AVAILABLE_10_12 = 0x10,
+ _PTHREAD_SET_SELF_ALTERNATE_AMX __QOS_AVAILABLE_10_15_1 = 0x20,
);
#undef __QOS_ENUM
int
pthread_set_timeshare_self(void);
+// Set self to avoid running on the same AMX as
+// other work in this group.
+// Only allowed on non-workqueue pthreads
+__API_AVAILABLE(macos(10.15.1), ios(13.2), tvos(13.2), watchos(6.2))
+int
+pthread_prefer_alternate_amx_self(void);
+
/*!
* @const PTHREAD_MAX_PARALLELISM_PHYSICAL
* Flag that can be used with pthread_qos_max_parallelism() and
#define _PTHREAD_SET_SELF_OUTSIDE_QOS_SKIP \
(_PTHREAD_SET_SELF_QOS_FLAG | _PTHREAD_SET_SELF_FIXEDPRIORITY_FLAG | \
- _PTHREAD_SET_SELF_TIMESHARE_FLAG)
+ _PTHREAD_SET_SELF_TIMESHARE_FLAG | \
+ _PTHREAD_SET_SELF_ALTERNATE_AMX)
int
_pthread_set_properties_self(_pthread_set_flags_t flags,
return _pthread_set_properties_self(_PTHREAD_SET_SELF_TIMESHARE_FLAG, 0, 0);
}
+int
+pthread_prefer_alternate_amx_self(void)
+{
+ return _pthread_set_properties_self(_PTHREAD_SET_SELF_ALTERNATE_AMX, 0, 0);
+}
+
+
pthread_override_t
pthread_override_qos_class_start_np(pthread_t thread, qos_class_t qc, int relpri)
{