+int
+_pthread_workqueue_asynchronous_override_add(mach_port_t thread, pthread_priority_t priority, void *resource)
+{
+ int res = __bsdthread_ctl(BSDTHREAD_CTL_QOS_DISPATCH_ASYNCHRONOUS_OVERRIDE_ADD, thread, priority, (uintptr_t)resource);
+ if (res == -1) { res = errno; }
+ return res;
+}
+
+int
+_pthread_workqueue_asynchronous_override_reset_self(void *resource)
+{
+ int res = __bsdthread_ctl(BSDTHREAD_CTL_QOS_DISPATCH_ASYNCHRONOUS_OVERRIDE_RESET,
+ 0 /* !reset_all */,
+ (uintptr_t)resource,
+ 0);
+ if (res == -1) { res = errno; }
+ return res;
+}
+
+int
+_pthread_workqueue_asynchronous_override_reset_all_self(void)
+{
+ int res = __bsdthread_ctl(BSDTHREAD_CTL_QOS_DISPATCH_ASYNCHRONOUS_OVERRIDE_RESET,
+ 1 /* reset_all */,
+ 0,
+ 0);
+ if (res == -1) { res = errno; }
+ return res;
+}
+
+static inline uint16_t
+_pthread_workqueue_parallelism_for_priority(int qos, unsigned long flags)
+{
+ int rc = __bsdthread_ctl(BSDTHREAD_CTL_QOS_MAX_PARALLELISM, qos, flags, 0);
+ if (os_unlikely(rc == -1)) {
+ rc = errno;
+ if (rc != EINVAL) {
+ PTHREAD_INTERNAL_CRASH(rc, "qos_max_parallelism failed");
+ }
+ if (flags & _PTHREAD_QOS_PARALLELISM_COUNT_LOGICAL) {
+ return *(uint8_t *)_COMM_PAGE_LOGICAL_CPUS;
+ } else {
+ return *(uint8_t *)_COMM_PAGE_PHYSICAL_CPUS;
+ }
+ }
+ return (uint16_t)rc;
+}
+
+int
+pthread_qos_max_parallelism(qos_class_t qos, unsigned long flags)
+{
+ thread_qos_t thread_qos;
+ if (qos == QOS_CLASS_UNSPECIFIED) {
+ qos = QOS_CLASS_DEFAULT; // <rdar://problem/35080198>
+ }
+ thread_qos = _pthread_qos_class_to_thread_qos(qos);
+ if (thread_qos == THREAD_QOS_UNSPECIFIED) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ unsigned long syscall_flags = _PTHREAD_QOS_PARALLELISM_COUNT_LOGICAL;
+ uint16_t *ptr = &_pthread_globals()->qmp_logical[thread_qos];
+
+ if (flags & PTHREAD_MAX_PARALLELISM_PHYSICAL) {
+ syscall_flags = 0;
+ ptr = &_pthread_globals()->qmp_physical[thread_qos];
+ }
+ if (*ptr == 0) {
+ *ptr = _pthread_workqueue_parallelism_for_priority(thread_qos, syscall_flags);
+ }
+ return *ptr;
+}
+
+int
+pthread_time_constraint_max_parallelism(unsigned long flags)
+{
+ unsigned long syscall_flags = _PTHREAD_QOS_PARALLELISM_COUNT_LOGICAL;
+ uint16_t *ptr = &_pthread_globals()->qmp_logical[0];
+
+ if (flags & PTHREAD_MAX_PARALLELISM_PHYSICAL) {
+ syscall_flags = 0;
+ ptr = &_pthread_globals()->qmp_physical[0];
+ }
+ if (*ptr == 0) {
+ *ptr = _pthread_workqueue_parallelism_for_priority(0,
+ syscall_flags | _PTHREAD_QOS_PARALLELISM_REALTIME);
+ }
+ return *ptr;
+}
+