概述
本文档对比分析 XNU 内核中两个核心线程优先级调整函数的完整调用链路:
-
workq_thread_reset_pri - 工作队列优先级重置(由内核调度器调用)
-
bsdthread_set_self - BSD 线程自我设置(由 bsdthread_set_self 系统调用触发)
分析范围:仅针对 workqueue 线程(GCD 工作线程)
相关文件:
1. workq_thread_reset_pri 完整调用链路
workq_thread_reset_pri(wq, uth, req, unpark)
│
├─► uth->uu_workq_pri = WORKQ_POLICY_INIT(qos) [pthread_workqueue.c:710]
│ └─► 设置 uth->uu_workq_pri.qos_req, qos_relprio
│
├─► uth->uu_workq_flags &= ~UT_WORKQ_OUTSIDE_QOS [pthread_workqueue.c:711]
│
└─► thread_set_preadopt_thread_group(th, tg) [pthread_workqueue.c:819]
│
├─► splsched() 关闭中断
│
├─► thread_lock(thread) 获取 thread lock
│
├─► thread_compute_resolved_thread_group(...) 计算 resolved thread_group
│
├─► thread_group_retain(tg) 增加引用计数
│
├─► thread_group_deallocate_safe(old_tg) 释放旧 thread_group
│
├─► thread->preadopt_thread_group = tg [thread_group.c:928-935]
│ └─► 设置preadopt_thread_group
│
├─► thread->thread_group = resolved_tg [thread_group.c:948+]
│ └─► **修改 thread->thread_group**
│
├─► thread_unlock(thread)
└─► splx(s)
继续:thread_set_workq_pri 分支
workq_thread_reset_pri
└─► thread_set_workq_pri(th, qos, priority, policy) [pthread_workqueue.c:822]
│
├─► splsched()
├─► thread_lock(thread)
│
├─► proc_set_thread_policy_spinlocked(..., TASK_POLICY_QOS_AND_RELPRIO, ...)
│ │
│ ├─► thread_set_requested_policy_spinlocked(...) [thread_policy.c:2054]
│ │ │
│ │ └─► thread->requested_policy.thrp_qos = value [thread_policy.c:2130]
│ │ └─► thread->requested_policy.thrp_qos_relprio = v2 [thread_policy.c:2131]
│ │ └─► thread->requested_policy = requested [thread_policy.c:2200]
│ │
│ └─► thread_policy_update_spinlocked(...) [thread_policy.c:1597]
│ │
│ └─► thread_policy_update_internal_spinlocked(...) [thread_policy.c:1623]
│ │
│ ├─► thread_update_qos_cpu_time_locked()
│ │ └─► thread->vtimer_qos_save = ...
│ │
│ ├─► thread->effective_policy = next [thread_policy.c:1844]
│ │ └─► **修改 effective_policy**
│ │
│ ├─► thread_recompute_priority(thread) [thread_policy.c:1054]
│ │ │
│ │ └─► sched_set_thread_base_priority(thread, priority) [priority.c:285]
│ │ │
│ │ ├─► thread->req_base_pri = priority [priority.c:297]
│ │ ├─► thread->base_pri = priority [priority.c:301]
│ │ │ └─► **修改 thread->base_pri**
│ │ │
│ │ └─► thread_recompute_sched_pri(...) [priority.c:383]
│ │ │
│ │ └─► set_sched_pri(thread, new_priority) [sched_prim.c:5898]
│ │ │
│ │ ├─► thread_run_queue_remove(thread) [sched_prim.c:5930]
│ │ │ └─► **可能触发 runqueue 迁移**
│ │ │
│ │ ├─► thread->sched_pri = new_priority [sched_prim.c:5933]
│ │ │ └─► **修改 thread->sched_pri**
│ │ │
│ │ └─► thread_run_queue_reinsert(...) [sched_prim.c:5956]
│ │
│ └─► [turnstile 更新: pend_token->tpt_update_turnstile]
│
├─► proc_set_thread_policy_spinlocked(..., TASK_POLICY_QOS_WORKQ_OVERRIDE, ...)
│ └─► 清除 workq override
│
├─► thread_unlock(thread)
└─► splx(s)
2. bsdthread_set_self 完整调用链路
bsdthread_set_self(p, th, priority, voucher, flags)
│
└─► workq_lock_spin(wq) [pthread_workqueue.c:2472]
└─► os_unfair_lock_lock_with_options(&wq->wq_lock, 0)
继续:workq_thread_update_bucket 分支
bsdthread_set_self
└─► workq_thread_update_bucket(p, wq, uth, old_pri, new_pri, force_run)
│
├─► wq->wq_thactive_bucket_priority[...] += delta [pthread_workqueue.c]
│ └─► **修改 wq->wq_thactive_bucket_priority[]**
│
├─► wq->wq_constrained_threads_scheduled++/-- [pthread_workqueue.c:2498,2503]
│ └─► **修改 wq_constrained_threads_scheduled**
│
└─► _wq_cooperative_queue_scheduled_count_dec/inc() [pthread_workqueue.c:2507,2508]
└─► **修改 cooperative 计数**
bsdthread_set_self
└─► workq_unlock(wq) [pthread_workqueue.c:2520]
└─► os_unfair_lock_unlock(&wq->wq_lock)
继续:thread_policy_set_internal 分支
bsdthread_set_self
└─► thread_policy_set_internal(th, THREAD_QOS_POLICY, ...) [pthread_workqueue.c:2535]
│
├─► thread_mtx_lock(thread) [thread_policy.c:350]
│
├─► [THREAD_QOS_POLICY case] [thread_policy.c:591-618]
│ │
│ └─► proc_set_thread_policy_locked(...)
│ │
│ └─► proc_set_thread_policy_spinlocked(...)
│ │
│ ├─► thread_set_requested_policy_spinlocked(...)
│ │ └─► thread->requested_policy.thrp_qos = value
│ │ └─► thread->requested_policy.thrp_qos_relprio = value2
│ │
│ └─► thread_policy_update_internal_spinlocked(...)
│ │
│ ├─► thread->effective_policy = next
│ ├─► thread_recompute_priority(...)
│ │ └─► sched_set_thread_base_priority(...)
│ │ └─► thread_recompute_sched_pri(...)
│ │ └─► set_sched_pri(...)
│ │ ├─► thread_run_queue_remove (可能)
│ │ ├─► thread->sched_pri = ...
│ │ └─► thread_run_queue_reinsert (可能)
│ │
│ └─► [turnstile 更新]
│
└─► thread_mtx_unlock(thread)
3. 修改变量完整对比
3.1 uthread 结构体
| 变量 |
workq_thread_reset_pri |
bsdthread_set_self |
uu_workq_pri |
✅ 完整替换 [710] |
✅ qos_req/qos_override [2475,2488] |
uu_workq_flags |
✅ 清除 UT_WORKQ_OUTSIDE_QOS [711] |
❌ |
uu_kqr_bound |
❌ |
✅ 可能解绑 [2379] |
uu_save.park_data |
✅ [714-716] |
❌ |
3.2 thread 结构体
| 变量 |
workq_thread_reset_pri |
bsdthread_set_self |
preadopt_thread_group |
✅ 设置/清除 [928-935] |
❌ |
thread_group |
✅ 设置 resolved_tg [948+] |
❌ |
requested_policy.thrp_qos |
✅ [2130] |
✅ [615] |
requested_policy.thrp_qos_relprio |
✅ [2131] |
✅ [616] |
effective_policy |
✅ [1844] |
✅ [1844] |
base_pri |
✅ [301] |
✅ [301] |
sched_pri |
✅ [5933] |
✅ [5933] |
voucher |
❌ |
✅ [2544] |
3.3 workqueue 结构体
| 变量 |
workq_thread_reset_pri |
bsdthread_set_self |
wq_constrained_threads_scheduled |
❌ |
✅ [2498,2503] |
wq_thactive_bucket_priority[] |
✅ (间接) |
✅ |
wq_cooperative_queue_scheduled_count |
❌ |
✅ [2507,2508] |
4. 关键差异总结
| 操作 |
workq_thread_reset_pri |
bsdthread_set_self |
| thread_group/preadopt_thread_group |
✅ |
❌ |
| os_unfair_lock (wq) |
❌ |
✅ |
| thread_run_queue_remove |
✅ (可能) |
❌ |
| workq_thread_update_bucket |
✅ (间接) |
✅ (直接) |
| voucher 设置 |
❌ |
✅ |
性能影响
-
workq_thread_reset_pri:更重量级,涉及 thread_group 操作和可能的 runqueue 迁移
-
bsdthread_set_self:更轻量,仅修改 QoS 策略和 wq 计数
5. 适用场景
| 函数 |
调用场景 |
用途 |
workq_thread_reset_pri |
内核工作队列调度 |
工作线程取新任务时调整优先级 |
bsdthread_set_self |
用户态 API 调用 |
GCD _pthread_set_properties_self() 设置 QoS |
6. 参考调用命令
# 反汇编 workq_thread_reset_pri
lldb -b -o "target create --arch arm64e \"$KDK\"" -o "dis -n workq_thread_reset_pri -c 200"
# 反汇编 thread_set_preadopt_thread_group
lldb -b -o "target create --arch arm64e \"$KDK\"" -o "dis -n thread_set_preadopt_thread_group -c 200"
# 反汇编 thread_set_workq_pri
lldb -b -o "target create --arch arm64e \"$KDK\"" -o "dis -n thread_set_workq_pri -c 100"
# 反汇编 bsdthread_set_self
lldb -b -o "target create --arch arm64e \"$KDK\"" -o "dis -n bsdthread_set_self -c 300"
# 反汇编 set_sched_pri
lldb -b -o "target create --arch arm64e \"$KDK\"" -o "dis -n set_sched_pri -c 80"