void kdp_machine_hostinfo( kdp_hostinfo_t *hostinfo ) { int i; hostinfo->cpus_mask = 0; hostinfo->cpu_type = 0; for (i = 0; i < machine_info.max_cpus; i++) { if ((PerProcTable[i].ppe_vaddr == (struct per_proc_info *)NULL) || !(PerProcTable[i].ppe_vaddr->running)) continue; hostinfo->cpus_mask |= (1 << i); if (hostinfo->cpu_type == 0) { hostinfo->cpu_type = slot_type(i); hostinfo->cpu_subtype = slot_subtype(i); } } }
kern_return_t host_info( host_t host, host_flavor_t flavor, host_info_t info, mach_msg_type_number_t *count) { if (host == HOST_NULL) return (KERN_INVALID_ARGUMENT); switch (flavor) { case HOST_BASIC_INFO: { register host_basic_info_t basic_info; register int master_id; /* * Basic information about this host. */ if (*count < HOST_BASIC_INFO_OLD_COUNT) return (KERN_FAILURE); basic_info = (host_basic_info_t) info; basic_info->memory_size = machine_info.memory_size; basic_info->max_cpus = machine_info.max_cpus; basic_info->avail_cpus = processor_avail_count; master_id = master_processor->cpu_id; basic_info->cpu_type = slot_type(master_id); basic_info->cpu_subtype = slot_subtype(master_id); if (*count >= HOST_BASIC_INFO_COUNT) { basic_info->cpu_threadtype = slot_threadtype(master_id); basic_info->physical_cpu = machine_info.physical_cpu; basic_info->physical_cpu_max = machine_info.physical_cpu_max; basic_info->logical_cpu = machine_info.logical_cpu; basic_info->logical_cpu_max = machine_info.logical_cpu_max; basic_info->max_mem = machine_info.max_mem; *count = HOST_BASIC_INFO_COUNT; } else { *count = HOST_BASIC_INFO_OLD_COUNT; } return (KERN_SUCCESS); } case HOST_SCHED_INFO: { register host_sched_info_t sched_info; uint32_t quantum_time; uint64_t quantum_ns; /* * Return scheduler information. */ if (*count < HOST_SCHED_INFO_COUNT) return (KERN_FAILURE); sched_info = (host_sched_info_t) info; quantum_time = SCHED(initial_quantum_size)(THREAD_NULL); absolutetime_to_nanoseconds(quantum_time, &quantum_ns); sched_info->min_timeout = sched_info->min_quantum = (uint32_t)(quantum_ns / 1000 / 1000); *count = HOST_SCHED_INFO_COUNT; return (KERN_SUCCESS); } case HOST_RESOURCE_SIZES: { /* * Return sizes of kernel data structures */ if (*count < HOST_RESOURCE_SIZES_COUNT) return (KERN_FAILURE); /* XXX Fail until ledgers are implemented */ return (KERN_INVALID_ARGUMENT); } case HOST_PRIORITY_INFO: { register host_priority_info_t priority_info; if (*count < HOST_PRIORITY_INFO_COUNT) return (KERN_FAILURE); priority_info = (host_priority_info_t) info; priority_info->kernel_priority = MINPRI_KERNEL; priority_info->system_priority = MINPRI_KERNEL; priority_info->server_priority = MINPRI_RESERVED; priority_info->user_priority = BASEPRI_DEFAULT; priority_info->depress_priority = DEPRESSPRI; priority_info->idle_priority = IDLEPRI; priority_info->minimum_priority = MINPRI_USER; priority_info->maximum_priority = MAXPRI_RESERVED; *count = HOST_PRIORITY_INFO_COUNT; return (KERN_SUCCESS); } /* * Gestalt for various trap facilities. */ case HOST_MACH_MSG_TRAP: case HOST_SEMAPHORE_TRAPS: { *count = 0; return (KERN_SUCCESS); } default: return (KERN_INVALID_ARGUMENT); } }
kern_return_t processor_info( register processor_t processor, processor_flavor_t flavor, host_t *host, processor_info_t info, mach_msg_type_number_t *count) { register int cpu_id, state; kern_return_t result; if (processor == PROCESSOR_NULL) return (KERN_INVALID_ARGUMENT); cpu_id = processor->cpu_id; switch (flavor) { case PROCESSOR_BASIC_INFO: { register processor_basic_info_t basic_info; if (*count < PROCESSOR_BASIC_INFO_COUNT) return (KERN_FAILURE); basic_info = (processor_basic_info_t) info; basic_info->cpu_type = slot_type(cpu_id); basic_info->cpu_subtype = slot_subtype(cpu_id); state = processor->state; if (state == PROCESSOR_OFF_LINE) basic_info->running = FALSE; else basic_info->running = TRUE; basic_info->slot_num = cpu_id; if (processor == master_processor) basic_info->is_master = TRUE; else basic_info->is_master = FALSE; *count = PROCESSOR_BASIC_INFO_COUNT; *host = &realhost; return (KERN_SUCCESS); } case PROCESSOR_CPU_LOAD_INFO: { register processor_cpu_load_info_t cpu_load_info; if (*count < PROCESSOR_CPU_LOAD_INFO_COUNT) return (KERN_FAILURE); cpu_load_info = (processor_cpu_load_info_t) info; cpu_load_info->cpu_ticks[CPU_STATE_USER] = (uint32_t)(timer_grab(&PROCESSOR_DATA(processor, user_state)) / hz_tick_interval); cpu_load_info->cpu_ticks[CPU_STATE_SYSTEM] = (uint32_t)(timer_grab(&PROCESSOR_DATA(processor, system_state)) / hz_tick_interval); cpu_load_info->cpu_ticks[CPU_STATE_IDLE] = (uint32_t)(timer_grab(&PROCESSOR_DATA(processor, idle_state)) / hz_tick_interval); cpu_load_info->cpu_ticks[CPU_STATE_NICE] = 0; *count = PROCESSOR_CPU_LOAD_INFO_COUNT; *host = &realhost; return (KERN_SUCCESS); } default: result = cpu_info(flavor, cpu_id, info, count); if (result == KERN_SUCCESS) *host = &realhost; return (result); } }
kern_return_t processor_info( processor_t processor, processor_flavor_t flavor, host_t *host, processor_info_t info, mach_msg_type_number_t *count) { int cpu_id, state; kern_return_t result; if (processor == PROCESSOR_NULL) return (KERN_INVALID_ARGUMENT); cpu_id = processor->cpu_id; switch (flavor) { case PROCESSOR_BASIC_INFO: { processor_basic_info_t basic_info; if (*count < PROCESSOR_BASIC_INFO_COUNT) return (KERN_FAILURE); basic_info = (processor_basic_info_t) info; basic_info->cpu_type = slot_type(cpu_id); basic_info->cpu_subtype = slot_subtype(cpu_id); state = processor->state; if (state == PROCESSOR_OFF_LINE) basic_info->running = FALSE; else basic_info->running = TRUE; basic_info->slot_num = cpu_id; if (processor == master_processor) basic_info->is_master = TRUE; else basic_info->is_master = FALSE; *count = PROCESSOR_BASIC_INFO_COUNT; *host = &realhost; return (KERN_SUCCESS); } case PROCESSOR_CPU_LOAD_INFO: { processor_cpu_load_info_t cpu_load_info; timer_t idle_state; uint64_t idle_time_snapshot1, idle_time_snapshot2; uint64_t idle_time_tstamp1, idle_time_tstamp2; /* * We capture the accumulated idle time twice over * the course of this function, as well as the timestamps * when each were last updated. Since these are * all done using non-atomic racy mechanisms, the * most we can infer is whether values are stable. * timer_grab() is the only function that can be * used reliably on another processor's per-processor * data. */ if (*count < PROCESSOR_CPU_LOAD_INFO_COUNT) return (KERN_FAILURE); cpu_load_info = (processor_cpu_load_info_t) info; if (precise_user_kernel_time) { cpu_load_info->cpu_ticks[CPU_STATE_USER] = (uint32_t)(timer_grab(&PROCESSOR_DATA(processor, user_state)) / hz_tick_interval); cpu_load_info->cpu_ticks[CPU_STATE_SYSTEM] = (uint32_t)(timer_grab(&PROCESSOR_DATA(processor, system_state)) / hz_tick_interval); } else { uint64_t tval = timer_grab(&PROCESSOR_DATA(processor, user_state)) + timer_grab(&PROCESSOR_DATA(processor, system_state)); cpu_load_info->cpu_ticks[CPU_STATE_USER] = (uint32_t)(tval / hz_tick_interval); cpu_load_info->cpu_ticks[CPU_STATE_SYSTEM] = 0; } idle_state = &PROCESSOR_DATA(processor, idle_state); idle_time_snapshot1 = timer_grab(idle_state); idle_time_tstamp1 = idle_state->tstamp; /* * Idle processors are not continually updating their * per-processor idle timer, so it may be extremely * out of date, resulting in an over-representation * of non-idle time between two measurement * intervals by e.g. top(1). If we are non-idle, or * have evidence that the timer is being updated * concurrently, we consider its value up-to-date. */ if (PROCESSOR_DATA(processor, current_state) != idle_state) { cpu_load_info->cpu_ticks[CPU_STATE_IDLE] = (uint32_t)(idle_time_snapshot1 / hz_tick_interval); } 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 */ cpu_load_info->cpu_ticks[CPU_STATE_IDLE] = (uint32_t)(idle_time_snapshot2 / hz_tick_interval); } 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; cpu_load_info->cpu_ticks[CPU_STATE_IDLE] = (uint32_t)(idle_time_snapshot1 / hz_tick_interval); } cpu_load_info->cpu_ticks[CPU_STATE_NICE] = 0; *count = PROCESSOR_CPU_LOAD_INFO_COUNT; *host = &realhost; return (KERN_SUCCESS); } default: result = cpu_info(flavor, cpu_id, info, count); if (result == KERN_SUCCESS) *host = &realhost; return (result); } }