+ cpu_load_info->cpu_ticks[CPU_STATE_NICE] = 0;
+
+ simple_lock(&processor_list_lock);
+
+ for (processor = processor_list; processor != NULL; processor = processor->processor_list) {
+ timer_t idle_state;
+ uint64_t idle_time_snapshot1, idle_time_snapshot2;
+ uint64_t idle_time_tstamp1, idle_time_tstamp2;
+
+ /* See discussion in processor_info(PROCESSOR_CPU_LOAD_INFO) */
+
+ GET_TICKS_VALUE_FROM_TIMER(processor, CPU_STATE_USER, user_state);
+ if (precise_user_kernel_time) {
+ GET_TICKS_VALUE_FROM_TIMER(processor, CPU_STATE_SYSTEM, system_state);
+ } else {
+ /* system_state may represent either sys or user */
+ GET_TICKS_VALUE_FROM_TIMER(processor, CPU_STATE_USER, system_state);
+ }
+
+ idle_state = &PROCESSOR_DATA(processor, idle_state);
+ idle_time_snapshot1 = timer_grab(idle_state);
+ idle_time_tstamp1 = idle_state->tstamp;
+
+ if (PROCESSOR_DATA(processor, current_state) != idle_state) {
+ /* Processor is non-idle, so idle timer should be accurate */
+ GET_TICKS_VALUE_FROM_TIMER(processor, CPU_STATE_IDLE, idle_state);
+ } else if ((idle_time_snapshot1 != (idle_time_snapshot2 = timer_grab(idle_state))) ||
+ (idle_time_tstamp1 != (idle_time_tstamp2 = idle_state->tstamp))) {
+ /* Idle timer is being updated concurrently, second stamp is good enough */
+ GET_TICKS_VALUE(CPU_STATE_IDLE, idle_time_snapshot2);
+ } else {
+ /*
+ * Idle timer may be very stale. Fortunately we have established
+ * that idle_time_snapshot1 and idle_time_tstamp1 are unchanging
+ */
+ idle_time_snapshot1 += mach_absolute_time() - idle_time_tstamp1;
+
+ GET_TICKS_VALUE(CPU_STATE_IDLE, idle_time_snapshot1);
+ }
+ }
+ simple_unlock(&processor_list_lock);
+
+ *count = HOST_CPU_LOAD_INFO_COUNT;
+
+ return (KERN_SUCCESS);
+ }
+
+ case HOST_EXPIRED_TASK_INFO: {
+ if (*count < TASK_POWER_INFO_COUNT) {
+ return (KERN_FAILURE);
+ }
+
+ task_power_info_t tinfo = (task_power_info_t)info;
+
+ tinfo->task_interrupt_wakeups = dead_task_statistics.task_interrupt_wakeups;
+ tinfo->task_platform_idle_wakeups = dead_task_statistics.task_platform_idle_wakeups;
+
+ tinfo->task_timer_wakeups_bin_1 = dead_task_statistics.task_timer_wakeups_bin_1;
+
+ tinfo->task_timer_wakeups_bin_2 = dead_task_statistics.task_timer_wakeups_bin_2;
+
+ tinfo->total_user = dead_task_statistics.total_user_time;
+ tinfo->total_system = dead_task_statistics.total_system_time;
+
+ return (KERN_SUCCESS);
+ }
+ default: return (KERN_INVALID_ARGUMENT);
+ }
+}
+
+extern uint32_t c_segment_pages_compressed;
+
+kern_return_t
+host_statistics64(host_t host, host_flavor_t flavor, host_info64_t info, mach_msg_type_number_t * count)
+{
+ uint32_t i;
+
+ if (host == HOST_NULL)
+ return (KERN_INVALID_HOST);
+
+ switch (flavor) {
+ case HOST_VM_INFO64: /* We were asked to get vm_statistics64 */
+ {
+ register processor_t processor;
+ register vm_statistics64_t stat;
+ vm_statistics64_data_t host_vm_stat;
+ mach_msg_type_number_t original_count;
+ unsigned int local_q_internal_count;
+ unsigned int local_q_external_count;
+
+ if (*count < HOST_VM_INFO64_REV0_COUNT)
+ return (KERN_FAILURE);