#include <kern/timer_call.h>
#include <kern/waitq.h>
#include <kern/ledger.h>
+#include <kern/policy_internal.h>
+
#include <pexpert/pexpert.h>
#include <libkern/kernel_mach_header.h>
*
* The pset lock may also be taken, but not while any other locks are held.
*
+ * The task and thread mutex may also be held while reevaluating sfi state.
+ *
* splsched ---> sfi_lock ---> waitq ---> thread_lock
* \ \ \__ thread_lock (*)
* \ \__ pset_lock
task_t task = thread->task;
boolean_t is_kernel_thread = (task == kernel_task);
sched_mode_t thmode = thread->sched_mode;
- int latency_qos = proc_get_effective_task_policy(task, TASK_POLICY_LATENCY_QOS);
- int task_role = proc_get_effective_task_policy(task, TASK_POLICY_ROLE);
- int thread_bg = proc_get_effective_thread_policy(thread, TASK_POLICY_DARWIN_BG);
- int managed_task = proc_get_effective_task_policy(task, TASK_POLICY_SFI_MANAGED);
- int thread_qos = proc_get_effective_thread_policy(thread, TASK_POLICY_QOS);
boolean_t focal = FALSE;
+ int task_role = proc_get_effective_task_policy(task, TASK_POLICY_ROLE);
+ int latency_qos = proc_get_effective_task_policy(task, TASK_POLICY_LATENCY_QOS);
+ int managed_task = proc_get_effective_task_policy(task, TASK_POLICY_SFI_MANAGED);
+
+ int thread_qos = proc_get_effective_thread_policy(thread, TASK_POLICY_QOS);
+ int thread_bg = proc_get_effective_thread_policy(thread, TASK_POLICY_DARWIN_BG);
+
/* kernel threads never reach the user AST boundary, and are in a separate world for SFI */
if (is_kernel_thread) {
return SFI_CLASS_KERNEL;
uint64_t tid;
thread_continue_t continuation;
sched_call_t workq_callback = workqueue_get_sched_callback();
- boolean_t did_clear_wq = FALSE;
s = splsched();
/* Optimistically clear workq callback while thread is already locked */
if (workq_callback && (thread->sched_call == workq_callback)) {
thread_sched_call(thread, NULL);
- did_clear_wq = TRUE;
+ } else {
+ workq_callback = NULL;
}
thread_unlock(thread);
splx(s);
if (did_wait) {
- thread_block_reason(continuation, did_clear_wq ? workq_callback : NULL, AST_SFI);
- } else {
- if (did_clear_wq) {
- s = splsched();
- thread_lock(thread);
- thread_sched_call(thread, workq_callback);
- thread_unlock(thread);
- splx(s);
- }
+ thread_block_reason(continuation, workq_callback, AST_SFI);
+ } else if (workq_callback) {
+ thread_reenable_sched_call(thread, workq_callback);
}
}