Esempio n. 1
0
kern_return_t
host_statistics(
    host_t			host,
    host_flavor_t		flavor,
    host_info_t		info,
    mach_msg_type_number_t	*count)
{

    if (host == HOST_NULL)
        return(KERN_INVALID_HOST);

    switch(flavor) {

    case HOST_LOAD_INFO: {
        register host_load_info_t load_info;
        extern integer_t avenrun[3], mach_factor[3];

        if (*count < HOST_LOAD_INFO_COUNT)
            return(KERN_FAILURE);

        load_info = (host_load_info_t) info;

        bcopy((char *) avenrun,
              (char *) load_info->avenrun,
              sizeof avenrun);
        bcopy((char *) mach_factor,
              (char *) load_info->mach_factor,
              sizeof mach_factor);

        *count = HOST_LOAD_INFO_COUNT;
        return(KERN_SUCCESS);
    }

    case HOST_VM_INFO: {
        register vm_statistics_t stat;
        vm_statistics_data_t host_vm_stat;
        extern int vm_page_free_count, vm_page_active_count,
               vm_page_inactive_count, vm_page_wire_count;

        if (*count < HOST_VM_INFO_COUNT)
            return(KERN_FAILURE);

        stat = &vm_stat[0];
        host_vm_stat = *stat;
#if NCPUS > 1
        {
            register int i;

            for (i = 1; i < NCPUS; i++) {
                host_vm_stat.zero_fill_count +=
                    stat->zero_fill_count;
                host_vm_stat.reactivations +=
                    stat->reactivations;
                host_vm_stat.pageins += stat->pageins;
                host_vm_stat.pageouts += stat->pageouts;
                host_vm_stat.faults += stat->faults;
                host_vm_stat.cow_faults += stat->cow_faults;
                host_vm_stat.lookups += stat->lookups;
                host_vm_stat.hits += stat->hits;
                stat++;
            }
        }
#endif

        stat = (vm_statistics_t) info;

        stat->free_count = vm_page_free_count;
        stat->active_count = vm_page_active_count;
        stat->inactive_count = vm_page_inactive_count;
        stat->wire_count = vm_page_wire_count;
        stat->zero_fill_count = host_vm_stat.zero_fill_count;
        stat->reactivations = host_vm_stat.reactivations;
        stat->pageins = host_vm_stat.pageins;
        stat->pageouts = host_vm_stat.pageouts;
        stat->faults = host_vm_stat.faults;
        stat->cow_faults = host_vm_stat.cow_faults;
        stat->lookups = host_vm_stat.lookups;
        stat->hits = host_vm_stat.hits;

        *count = HOST_VM_INFO_COUNT;
        return(KERN_SUCCESS);
    }

    case HOST_CPU_LOAD_INFO: {
        host_cpu_load_info_t	cpu_load_info;
        unsigned long		ticks_value1, ticks_value2;
        int			i;

#define GET_TICKS_VALUE(__cpu,__state) \
MACRO_BEGIN \
	do { \
		ticks_value1 = *(volatile integer_t *) \
			(&machine_slot[(__cpu)].cpu_ticks[(__state)]); \
		ticks_value2 = *(volatile integer_t *) \
			(&machine_slot[(__cpu)].cpu_ticks[(__state)]); \
	} while (ticks_value1 != ticks_value2); \
	cpu_load_info->cpu_ticks[(__state)] += ticks_value1; \
MACRO_END

        if (*count < HOST_CPU_LOAD_INFO_COUNT)
            return KERN_FAILURE;

        cpu_load_info = (host_cpu_load_info_t) info;

        cpu_load_info->cpu_ticks[CPU_STATE_USER] = 0;
        cpu_load_info->cpu_ticks[CPU_STATE_NICE] = 0;
        cpu_load_info->cpu_ticks[CPU_STATE_SYSTEM] = 0;
        cpu_load_info->cpu_ticks[CPU_STATE_IDLE] = 0;
        for (i = 0; i < NCPUS; i++) {
            if (!machine_slot[i].is_cpu ||
                    !machine_slot[i].running)
                continue;
            GET_TICKS_VALUE(i, CPU_STATE_USER);
            GET_TICKS_VALUE(i, CPU_STATE_NICE);
            GET_TICKS_VALUE(i, CPU_STATE_SYSTEM);
            GET_TICKS_VALUE(i, CPU_STATE_IDLE);
        }

        *count = HOST_CPU_LOAD_INFO_COUNT;
        return KERN_SUCCESS;
    }

    default:
        return(KERN_INVALID_ARGUMENT);
    }
}
Esempio n. 2
0
File: host.c Progetto: DJHartley/xnu
kern_return_t
host_statistics(
	host_t					host,
	host_flavor_t			flavor,
	host_info_t				info,
	mach_msg_type_number_t	*count)
{
	uint32_t	i;

	if (host == HOST_NULL)
		return (KERN_INVALID_HOST);
	
	switch(flavor) {

	case HOST_LOAD_INFO:
	{
		host_load_info_t	load_info;

		if (*count < HOST_LOAD_INFO_COUNT)
			return (KERN_FAILURE);

		load_info = (host_load_info_t) info;

		bcopy((char *) avenrun,
			  (char *) load_info->avenrun, sizeof avenrun);
		bcopy((char *) mach_factor,
			  (char *) load_info->mach_factor, sizeof mach_factor);

		*count = HOST_LOAD_INFO_COUNT;
		return (KERN_SUCCESS);
	}

	case HOST_VM_INFO:
	{
		register processor_t		processor;
		register vm_statistics64_t	stat;
		vm_statistics64_data_t		host_vm_stat;
		vm_statistics_t			stat32;
		mach_msg_type_number_t		original_count;
                
		if (*count < HOST_VM_INFO_REV0_COUNT)
			return (KERN_FAILURE);

		processor = processor_list;
		stat = &PROCESSOR_DATA(processor, vm_stat);
		host_vm_stat = *stat;

		if (processor_count > 1) {
			simple_lock(&processor_list_lock);

			while ((processor = processor->processor_list) != NULL) {
				stat = &PROCESSOR_DATA(processor, vm_stat);

				host_vm_stat.zero_fill_count +=	stat->zero_fill_count;
				host_vm_stat.reactivations += stat->reactivations;
				host_vm_stat.pageins += stat->pageins;
				host_vm_stat.pageouts += stat->pageouts;
				host_vm_stat.faults += stat->faults;
				host_vm_stat.cow_faults += stat->cow_faults;
				host_vm_stat.lookups += stat->lookups;
				host_vm_stat.hits += stat->hits;
			}

			simple_unlock(&processor_list_lock);
		}

		stat32 = (vm_statistics_t) info;

		stat32->free_count = VM_STATISTICS_TRUNCATE_TO_32_BIT(vm_page_free_count + vm_page_speculative_count);
		stat32->active_count = VM_STATISTICS_TRUNCATE_TO_32_BIT(vm_page_active_count);
		
		if (vm_page_local_q) {
			for (i = 0; i < vm_page_local_q_count; i++) {
				struct vpl	*lq;

				lq = &vm_page_local_q[i].vpl_un.vpl;

				stat32->active_count += VM_STATISTICS_TRUNCATE_TO_32_BIT(lq->vpl_count);
			}
		}
		stat32->inactive_count = VM_STATISTICS_TRUNCATE_TO_32_BIT(vm_page_inactive_count);
#if CONFIG_EMBEDDED
		stat32->wire_count = VM_STATISTICS_TRUNCATE_TO_32_BIT(vm_page_wire_count);
#else
		stat32->wire_count = VM_STATISTICS_TRUNCATE_TO_32_BIT(vm_page_wire_count + vm_page_throttled_count + vm_lopage_free_count);
#endif
		stat32->zero_fill_count = VM_STATISTICS_TRUNCATE_TO_32_BIT(host_vm_stat.zero_fill_count);
		stat32->reactivations = VM_STATISTICS_TRUNCATE_TO_32_BIT(host_vm_stat.reactivations);
		stat32->pageins = VM_STATISTICS_TRUNCATE_TO_32_BIT(host_vm_stat.pageins);
		stat32->pageouts = VM_STATISTICS_TRUNCATE_TO_32_BIT(host_vm_stat.pageouts);
		stat32->faults = VM_STATISTICS_TRUNCATE_TO_32_BIT(host_vm_stat.faults);
		stat32->cow_faults = VM_STATISTICS_TRUNCATE_TO_32_BIT(host_vm_stat.cow_faults);
		stat32->lookups = VM_STATISTICS_TRUNCATE_TO_32_BIT(host_vm_stat.lookups);
		stat32->hits = VM_STATISTICS_TRUNCATE_TO_32_BIT(host_vm_stat.hits);

		/*
		 * Fill in extra info added in later revisions of the
		 * vm_statistics data structure.  Fill in only what can fit
		 * in the data structure the caller gave us !
		 */
		original_count = *count;
		*count = HOST_VM_INFO_REV0_COUNT; /* rev0 already filled in */
		if (original_count >= HOST_VM_INFO_REV1_COUNT) {
			/* rev1 added "purgeable" info */
			stat32->purgeable_count = VM_STATISTICS_TRUNCATE_TO_32_BIT(vm_page_purgeable_count);
			stat32->purges = VM_STATISTICS_TRUNCATE_TO_32_BIT(vm_page_purged_count);
			*count = HOST_VM_INFO_REV1_COUNT;
		}

		if (original_count >= HOST_VM_INFO_REV2_COUNT) {
			/* rev2 added "speculative" info */
			stat32->speculative_count = VM_STATISTICS_TRUNCATE_TO_32_BIT(vm_page_speculative_count);
			*count = HOST_VM_INFO_REV2_COUNT;
		}

		/* rev3 changed some of the fields to be 64-bit*/

		return (KERN_SUCCESS);
	}
                
	case HOST_CPU_LOAD_INFO:
	{
		register processor_t	processor;
		host_cpu_load_info_t	cpu_load_info;

		if (*count < HOST_CPU_LOAD_INFO_COUNT)
			return (KERN_FAILURE);

#define GET_TICKS_VALUE(processor, state, timer)			 \
MACRO_BEGIN								 \
	cpu_load_info->cpu_ticks[(state)] +=				 \
		(uint32_t)(timer_grab(&PROCESSOR_DATA(processor, timer)) \
				/ hz_tick_interval);			 \
MACRO_END

		cpu_load_info = (host_cpu_load_info_t)info;
		cpu_load_info->cpu_ticks[CPU_STATE_USER] = 0;
		cpu_load_info->cpu_ticks[CPU_STATE_SYSTEM] = 0;
		cpu_load_info->cpu_ticks[CPU_STATE_IDLE] = 0;
		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_data_t	idle_temp;
			timer_t		idle_state;

			GET_TICKS_VALUE(processor, CPU_STATE_USER, user_state);
			if (precise_user_kernel_time) {
				GET_TICKS_VALUE(processor, CPU_STATE_SYSTEM, system_state);
			} else {
				/* system_state may represent either sys or user */
				GET_TICKS_VALUE(processor, CPU_STATE_USER, system_state);
			}

			idle_state = &PROCESSOR_DATA(processor, idle_state);
			idle_temp = *idle_state;

			if (PROCESSOR_DATA(processor, current_state) != idle_state ||
			    timer_grab(&idle_temp) != timer_grab(idle_state))
				GET_TICKS_VALUE(processor, CPU_STATE_IDLE, idle_state);
			else {
				timer_advance(&idle_temp, mach_absolute_time() - idle_temp.tstamp);

				cpu_load_info->cpu_ticks[CPU_STATE_IDLE] +=
					(uint32_t)(timer_grab(&idle_temp) / hz_tick_interval);
			}
		}
		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);
	}
}