#include <mach/kern_return.h>
#include <kern/kern_types.h>
-extern struct processor_set default_pset;
-extern processor_t master_processor;
+#include <sys/appleapiopts.h>
+
+#ifdef __APPLE_API_PRIVATE
-#ifdef MACH_KERNEL_PRIVATE
+#ifdef MACH_KERNEL_PRIVATE
#include <cpus.h>
-#include <mach_host.h>
#include <mach/mach_types.h>
#include <kern/cpu_number.h>
#include <kern/queue.h>
#include <kern/sched.h>
-#if NCPUS > 1
#include <machine/ast_types.h>
-#endif /* NCPUS > 1 */
struct processor_set {
- struct run_queue runq; /* runq for this set */
queue_head_t idle_queue; /* idle processors */
int idle_count; /* how many ? */
- decl_simple_lock_data(,idle_lock) /* lock for above */
+ queue_head_t active_queue; /* active processors */
+
queue_head_t processors; /* all processors here */
int processor_count;/* how many ? */
- decl_simple_lock_data(,processors_lock) /* lock for above */
+ decl_simple_lock_data(,sched_lock) /* lock for above */
+
+ struct run_queue runq; /* runq for this set */
+
queue_head_t tasks; /* tasks assigned */
int task_count; /* how many */
queue_head_t threads; /* threads in this set */
int thread_count; /* how many */
int ref_count; /* structure ref count */
boolean_t active; /* is pset in use */
- decl_mutex_data(, lock) /* lock for everything else */
+ decl_mutex_data(, lock) /* lock for above */
+
+ int timeshare_quanta; /* timeshare quantum factor */
+ int quantum_factors[NCPUS+1];
+
struct ipc_port * pset_self; /* port for operations */
struct ipc_port * pset_name_self; /* port for information */
- int max_priority; /* maximum priority */
- int policies; /* bit vector for policies */
- int set_quantum; /* current default quantum */
-#if NCPUS > 1
- int quantum_adj_index; /* runtime quantum adj. */
- decl_simple_lock_data(,quantum_adj_lock) /* lock for above */
- int machine_quantum[NCPUS+1]; /* ditto */
-#endif /* NCPUS > 1 */
+
+ uint32_t run_count; /* threads running in set */
+ uint32_t share_count; /* timeshare threads running in set */
+
integer_t mach_factor; /* mach_factor */
integer_t load_average; /* load_average */
- long sched_load; /* load avg for scheduler */
- policy_t policy_default; /* per set default */
- policy_base_data_t policy_base; /* base attributes */
- policy_limit_data_t policy_limit; /* limit attributes */
+ uint32_t sched_load; /* load avg for scheduler */
};
struct processor {
- struct run_queue runq; /* local runq for this processor */
- queue_chain_t processor_queue;/* idle/assign/shutdown queue link */
+ queue_chain_t processor_queue;/* idle/active/action queue link,
+ * MUST remain the first element */
int state; /* See below */
- struct thread_shuttle
+ struct thread
+ *active_thread, /* thread running on processor */
*next_thread, /* next thread to run if dispatched */
*idle_thread; /* this processor's idle thread. */
- int quantum; /* quantum for current thread */
- boolean_t first_quantum; /* first quantum in succession */
- int last_quantum; /* last quantum assigned */
- processor_set_t processor_set; /* processor set I belong to */
- processor_set_t processor_set_next; /* set I will belong to */
- queue_chain_t processors; /* all processors in set */
+ processor_set_t processor_set; /* current membership */
+
+ int current_pri; /* priority of current thread */
+
+ timer_call_data_t quantum_timer; /* timer for quantum expiration */
+ uint64_t quantum_end; /* time when current quantum ends */
+ uint64_t last_dispatch; /* time of last dispatch */
+
+ int timeslice; /* quanta before timeslice ends */
+ uint64_t deadline; /* current deadline */
+
+ struct run_queue runq; /* local runq for this processor */
+
+ queue_chain_t processors; /* all processors in set */
decl_simple_lock_data(,lock)
struct ipc_port *processor_self;/* port for operations */
int slot_num; /* machine-indep slot number */
-#if NCPUS > 1
- ast_check_t ast_check_data; /* for remote ast_check invocation */
- queue_chain_t softclock_queue;/* cpus handling softclocks */
-#endif /* NCPUS > 1 */
- /* punt id data temporarily */
};
+extern struct processor_set default_pset;
+extern processor_t master_processor;
+
extern struct processor processor_array[NCPUS];
/*
* Values for the processor state are defined below. If the processor
* is off-line or being shutdown, then it is only necessary to lock
* the processor to change its state. Otherwise it is only necessary
- * to lock its processor set's idle_lock. Scheduler code will
- * typically lock only the idle_lock, but processor manipulation code
+ * to lock its processor set's sched_lock. Scheduler code will
+ * typically lock only the sched_lock, but processor manipulation code
* will often lock both.
*/
-#define PROCESSOR_OFF_LINE 0 /* Not in system */
-#define PROCESSOR_RUNNING 1 /* Running a normal thread */
-#define PROCESSOR_IDLE 2 /* idle */
-#define PROCESSOR_DISPATCHING 3 /* dispatching (idle -> running) */
-#define PROCESSOR_ASSIGN 4 /* Assignment is changing */
-#define PROCESSOR_SHUTDOWN 5 /* Being shutdown */
-#define PROCESSOR_START 6 /* Being start */
+#define PROCESSOR_OFF_LINE 0 /* Not available */
+#define PROCESSOR_RUNNING 1 /* Normal execution */
+#define PROCESSOR_IDLE 2 /* Idle */
+#define PROCESSOR_DISPATCHING 3 /* Dispatching (idle -> running) */
+#define PROCESSOR_SHUTDOWN 4 /* Going off-line */
+#define PROCESSOR_START 5 /* Being started */
/*
* Use processor ptr array to find current processor's data structure.
#define cpu_to_processor(i) (processor_ptr[i])
#define current_processor() (processor_ptr[cpu_number()])
-#define current_processor_set() (current_processor()->processor_set)
/* Compatibility -- will go away */
#define processor_lock(pr) simple_lock(&(pr)->lock)
#define processor_unlock(pr) simple_unlock(&(pr)->lock)
-
extern void pset_sys_bootstrap(void);
-/* Implemented by MD layer */
+#define timeshare_quanta_update(pset) \
+MACRO_BEGIN \
+ int proc_count = (pset)->processor_count; \
+ int runq_count = (pset)->runq.count; \
+ \
+ (pset)->timeshare_quanta = (pset)->quantum_factors[ \
+ (runq_count > proc_count)? \
+ proc_count: runq_count]; \
+MACRO_END
+
+#define pset_run_incr(pset) \
+ hw_atomic_add(&(pset)->run_count, 1)
+
+#define pset_run_decr(pset) \
+ hw_atomic_sub(&(pset)->run_count, 1)
+
+#define pset_share_incr(pset) \
+ hw_atomic_add(&(pset)->share_count, 1)
+
+#define pset_share_decr(pset) \
+ hw_atomic_sub(&(pset)->share_count, 1)
extern void cpu_up(
- int cpu);
+ int cpu);
extern kern_return_t processor_shutdown(
- processor_t processor);
+ processor_t processor);
extern void pset_remove_processor(
- processor_set_t pset,
- processor_t processor);
+ processor_set_t pset,
+ processor_t processor);
extern void pset_add_processor(
- processor_set_t pset,
- processor_t processor);
+ processor_set_t pset,
+ processor_t processor);
extern void pset_remove_task(
- processor_set_t pset,
- task_t task);
+ processor_set_t pset,
+ task_t task);
extern void pset_add_task(
- processor_set_t pset,
- task_t task);
+ processor_set_t pset,
+ task_t task);
extern void pset_remove_thread(
- processor_set_t pset,
- thread_t thread);
+ processor_set_t pset,
+ thread_t thread);
extern void pset_add_thread(
- processor_set_t pset,
- thread_t thread);
+ processor_set_t pset,
+ thread_t thread);
extern void thread_change_psets(
- thread_t thread,
- processor_set_t old_pset,
- processor_set_t new_pset);
-
-extern void pset_deallocate(
- processor_set_t pset);
-
-extern void pset_reference(
- processor_set_t pset);
+ thread_t thread,
+ processor_set_t old_pset,
+ processor_set_t new_pset);
extern kern_return_t processor_assign(
- processor_t processor,
- processor_set_t new_pset,
- boolean_t wait);
+ processor_t processor,
+ processor_set_t new_pset,
+ boolean_t wait);
extern kern_return_t processor_info_count(
- processor_flavor_t flavor,
- mach_msg_type_number_t *count);
-#endif /* MACH_KERNEL_PRIVATE */
+ processor_flavor_t flavor,
+ mach_msg_type_number_t *count);
+
+#endif /* MACH_KERNEL_PRIVATE */
extern kern_return_t processor_start(
- processor_t processor);
+ processor_t processor);
extern kern_return_t processor_exit(
- processor_t processor);
+ processor_t processor);
+
+#endif /* __APPLE_API_PRIVATE */
+
+extern void pset_deallocate(
+ processor_set_t pset);
+
+extern void pset_reference(
+ processor_set_t pset);
#endif /* _KERN_PROCESSOR_H_ */