/* * perfstat() interface * e.g. AIX */ #include #include #include #include #include #include #include #include #include #include netsnmp_feature_require(hardware_cpu_copy_stats); void _cpu_copy_stats( netsnmp_cpu_info *cpu ); /* * Initialise the list of CPUs on the system * (including descriptions) */ void init_cpu_perfstat( void ) { int i; perfstat_id_t name; perfstat_cpu_t *cs2; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 ); strcpy(cpu->name, "Overall CPU statistics"); cpu_num = perfstat_cpu( NULL, NULL, sizeof(perfstat_cpu_t), 0 ); cs2 = (perfstat_cpu_t*)malloc( cpu_num*sizeof(perfstat_cpu_t)); strcpy( name.name, ""); if (perfstat_cpu(&name, cs2, sizeof(perfstat_cpu_t), cpu_num) > 0) { for ( i = 0; i < cpu_num; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 1 ); sprintf( cpu->name, cs2[i].name); } } free(cs2); } /* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { int i,n; perfstat_id_t name; perfstat_cpu_total_t cs; perfstat_cpu_t *cs2; perfstat_memory_total_t ms; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 ); if (perfstat_cpu_total((perfstat_id_t *)NULL, &cs, sizeof(perfstat_cpu_total_t), 1) > 0) { /* Returns 'u_longlong_t' statistics */ cpu->user_ticks = (unsigned long long)cs.user / cs.ncpus; cpu->sys_ticks = ((unsigned long long)cs.sys + (unsigned long long)cs.wait) / cs.ncpus; cpu->kern_ticks = (unsigned long long)cs.sys / cs.ncpus; cpu->wait_ticks = (unsigned long long)cs.wait / cs.ncpus; cpu->idle_ticks = (unsigned long long)cs.idle / cs.ncpus; /* intrpt_ticks, sirq_ticks, nice_ticks unused */ /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ cpu->pageIn = (unsigned long long)cs.sysread; cpu->pageOut = (unsigned long long)cs.syswrite; cpu->nInterrupts = (unsigned long long)cs.devintrs + cs.softintrs; cpu->nCtxSwitches = (unsigned long long)cs.pswitch; } if (perfstat_memory_total((perfstat_id_t *)NULL, &ms, sizeof(perfstat_memory_total_t), 1) > 0) { cpu->swapIn = (unsigned long long)ms.pgspins; cpu->swapOut = (unsigned long long)ms.pgspouts; } /* * Per-CPU statistics */ n = cs.ncpus; /* XXX - Compare against cpu_num */ cs2 = (perfstat_cpu_t*)malloc( n*sizeof(perfstat_cpu_t)); strcpy( name.name, ""); if (perfstat_cpu(&name, cs2, sizeof(perfstat_cpu_t), n) > 0) { for ( i = 0; i < n; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 1 ); cpu->user_ticks = (unsigned long long)cs2[i].user; cpu->sys_ticks = (unsigned long long)cs2[i].sys + (unsigned long long)cs2[i].wait; cpu->kern_ticks = (unsigned long long)cs2[i].sys; cpu->wait_ticks = (unsigned long long)cs2[i].wait; cpu->idle_ticks = (unsigned long long)cs2[i].idle; cpu->pageIn = (unsigned long long)cs2[i].sysread; cpu->pageOut = (unsigned long long)cs2[i].syswrite; cpu->nCtxSwitches = (unsigned long long)cs2[i].pswitch; /* Interrupt stats only apply overall, not per-CPU */ } } else { _cpu_copy_stats( cpu ); } free(cs2); return 0; }