commit 8187859d2515ceb4bbbe6f608e24f490fb40094e from: rsc date: Wed Oct 05 13:30:49 2005 UTC new code from Jeff Sickel commit - 431e32de9b41c230b0791fb9f2f293859d189e59 commit + 8187859d2515ceb4bbbe6f608e24f490fb40094e blob - 46ba5cbf119893acadc01000547032f34f64b7b6 blob + 94a8794d28a8f6bb9f7effe00b59a387f8fb48a2 --- src/cmd/auxstats/Darwin.c +++ src/cmd/auxstats/Darwin.c @@ -1,10 +1,4 @@ -/* - * No idea whether this will work. It does compile. - */ - #include -#include -#include #include #include #include @@ -15,120 +9,303 @@ #include #include #include +#include #include #include #include #include + +#include +#include +#include +#include +AUTOFRAMEWORK(CoreFoundation) +AUTOFRAMEWORK(IOKit) + #include "dat.h" +typedef struct Sample Sample; + +struct Sample +{ + uint seq; + host_cpu_load_info_data_t cpu, p_cpu; + vm_size_t pgsize; + double divisor; + uint64_t time, p_time; + vm_statistics_data_t vm_stat, p_vm_stat; + boolean_t purgeable_is_valid; + struct xsw_usage xsu; + boolean_t xsu_valid; + integer_t syscalls_mach, p_syscalls_mach; + integer_t syscalls_unix, p_syscalls_unix; + ulong csw, p_csw; + uint net_ifaces; + uvlong net_ipackets, p_net_ipackets; + uvlong net_opackets, p_net_opackets; + uvlong net_ibytes, p_net_ibytes; + uvlong net_obytes, p_net_obytes; + uvlong net_errors, p_net_errors; + ulong usecs; +}; + +static Sample sample; + +void xsample(int); +void xapm(int); void xloadavg(int); void xcpu(int); void xswap(int); -void xsysctl(int); +void xvm(int); void xnet(int); -void xkvm(int); void (*statfn[])(int) = { - xkvm, + xsample, + xapm, xloadavg, xswap, xcpu, - xsysctl, + xvm, xnet, 0 }; -static kvm_t *kvm; +static mach_port_t stat_port; -static struct nlist nl[] = { - { "_ifnet" }, - { "_cp_time" }, - { "" }, -}; +void +sampleinit(void) +{ + mach_timebase_info_data_t info; + + if(stat_port) + return; + stat_port = mach_host_self(); + memset(&sample, 0, sizeof sample); + if(host_page_size(stat_port, &sample.pgsize) != KERN_SUCCESS) + sample.pgsize = 4096; + + // populate clock tick info for timestamps + mach_timebase_info(&info); + sample.divisor = 1000.0 * (double)info.denom/info.numer; + sample.time = mach_absolute_time(); +} + void -kvminit(void) +samplenet(void) { - char buf[_POSIX2_LINE_MAX]; + struct ifaddrs *ifa_list, *ifa; + + ifa_list = nil; + sample.net_ifaces = nil; + if(getifaddrs(&ifa_list) == 0){ + sample.p_net_ipackets = sample.net_ipackets; + sample.p_net_opackets = sample.net_opackets; + sample.p_net_ibytes = sample.net_ibytes; + sample.p_net_obtypes = sample.net_obytes; + sample.p_net_errors = sample.net_errors; - if(kvm) - return; - kvm = kvm_openfiles(nil, nil, nil, OREAD, buf); - if(kvm == nil) - return; - if(kvm_nlist(kvm, nl) < 0 || nl[0].n_type == 0){ - kvm = nil; - return; + sample.net_ipackets = 0; + sample.net_opackets = 0; + sample.net_ibytes = 0; + sample.net_obytes = 0; + sample.net_errors = 0; + sample.net_ifaces = 0; + + for(ifa=ifa_list; ifa; ifa=ifa->next){ + if(ifa->ifa_addr->sa_family != AF_LINK) + continue; + if((ifa->ifa_flags&(IFF_UP|IFF_RUNNING)) == 0) + continue; + if(ifa->ifa_data == nil) + continue; + if(strncmp(ifa->ifa_name, "lo", 2) == 0) /* loopback */ + continue; + + sample.net_ipackets += if_data->ifi_ipackets; + sample.net_opackets += if_data->ifi_opackets; + sample.net_ibytes += if_data->ifi_ibytes; + sample.net_obytes += if_data->ifi_obtypes; + sample.net_errors += if_data->ifi_ierrors + if_data->ifif_oerrors; + sample.net_ifaces++; + } + freeifaddrs(ifa_list); } } + +/* + * The following forces the program to be run with the suid root as + * all the other stat monitoring apps get set: + * + * -rwsr-xr-x 1 root wheel 83088 Mar 20 2005 /usr/bin/top + * -rwsrwxr-x 1 root admin 54048 Mar 20 2005 + * /Applications/Utilities/Activity Monitor.app/Contents/Resources/pmTool + * + * If Darwin eventually encompases more into sysctl then this + * won't be required. + */ void -xkvm(int first) +sampevents(void) { - if(first) - kvminit(); + uint i, j, pcnt, tcnt; + mach_msg_type_number_t count; + kern_return_t error; + processor_set_t *psets, pset; + task_t *tasks; + task_events_info_data_t events; + + if((error = host_processor_sets(stat_port, &psets, &pcnt)) != KERN_SUCCESS){ + Bprint(&bout, "host_processor_sets: %s (make sure auxstats is setuid root)\n", + mach_error_string(error)); + return; + } + + sample.p_syscalls_mach = sample.syscalls_mach; + sample.p_syscalls_unix = sample.syscalls_unix; + sample.p_csw = sample.csw; + + sample.syscalls_mach = 0; + sample.syscalls_unix = 0; + sample.csw = 0; + + for(i=0; istathz; - } + if(first) return; - } - if((n=rsys("kern.cp_time", (char*)x, sizeof x)) < 5*sizeof(ulong)) - return; + sys = sample.cpu.cpu_ticks[CPU_STATE_SYSTEM] - + sample.p_cpu.cpu_ticks[CPU_STATE_SYSTEM]; + idle = sample.cpu.cpu_ticks[CPU_STATE_IDLE] - + sample.p_cpu.cpu_ticks[CPU_STATE_IDLE]; + user = sample.cpu.cpu_ticks[CPU_STATE_USER] - + sample.p_cpu.cpu_ticks[CPU_STATE_USER]; + nice = sample.cpu.cpu_ticks[CPU_STATE_NICE] - + sample.p_cpu.cpu_ticks[CPU_STATE_NICE]; + + t = sys+idle+user+nice; - Bprint(&bout, "user %lud %d\n", x[CP_USER]+x[CP_NICE], stathz); - Bprint(&bout, "sys %lud %d\n", x[CP_SYS], stathz); - Bprint(&bout, "cpu %lud %d\n", x[CP_USER]+x[CP_NICE]+x[CP_SYS], stathz); - Bprint(&bout, "idle %lud %d\n", x[CP_IDLE], stathz); -#endif + Bprint(&bout, "user =%lud %lud\n", user, t); + Bprint(&bout, "sys =%lud %lud\n", sys, t); + Bprint(&bout, "idle =%lud %lud\n", idle, t); + Bprint(&bout, "nice =%lud %lud\n", nice, t); } void @@ -222,32 +403,11 @@ xloadavg(int first) void xswap(int first) { -#if 0 - static struct kvm_swap s; - static ulong pgin, pgout; - int i, o; - static int pgsize; - - if(first){ - pgsize = getpagesize(); - if(pgsize == 0) - pgsize = 4096; + if(first) return; - } - - if(kvm == nil) - return; - - i = isys("vm.stats.vm.v_swappgsin"); - o = isys("vm.stats.vm.v_swappgsout"); - if(i != pgin || o != pgout){ - pgin = i; - pgout = o; - kvm_getswapinfo(kvm, &s, 1, 0); - } - - - Bprint(&bout, "swap %lld %lld\n", s.ksw_used*(vlong)pgsize, s.ksw_total*(vlong)pgsize); -#endif + + if(sample.xsu_valid) + Bprint(&bout, "swap %lld %lld\n", + (vlong)samle.xsu.xsu_used, + (vlong)sample.xsu.xsu_total); } -