概述
本文檔對比分析 XNU 內(nèi)核中兩個核心線程優(yōu)先級調(diào)整函數(shù)的完整調(diào)用鏈路:
-
workq_thread_reset_pri - 工作隊列優(yōu)先級重置(由內(nèi)核調(diào)度器調(diào)用)
-
bsdthread_set_self - BSD 線程自我設(shè)置(由 bsdthread_set_self 系統(tǒng)調(diào)用觸發(fā))
分析范圍:僅針對 workqueue 線程(GCD 工作線程)
相關(guān)文件:
1. workq_thread_reset_pri 完整調(diào)用鏈路
workq_thread_reset_pri(wq, uth, req, unpark)
│
├─? uth->uu_workq_pri = WORKQ_POLICY_INIT(qos) [pthread_workqueue.c:710]
│ └─? 設(shè)置 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() 關(guān)閉中斷
│
├─? thread_lock(thread) 獲取 thread lock
│
├─? thread_compute_resolved_thread_group(...) 計算 resolved thread_group
│
├─? thread_group_retain(tg) 增加引用計數(shù)
│
├─? thread_group_deallocate_safe(old_tg) 釋放舊 thread_group
│
├─? thread->preadopt_thread_group = tg [thread_group.c:928-935]
│ └─? 設(shè)置preadopt_thread_group
│
├─? thread->thread_group = resolved_tg [thread_group.c:948+]
│ └─? **修改 thread->thread_group**
│
├─? thread_unlock(thread)
└─? splx(s)
繼續(xù):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]
│ │ │ └─? **可能觸發(fā) 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 完整調(diào)用鏈路
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)
繼續(xù):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 計數(shù)**
bsdthread_set_self
└─? workq_unlock(wq) [pthread_workqueue.c:2520]
└─? os_unfair_lock_unlock(&wq->wq_lock)
繼續(xù):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 結(jié)構(gòu)體
| 變量 |
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 結(jié)構(gòu)體
| 變量 |
workq_thread_reset_pri |
bsdthread_set_self |
preadopt_thread_group |
? 設(shè)置/清除 [928-935] |
? |
thread_group |
? 設(shè)置 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 結(jié)構(gòu)體
| 變量 |
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. 關(guān)鍵差異總結(jié)
| 操作 |
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 設(shè)置 |
? |
? |
性能影響
-
workq_thread_reset_pri:更重量級,涉及 thread_group 操作和可能的 runqueue 遷移
-
bsdthread_set_self:更輕量,僅修改 QoS 策略和 wq 計數(shù)
5. 適用場景
| 函數(shù) |
調(diào)用場景 |
用途 |
workq_thread_reset_pri |
內(nèi)核工作隊列調(diào)度 |
工作線程取新任務(wù)時調(diào)整優(yōu)先級 |
bsdthread_set_self |
用戶態(tài) API 調(diào)用 |
GCD _pthread_set_properties_self() 設(shè)置 QoS |
6. 參考調(diào)用命令
# 反匯編 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"