#ifndef _KERN_SCHED_PRIM_H_
#define _KERN_SCHED_PRIM_H_
#include <mach/boolean.h>
#include <mach/machine/vm_types.h>
#include <mach/kern_return.h>
#include <kern/clock.h>
#include <kern/kern_types.h>
#include <kern/thread.h>
#include <sys/cdefs.h>
#ifdef MACH_KERNEL_PRIVATE
extern void sched_init(void) __attribute__((section("__TEXT, initcode")));
extern void sched_startup(void);
extern void sched_timebase_init(void);
extern boolean_t thread_stop(
thread_t thread);
extern void thread_unstop(
thread_t thread);
extern void thread_wait(
thread_t thread,
boolean_t until_not_runnable);
extern boolean_t thread_unblock(
thread_t thread,
wait_result_t wresult);
extern kern_return_t thread_go(
thread_t thread,
wait_result_t wresult);
extern void thread_dispatch(
thread_t old_thread,
thread_t new_thread);
extern int thread_run(
thread_t self,
thread_continue_t continuation,
void *parameter,
thread_t new_thread);
extern void thread_continue(
thread_t old_thread);
extern void call_continuation(
thread_continue_t continuation,
void *parameter,
wait_result_t wresult);
extern void set_sched_pri(
thread_t thread,
int priority);
extern void set_priority(
thread_t thread,
int priority);
extern void compute_priority(
thread_t thread,
boolean_t override_depress);
extern void compute_my_priority(
thread_t thread);
extern void sched_init_thread(void (*)(void));
extern boolean_t can_update_priority(
thread_t thread);
extern void update_priority(
thread_t thread);
extern void lightweight_update_priority(
thread_t thread);
extern void sched_traditional_quantum_expire(thread_t thread);
extern void idle_thread(void);
extern kern_return_t idle_thread_create(
processor_t processor);
extern void thread_syscall_return(
kern_return_t ret);
extern wait_result_t thread_block_reason(
thread_continue_t continuation,
void *parameter,
ast_t reason);
extern void thread_setrun(
thread_t thread,
integer_t options);
#define SCHED_TAILQ 1
#define SCHED_HEADQ 2
#define SCHED_PREEMPT 4
extern processor_set_t task_choose_pset(
task_t task);
extern processor_t thread_bind(
processor_t processor);
extern processor_t choose_processor(
processor_set_t pset,
processor_t processor,
thread_t thread);
extern thread_t choose_thread(
processor_t processor,
run_queue_t runq,
int priority);
extern void thread_quantum_init(
thread_t thread);
extern void run_queue_init(
run_queue_t runq);
extern thread_t run_queue_dequeue(
run_queue_t runq,
integer_t options);
extern boolean_t run_queue_enqueue(
run_queue_t runq,
thread_t thread,
integer_t options);
extern void run_queue_remove(
run_queue_t runq,
thread_t thread);
extern boolean_t thread_run_queue_remove(
thread_t thread);
extern void thread_timer_expire(
void *thread,
void *p1);
extern boolean_t thread_eager_preemption(
thread_t thread);
#if defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_PROTO) || defined(CONFIG_SCHED_FIXEDPRIORITY)
void sched_traditional_fairshare_init(void);
int sched_traditional_fairshare_runq_count(void);
uint64_t sched_traditional_fairshare_runq_stats_count_sum(void);
void sched_traditional_fairshare_enqueue(thread_t thread);
thread_t sched_traditional_fairshare_dequeue(void);
boolean_t sched_traditional_fairshare_queue_remove(thread_t thread);
#endif
#if defined(CONFIG_SCHED_GRRR) || defined(CONFIG_SCHED_FIXEDPRIORITY)
void sched_grrr_fairshare_init(void);
int sched_grrr_fairshare_runq_count(void);
uint64_t sched_grrr_fairshare_runq_stats_count_sum(void);
void sched_grrr_fairshare_enqueue(thread_t thread);
thread_t sched_grrr_fairshare_dequeue(void);
boolean_t sched_grrr_fairshare_queue_remove(thread_t thread);
#endif
extern boolean_t sched_generic_direct_dispatch_to_idle_processors;
__private_extern__ wait_interrupt_t thread_interrupt_level(
wait_interrupt_t interruptible);
__private_extern__ wait_result_t thread_mark_wait_locked(
thread_t thread,
wait_interrupt_t interruptible);
__private_extern__ kern_return_t clear_wait_internal(
thread_t thread,
wait_result_t result);
extern void sched_stats_handle_csw(
processor_t processor,
int reasons,
int selfpri,
int otherpri);
extern void sched_stats_handle_runq_change(
struct runq_stats *stats,
int old_count);
#define SCHED_STATS_CSW(processor, reasons, selfpri, otherpri) \
do { \
if (__builtin_expect(sched_stats_active, 0)) { \
sched_stats_handle_csw((processor), \
(reasons), (selfpri), (otherpri)); \
} \
} while (0)
#define SCHED_STATS_RUNQ_CHANGE(stats, old_count) \
do { \
if (__builtin_expect(sched_stats_active, 0)) { \
sched_stats_handle_runq_change((stats), \
(old_count)); \
} \
} while (0)
#define THREAD_URGENCY_NONE 0
#define THREAD_URGENCY_BACKGROUND 1
#define THREAD_URGENCY_NORMAL 2
#define THREAD_URGENCY_REAL_TIME 3
#define THREAD_URGENCY_MAX 4
extern int thread_get_urgency(
uint64_t *rt_period,
uint64_t *rt_deadline);
extern void thread_tell_urgency(
int urgency,
uint64_t rt_period,
uint64_t rt_deadline);
extern void active_rt_threads(
boolean_t active);
#endif
__BEGIN_DECLS
#ifdef XNU_KERNEL_PRIVATE
extern boolean_t assert_wait_possible(void);
extern kern_return_t clear_wait(
thread_t thread,
wait_result_t result);
extern void thread_bootstrap_return(void);
extern void thread_exception_return(void) __dead2;
#endif
extern wait_result_t thread_block(
thread_continue_t continuation);
extern wait_result_t thread_block_parameter(
thread_continue_t continuation,
void *parameter);
extern wait_result_t assert_wait(
event_t event,
wait_interrupt_t interruptible);
extern wait_result_t assert_wait_timeout(
event_t event,
wait_interrupt_t interruptible,
uint32_t interval,
uint32_t scale_factor);
extern wait_result_t assert_wait_deadline(
event_t event,
wait_interrupt_t interruptible,
uint64_t deadline);
extern kern_return_t thread_wakeup_prim(
event_t event,
boolean_t one_thread,
wait_result_t result);
extern kern_return_t thread_wakeup_prim_internal(
event_t event,
boolean_t one_thread,
wait_result_t result,
int priority);
#define thread_wakeup(x) \
thread_wakeup_prim((x), FALSE, THREAD_AWAKENED)
#define thread_wakeup_with_result(x, z) \
thread_wakeup_prim((x), FALSE, (z))
#define thread_wakeup_one(x) \
thread_wakeup_prim((x), TRUE, THREAD_AWAKENED)
#ifdef MACH_KERNEL_PRIVATE
#define thread_wakeup_one_with_pri(x, pri) \
thread_wakeup_prim_internal((x), TRUE, THREAD_AWAKENED, pri)
#endif
extern boolean_t preemption_enabled(void);
#ifdef KERNEL_PRIVATE
#ifndef __LP64__
extern void thread_set_timer(
uint32_t interval,
uint32_t scale_factor);
extern void thread_set_timer_deadline(
uint64_t deadline);
extern void thread_cancel_timer(void);
#ifndef MACH_KERNEL_PRIVATE
#ifndef ABSOLUTETIME_SCALAR_TYPE
#define thread_set_timer_deadline(a) \
thread_set_timer_deadline(__OSAbsoluteTime(a))
#endif
#endif
#endif
#endif
#ifdef MACH_KERNEL_PRIVATE
#if !defined(CONFIG_SCHED_TRADITIONAL) && !defined(CONFIG_SCHED_PROTO) && !defined(CONFIG_SCHED_GRRR) && !defined(CONFIG_SCHED_FIXEDPRIORITY)
#error Enable at least one scheduler algorithm in osfmk/conf/MASTER.XXX
#endif
#define SCHED(f) (sched_current_dispatch->f)
struct sched_dispatch_table {
void (*init)(void);
void (*timebase_init)(void);
void (*processor_init)(processor_t processor);
void (*pset_init)(processor_set_t pset);
void (*maintenance_continuation)(void);
thread_t (*choose_thread)(
processor_t processor,
int priority);
thread_t (*steal_thread)(
processor_set_t pset);
void (*compute_priority)(
thread_t thread,
boolean_t override_depress);
processor_t (*choose_processor)(
processor_set_t pset,
processor_t processor,
thread_t thread);
boolean_t (*processor_enqueue)(
processor_t processor,
thread_t thread,
integer_t options);
void (*processor_queue_shutdown)(
processor_t processor);
boolean_t (*processor_queue_remove)(
processor_t processor,
thread_t thread);
boolean_t (*processor_queue_empty)(processor_t processor);
boolean_t (*priority_is_urgent)(int priority);
ast_t (*processor_csw_check)(processor_t processor);
boolean_t (*processor_queue_has_priority)(processor_t processor,
int priority,
boolean_t gte);
uint32_t (*initial_quantum_size)(thread_t thread);
sched_mode_t (*initial_thread_sched_mode)(task_t parent_task);
boolean_t (*supports_timeshare_mode)(void);
boolean_t (*can_update_priority)(thread_t thread);
void (*update_priority)(thread_t thread);
void (*lightweight_update_priority)(thread_t thread);
void (*quantum_expire)(thread_t thread);
boolean_t (*should_current_thread_rechoose_processor)(processor_t processor);
int (*processor_runq_count)(processor_t processor);
uint64_t (*processor_runq_stats_count_sum)(processor_t processor);
void (*fairshare_init)(void);
int (*fairshare_runq_count)(void);
uint64_t (*fairshare_runq_stats_count_sum)(void);
void (*fairshare_enqueue)(thread_t thread);
thread_t (*fairshare_dequeue)(void);
boolean_t (*fairshare_queue_remove)(thread_t thread);
boolean_t direct_dispatch_to_idle_processors;
};
#if defined(CONFIG_SCHED_TRADITIONAL)
#define kSchedTraditionalString "traditional"
#define kSchedTraditionalWithPsetRunqueueString "traditional_with_pset_runqueue"
extern const struct sched_dispatch_table sched_traditional_dispatch;
extern const struct sched_dispatch_table sched_traditional_with_pset_runqueue_dispatch;
#endif
#if defined(CONFIG_SCHED_PROTO)
#define kSchedProtoString "proto"
extern const struct sched_dispatch_table sched_proto_dispatch;
#endif
#if defined(CONFIG_SCHED_GRRR)
#define kSchedGRRRString "grrr"
extern const struct sched_dispatch_table sched_grrr_dispatch;
#endif
#if defined(CONFIG_SCHED_FIXEDPRIORITY)
#define kSchedFixedPriorityString "fixedpriority"
#define kSchedFixedPriorityWithPsetRunqueueString "fixedpriority_with_pset_runqueue"
extern const struct sched_dispatch_table sched_fixedpriority_dispatch;
extern const struct sched_dispatch_table sched_fixedpriority_with_pset_runqueue_dispatch;
#endif
enum sched_enum {
sched_enum_unknown = 0,
#if defined(CONFIG_SCHED_TRADITIONAL)
sched_enum_traditional = 1,
sched_enum_traditional_with_pset_runqueue = 2,
#endif
#if defined(CONFIG_SCHED_PROTO)
sched_enum_proto = 3,
#endif
#if defined(CONFIG_SCHED_GRRR)
sched_enum_grrr = 4,
#endif
#if defined(CONFIG_SCHED_FIXEDPRIORITY)
sched_enum_fixedpriority = 5,
sched_enum_fixedpriority_with_pset_runqueue = 6,
#endif
sched_enum_max = 7
};
extern const struct sched_dispatch_table *sched_current_dispatch;
#endif
__END_DECLS
#endif