int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { uv_cpu_info_t* cpu_info; perfstat_cpu_total_t ps_total; perfstat_cpu_t* ps_cpus; perfstat_id_t cpu_id; int result, ncpus, idx = 0; result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1); if (result == -1) { return UV_ENOSYS; } ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); if (result == -1) { return UV_ENOSYS; } ps_cpus = (perfstat_cpu_t*) uv__malloc(ncpus * sizeof(perfstat_cpu_t)); if (!ps_cpus) { return UV_ENOMEM; } /* TODO(bnoordhuis) Check uv__strscpy() return value. */ uv__strscpy(cpu_id.name, FIRST_CPU, sizeof(cpu_id.name)); result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus); if (result == -1) { uv__free(ps_cpus); return UV_ENOSYS; } *cpu_infos = (uv_cpu_info_t*) uv__malloc(ncpus * sizeof(uv_cpu_info_t)); if (!*cpu_infos) { uv__free(ps_cpus); return UV_ENOMEM; } *count = ncpus; cpu_info = *cpu_infos; while (idx < ncpus) { cpu_info->speed = (int)(ps_total.processorHZ / 1000000); cpu_info->model = uv__strdup(ps_total.description); cpu_info->cpu_times.user = ps_cpus[idx].user; cpu_info->cpu_times.sys = ps_cpus[idx].sys; cpu_info->cpu_times.idle = ps_cpus[idx].idle; cpu_info->cpu_times.irq = ps_cpus[idx].wait; cpu_info->cpu_times.nice = 0; cpu_info++; idx++; } uv__free(ps_cpus); return 0; }
uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { uv_cpu_info_t* cpu_info; perfstat_cpu_total_t ps_total; perfstat_cpu_t* ps_cpus; perfstat_id_t cpu_id; int result, ncpus, idx = 0; result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1); if (result == -1) { return uv__new_artificial_error(UV_ENOSYS); } ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); if (result == -1) { return uv__new_artificial_error(UV_ENOSYS); } ps_cpus = (perfstat_cpu_t*) malloc(ncpus * sizeof(perfstat_cpu_t)); if (!ps_cpus) { return uv__new_artificial_error(UV_ENOMEM); } strcpy(cpu_id.name, FIRST_CPU); result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus); if (result == -1) { free(ps_cpus); return uv__new_artificial_error(UV_ENOSYS); } *cpu_infos = (uv_cpu_info_t*) malloc(ncpus * sizeof(uv_cpu_info_t)); if (!*cpu_infos) { free(ps_cpus); return uv__new_artificial_error(UV_ENOMEM); } *count = ncpus; cpu_info = *cpu_infos; while (idx < ncpus) { cpu_info->speed = (int)(ps_total.processorHZ / 1000000); cpu_info->model = strdup(ps_total.description); cpu_info->cpu_times.user = ps_cpus[idx].user; cpu_info->cpu_times.sys = ps_cpus[idx].sys; cpu_info->cpu_times.idle = ps_cpus[idx].idle; cpu_info->cpu_times.irq = ps_cpus[idx].wait; cpu_info->cpu_times.nice = 0; cpu_info++; idx++; } free(ps_cpus); return uv_ok_; }
void print_cpu(void) { int i, retcode, cputotal; perfstat_id_t firstcpu; perfstat_cpu_t *statp1, *statp2; long total_user, total_sys, total_idle, total_wait; total_user = total_sys = total_idle = total_wait = 0; /* check how many perfstat_cpu_t structures are available */ cputotal = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); /* allocate enough memory for all the structures */ statp1 = calloc(cputotal, sizeof(perfstat_cpu_t)); statp2 = calloc(cputotal, sizeof(perfstat_cpu_t)); /* set name to first cpu */ strcpy(firstcpu.name, FIRST_CPU); /* ask to get all the structures available in one call */ retcode = perfstat_cpu(&firstcpu, statp1, sizeof(perfstat_cpu_t), cputotal); sleep(1); retcode = perfstat_cpu(&firstcpu, statp2, sizeof(perfstat_cpu_t), cputotal); /* return code is number of structures returned */ printf("System Configuration: lcpu=%d\n", retcode); printf("cpu\t%%usr\t%%sys\t%%wio\t%%idle\n"); for (i = 0; i < retcode; i++) { printf("%s\t%llu\t%llu\t%llu\t%llu\t\n", &statp1[i].name[3], statp2[i].user - statp1[i].user, statp2[i].sys - statp1[i].sys, statp2[i].wait - statp1[i].wait, statp2[i].idle - statp1[i].idle); total_user += statp2[i].user - statp1[i].user; total_sys += statp2[i].sys - statp1[i].sys; total_wait += statp2[i].wait - statp1[i].wait; total_idle += statp2[i].idle - statp1[i].idle; } printf("-\t%llu\t%llu\t%llu\t%llu\t\n", lround(total_user / (float) retcode), lround(total_sys / (float) retcode), lround(total_wait / (float) retcode), lround(total_idle / (float) retcode)); free(statp1); free(statp2); }
/* * 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); }
void get_cpu_idle(uint64_t *res) { perfstat_cpu_t *perfstat_buffer; perfstat_cpu_t *per_cpu_pointer; perfstat_id_t name; int i,ret; /* a name of "" will cause us to start from the beginning */ strcpy(name.name,""); perfstat_buffer = (perfstat_cpu_t *)malloc(lib_num_loc_cpus * sizeof(perfstat_cpu_t)); if (perfstat_buffer == NULL) { fprintf(where, "cpu_start: malloc failed errno %d\n", errno); fflush(where); exit(-1); } /* happiness and joy, keep going */ ret = perfstat_cpu(&name, perfstat_buffer, sizeof(perfstat_cpu_t), lib_num_loc_cpus); if ((ret == -1) || (ret != lib_num_loc_cpus)) { fprintf(where, "cpu_start: perfstat_cpu failed/count off; errno %d cpus %d count %d\n", errno, lib_num_loc_cpus, ret); fflush(where); exit(-1); } per_cpu_pointer = perfstat_buffer; for (i = 0; i < lib_num_loc_cpus; i++){ res[i] = per_cpu_pointer->idle; per_cpu_pointer++; } free(perfstat_buffer); return; }
void get_cpu_time_counters(cpu_time_counters_t *res, struct timeval *timestamp, test_t *test) { netsysstat_data_t *tsd = GET_TEST_DATA(test); perfstat_cpu_total_t *psp = tsd->psd; perfstat_cpu_t *per_cpu_data; perfstat_id_t name; int num_cpus = tsd->num_cpus; int i; double elapsed; strcpy(name.name,""); per_cpu_data = (perfstat_cpu_t *)malloc(num_cpus * sizeof(perfstat_cpu_t)); if (perfstat_cpu(&name, per_cpu_data, sizeof(perfstat_cpu_t), num_cpus) == num_cpus) { gettimeofday(timestamp, NULL); /* "elapsed" isn't "really" elapsed, but it works for what we want */ elapsed = (double)timestamp->tv_sec + ((double)timestamp->tv_usec / (double)1000000); for (i = 0; i < num_cpus; i++) { /* our "calibration" value will be our "elapsed" time multiplied by the value of _SC_CLK_TCK. */ res[i].calibrate = (uint64_t)(elapsed * (double) sysconf(_SC_CLK_TCK)); res[i].idle = per_cpu_data[i].idle; #ifndef EXTRA_COUNTERS_MISSING res[i].user = per_cpu_data[i].user; res[i].kernel = per_cpu_data[i].sys; res[i].interrupt = 0; res[i].other = res[i].calibrate; res[i].other -= res[i].idle; res[i].other -= res[i].user; res[i].other -= res[i].kernel; res[i].other -= res[i].interrupt; #endif if(test->debug) { fprintf(test->where, "\tcalibrate[%d] = %"PRIx64, i, res[i].calibrate); fprintf(test->where, "\tidle[%d] = %"PRIx64, i, res[i].idle); #ifndef EXTRA_COUNTERS_MISSING fprintf(test->where, "\tuser[%d] = %"PRIx64, i, res[i].user); fprintf(test->where, "\tkern[%d] = %"PRIx64, i, res[i].kernel); fprintf(test->where, "\tintr[%d] = %"PRIx64, i, res[i].interrupt); fprintf(test->where, "\tothr[%d] = %"PRIx64, i, res[i].other); #endif fprintf(test->where, "\n"); fflush(test->where); } } if (test->debug) { fprintf(test->where, "\tseconds=%d\tusec=%d\telapsed=%f\n", timestamp->tv_sec,timestamp->tv_usec,elapsed); fflush(test->where); } } }
static int cpu_read (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE int cpu; kern_return_t status; #if PROCESSOR_CPU_LOAD_INFO processor_cpu_load_info_data_t cpu_info; mach_msg_type_number_t cpu_info_len; #endif #if PROCESSOR_TEMPERATURE processor_info_data_t cpu_temp; mach_msg_type_number_t cpu_temp_len; #endif host_t cpu_host; for (cpu = 0; cpu < cpu_list_len; cpu++) { #if PROCESSOR_CPU_LOAD_INFO derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; memset(derives, -1, sizeof(derives)); cpu_host = 0; cpu_info_len = PROCESSOR_BASIC_INFO_COUNT; if ((status = processor_info (cpu_list[cpu], PROCESSOR_CPU_LOAD_INFO, &cpu_host, (processor_info_t) &cpu_info, &cpu_info_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed with status %i", (int) status); continue; } if (cpu_info_len < CPU_STATE_MAX) { ERROR ("cpu plugin: processor_info returned only %i elements..", cpu_info_len); continue; } derives[CPU_SUBMIT_USER] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER]; derives[CPU_SUBMIT_NICE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE]; derives[CPU_SUBMIT_SYSTEM] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM]; derives[CPU_SUBMIT_IDLE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE]; submit (cpu, derives); #endif /* PROCESSOR_CPU_LOAD_INFO */ #if PROCESSOR_TEMPERATURE /* * Not all Apple computers do have this ability. To minimize * the messages sent to the syslog we do an exponential * stepback if `processor_info' fails. We still try ~once a day * though.. */ if (cpu_temp_retry_counter > 0) { cpu_temp_retry_counter--; continue; } cpu_temp_len = PROCESSOR_INFO_MAX; status = processor_info (cpu_list[cpu], PROCESSOR_TEMPERATURE, &cpu_host, cpu_temp, &cpu_temp_len); if (status != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed: %s", mach_error_string (status)); cpu_temp_retry_counter = cpu_temp_retry_step; cpu_temp_retry_step *= 2; if (cpu_temp_retry_step > cpu_temp_retry_max) cpu_temp_retry_step = cpu_temp_retry_max; continue; } if (cpu_temp_len != 1) { DEBUG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?", (int) cpu_temp_len); continue; } cpu_temp_retry_counter = 0; cpu_temp_retry_step = 1; #endif /* PROCESSOR_TEMPERATURE */ } submit_flush (); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(KERNEL_LINUX) int cpu; FILE *fh; char buf[1024]; char *fields[9]; int numfields; if ((fh = fopen ("/proc/stat", "r")) == NULL) { char errbuf[1024]; ERROR ("cpu plugin: fopen (/proc/stat) failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buf, 1024, fh) != NULL) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; if (strncmp (buf, "cpu", 3)) continue; if ((buf[3] < '0') || (buf[3] > '9')) continue; numfields = strsplit (buf, fields, 9); if (numfields < 5) continue; cpu = atoi (fields[0] + 3); derives[CPU_SUBMIT_USER] = atoll(fields[1]); derives[CPU_SUBMIT_NICE] = atoll(fields[2]); derives[CPU_SUBMIT_SYSTEM] = atoll(fields[3]); derives[CPU_SUBMIT_IDLE] = atoll(fields[4]); if (numfields >= 8) { derives[CPU_SUBMIT_WAIT] = atoll(fields[5]); derives[CPU_SUBMIT_INTERRUPT] = atoll(fields[6]); derives[CPU_SUBMIT_SOFTIRQ] = atoll(fields[6]); if (numfields >= 9) derives[CPU_SUBMIT_STEAL] = atoll(fields[8]); } submit(cpu, derives); } submit_flush(); fclose (fh); /* #endif defined(KERNEL_LINUX) */ #elif defined(HAVE_LIBKSTAT) int cpu; static cpu_stat_t cs; if (kc == NULL) return (-1); for (cpu = 0; cpu < numcpu; cpu++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; if (kstat_read (kc, ksp[cpu], &cs) == -1) continue; /* error message? */ memset(derives, -1, sizeof(derives)); derives[CPU_SUBMIT_IDLE] = cs.cpu_sysinfo.cpu[CPU_IDLE]; derives[CPU_SUBMIT_USER] = cs.cpu_sysinfo.cpu[CPU_USER]; derives[CPU_SUBMIT_SYSTEM] = cs.cpu_sysinfo.cpu[CPU_KERNEL]; derives[CPU_SUBMIT_WAIT] = cs.cpu_sysinfo.cpu[CPU_WAIT]; submit (ksp[cpu]->ks_instance, derives); } submit_flush (); /* #endif defined(HAVE_LIBKSTAT) */ #elif CAN_USE_SYSCTL uint64_t cpuinfo[numcpu][CPUSTATES]; size_t cpuinfo_size; int status; int i; if (numcpu < 1) { ERROR ("cpu plugin: Could not determine number of " "installed CPUs using sysctl(3)."); return (-1); } memset (cpuinfo, 0, sizeof (cpuinfo)); #if defined(KERN_CPTIME2) if (numcpu > 1) { for (i = 0; i < numcpu; i++) { int mib[] = {CTL_KERN, KERN_CPTIME2, i}; cpuinfo_size = sizeof (cpuinfo[0]); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), cpuinfo[i], &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } } } else #endif /* defined(KERN_CPTIME2) */ { int mib[] = {CTL_KERN, KERN_CPTIME}; long cpuinfo_tmp[CPUSTATES]; cpuinfo_size = sizeof(cpuinfo_tmp); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &cpuinfo_tmp, &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for(i = 0; i < CPUSTATES; i++) { cpuinfo[0][i] = cpuinfo_tmp[i]; } } for (i = 0; i < numcpu; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; submit(i, derives); } submit_flush(); /* #endif CAN_USE_SYSCTL */ #elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) long cpuinfo[maxcpu][CPUSTATES]; size_t cpuinfo_size; int i; memset (cpuinfo, 0, sizeof (cpuinfo)); cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < numcpu; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; submit(i, derives); } submit_flush(); /* #endif HAVE_SYSCTL_KERN_CP_TIMES */ #elif defined(HAVE_SYSCTLBYNAME) long cpuinfo[CPUSTATES]; size_t cpuinfo_size; derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_time", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } derives[CPU_SUBMIT_USER] = cpuinfo[CP_USER]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[CP_SYS]; derives[CPU_SUBMIT_NICE] = cpuinfo[CP_NICE]; derives[CPU_SUBMIT_IDLE] = cpuinfo[CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[CP_INTR]; submit(0, derives); submit_flush(); /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) sg_cpu_stats *cs; derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; cs = sg_get_cpu_stats (); if (cs == NULL) { ERROR ("cpu plugin: sg_get_cpu_stats failed."); return (-1); } derives[CPU_SUBMIT_IDLE] = (derive_t) cs->idle; derives[CPU_SUBMIT_NICE] = (derive_t) cs->nice; derives[CPU_SUBMIT_SWAP] = (derive_t) cs->swap; derives[CPU_SUBMIT_SYSTEM] = (derive_t) cs->kernel; derives[CPU_SUBMIT_USER] = (derive_t) cs->user; derives[CPU_SUBMIT_WAIT] = (derive_t) cs->iowait; submit(0, derives); submit_flush(); /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) perfstat_id_t id; int i, cpus; numcpu = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); if(numcpu == -1) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (pnumcpu != numcpu || perfcpu == NULL) { if (perfcpu != NULL) free(perfcpu); perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t)); } pnumcpu = numcpu; id.name[0] = '\0'; if ((cpus = perfstat_cpu(&id, perfcpu, sizeof(perfstat_cpu_t), numcpu)) < 0) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < cpus; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_IDLE] = perfcpu[i].idle; derives[CPU_SUBMIT_SYSTEM] = perfcpu[i].sys; derives[CPU_SUBMIT_USER] = perfcpu[i].user; derives[CPU_SUBMIT_WAIT] = perfcpu[i].wait; submit(i, derives); } submit_flush(); #endif /* HAVE_PERFSTAT */ return (0); }
/* * 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; }
static void update_cpustats(ZBX_CPUS_STAT_DATA *pcpus) { const char *__function_name = "update_cpustats"; int cpu_num; zbx_uint64_t counter[ZBX_CPU_STATE_COUNT]; #if defined(HAVE_PROC_STAT) FILE *file; char line[1024]; unsigned char *cpu_status = NULL; const char *filename = "/proc/stat"; #elif defined(HAVE_SYS_PSTAT_H) struct pst_dynamic psd; struct pst_processor psp; #elif defined(HAVE_FUNCTION_SYSCTLBYNAME) && defined(CPUSTATES) long cp_time[CPUSTATES], *cp_times = NULL; size_t nlen, nlen_alloc; #elif defined(HAVE_KSTAT_H) kstat_ctl_t *kc; kstat_t *k; cpu_stat_t *cpu; zbx_uint64_t total[ZBX_CPU_STATE_COUNT]; #elif defined(HAVE_FUNCTION_SYSCTL_KERN_CPTIME) int mib[3]; long all_states[CPUSTATES]; u_int64_t one_states[CPUSTATES]; size_t sz; #elif defined(HAVE_LIBPERFSTAT) perfstat_cpu_total_t ps_cpu_total; perfstat_cpu_t ps_cpu; perfstat_id_t ps_id; #endif zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); #define ZBX_SET_CPUS_NOTSUPPORTED() \ for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) \ update_cpu_counters(&pcpus->cpu[cpu_num], NULL) #if defined(HAVE_PROC_STAT) if (NULL == (file = fopen(filename, "r"))) { zbx_error("cannot open [%s]: %s", filename, zbx_strerror(errno)); ZBX_SET_CPUS_NOTSUPPORTED(); goto exit; } cpu_status = zbx_malloc(cpu_status, sizeof(unsigned char) * (pcpus->count + 1)); for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) cpu_status[cpu_num] = SYSINFO_RET_FAIL; while (NULL != fgets(line, sizeof(line), file)) { if (0 != strncmp(line, "cpu", 3)) continue; if ('0' <= line[3] && line[3] <= '9') { cpu_num = atoi(line + 3) + 1; if (1 > cpu_num || cpu_num > pcpus->count) continue; } else if (' ' == line[3]) cpu_num = 0; else continue; memset(counter, 0, sizeof(counter)); sscanf(line, "%*s " ZBX_FS_UI64 " " ZBX_FS_UI64 " " ZBX_FS_UI64 " " ZBX_FS_UI64 " " ZBX_FS_UI64 " " ZBX_FS_UI64 " " ZBX_FS_UI64 " " ZBX_FS_UI64, &counter[ZBX_CPU_STATE_USER], &counter[ZBX_CPU_STATE_NICE], &counter[ZBX_CPU_STATE_SYSTEM], &counter[ZBX_CPU_STATE_IDLE], &counter[ZBX_CPU_STATE_IOWAIT], &counter[ZBX_CPU_STATE_INTERRUPT], &counter[ZBX_CPU_STATE_SOFTIRQ], &counter[ZBX_CPU_STATE_STEAL]); update_cpu_counters(&pcpus->cpu[cpu_num], counter); cpu_status[cpu_num] = SYSINFO_RET_OK; } zbx_fclose(file); for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) if (SYSINFO_RET_FAIL == cpu_status[cpu_num]) update_cpu_counters(&pcpus->cpu[cpu_num], NULL); zbx_free(cpu_status); #elif defined(HAVE_SYS_PSTAT_H) for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) { memset(counter, 0, sizeof(counter)); if (0 == cpu_num) { if (-1 == pstat_getdynamic(&psd, sizeof(psd), 1, 0)) { update_cpu_counters(&pcpus->cpu[cpu_num], NULL); continue; } counter[ZBX_CPU_STATE_USER] = (zbx_uint64_t)psd.psd_cpu_time[CP_USER]; counter[ZBX_CPU_STATE_NICE] = (zbx_uint64_t)psd.psd_cpu_time[CP_NICE]; counter[ZBX_CPU_STATE_SYSTEM] = (zbx_uint64_t)psd.psd_cpu_time[CP_SYS]; counter[ZBX_CPU_STATE_IDLE] = (zbx_uint64_t)psd.psd_cpu_time[CP_IDLE]; } else { if (-1 == pstat_getprocessor(&psp, sizeof(psp), 1, cpu_num - 1)) { update_cpu_counters(&pcpus->cpu[cpu_num], NULL); continue; } counter[ZBX_CPU_STATE_USER] = (zbx_uint64_t)psp.psp_cpu_time[CP_USER]; counter[ZBX_CPU_STATE_NICE] = (zbx_uint64_t)psp.psp_cpu_time[CP_NICE]; counter[ZBX_CPU_STATE_SYSTEM] = (zbx_uint64_t)psp.psp_cpu_time[CP_SYS]; counter[ZBX_CPU_STATE_IDLE] = (zbx_uint64_t)psp.psp_cpu_time[CP_IDLE]; } update_cpu_counters(&pcpus->cpu[cpu_num], counter); } #elif defined(HAVE_FUNCTION_SYSCTLBYNAME) && defined(CPUSTATES) /* FreeBSD 7.0 */ nlen = sizeof(cp_time); if (-1 == sysctlbyname("kern.cp_time", &cp_time, &nlen, NULL, 0) || nlen != sizeof(cp_time)) { ZBX_SET_CPUS_NOTSUPPORTED(); goto exit; } memset(counter, 0, sizeof(counter)); counter[ZBX_CPU_STATE_USER] = (zbx_uint64_t)cp_time[CP_USER]; counter[ZBX_CPU_STATE_NICE] = (zbx_uint64_t)cp_time[CP_NICE]; counter[ZBX_CPU_STATE_SYSTEM] = (zbx_uint64_t)cp_time[CP_SYS]; counter[ZBX_CPU_STATE_INTERRUPT] = (zbx_uint64_t)cp_time[CP_INTR]; counter[ZBX_CPU_STATE_IDLE] = (zbx_uint64_t)cp_time[CP_IDLE]; update_cpu_counters(&pcpus->cpu[0], counter); /* get size of result set for CPU statistics */ if (-1 == sysctlbyname("kern.cp_times", NULL, &nlen_alloc, NULL, 0)) { for (cpu_num = 1; cpu_num <= pcpus->count; cpu_num++) update_cpu_counters(&pcpus->cpu[cpu_num], NULL); goto exit; } cp_times = zbx_malloc(cp_times, nlen_alloc); nlen = nlen_alloc; if (0 == sysctlbyname("kern.cp_times", cp_times, &nlen, NULL, 0) && nlen == nlen_alloc) { for (cpu_num = 1; cpu_num <= pcpus->count; cpu_num++) { memset(counter, 0, sizeof(counter)); counter[ZBX_CPU_STATE_USER] = (zbx_uint64_t)*(cp_times + (cpu_num - 1) * CPUSTATES + CP_USER); counter[ZBX_CPU_STATE_NICE] = (zbx_uint64_t)*(cp_times + (cpu_num - 1) * CPUSTATES + CP_NICE); counter[ZBX_CPU_STATE_SYSTEM] = (zbx_uint64_t)*(cp_times + (cpu_num - 1) * CPUSTATES + CP_SYS); counter[ZBX_CPU_STATE_INTERRUPT] = (zbx_uint64_t)*(cp_times + (cpu_num - 1) * CPUSTATES + CP_INTR); counter[ZBX_CPU_STATE_IDLE] = (zbx_uint64_t)*(cp_times + (cpu_num - 1) * CPUSTATES + CP_IDLE); update_cpu_counters(&pcpus->cpu[cpu_num], counter); } } else { for (cpu_num = 1; cpu_num <= pcpus->count; cpu_num++) update_cpu_counters(&pcpus->cpu[cpu_num], NULL); } zbx_free(cp_times); #elif defined(HAVE_KSTAT_H) /* Solaris */ if (NULL == (kc = kstat_open())) { ZBX_SET_CPUS_NOTSUPPORTED(); goto exit; } memset(total, 0, sizeof(total)); for (cpu_num = 1; cpu_num <= pcpus->count; cpu_num++) { if (NULL == (k = kstat_lookup(kc, "cpu_stat", pcpus->cpu[cpu_num].cpu_num - 1, NULL)) || -1 == kstat_read(kc, k, NULL)) { update_cpu_counters(&pcpus->cpu[cpu_num], NULL); continue; } cpu = (cpu_stat_t *)k->ks_data; memset(counter, 0, sizeof(counter)); total[ZBX_CPU_STATE_IDLE] += counter[ZBX_CPU_STATE_IDLE] = cpu->cpu_sysinfo.cpu[CPU_IDLE]; total[ZBX_CPU_STATE_USER] += counter[ZBX_CPU_STATE_USER] = cpu->cpu_sysinfo.cpu[CPU_USER]; total[ZBX_CPU_STATE_SYSTEM] += counter[ZBX_CPU_STATE_SYSTEM] = cpu->cpu_sysinfo.cpu[CPU_KERNEL]; total[ZBX_CPU_STATE_IOWAIT] += counter[ZBX_CPU_STATE_IOWAIT] = cpu->cpu_sysinfo.cpu[CPU_WAIT]; update_cpu_counters(&pcpus->cpu[cpu_num], counter); } kstat_close(kc); update_cpu_counters(&pcpus->cpu[0], total); #elif defined(HAVE_FUNCTION_SYSCTL_KERN_CPTIME) /* OpenBSD 4.3 */ for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) { memset(counter, 0, sizeof(counter)); if (0 == cpu_num) { mib[0] = CTL_KERN; mib[1] = KERN_CPTIME; sz = sizeof(all_states); if (-1 == sysctl(mib, 2, &all_states, &sz, NULL, 0) || sz != sizeof(all_states)) { update_cpu_counters(&pcpus->cpu[cpu_num], NULL); continue; } counter[ZBX_CPU_STATE_USER] = (zbx_uint64_t)all_states[CP_USER]; counter[ZBX_CPU_STATE_NICE] = (zbx_uint64_t)all_states[CP_NICE]; counter[ZBX_CPU_STATE_SYSTEM] = (zbx_uint64_t)all_states[CP_SYS]; counter[ZBX_CPU_STATE_INTERRUPT] = (zbx_uint64_t)all_states[CP_INTR]; counter[ZBX_CPU_STATE_IDLE] = (zbx_uint64_t)all_states[CP_IDLE]; } else { mib[0] = CTL_KERN; mib[1] = KERN_CPTIME2; mib[2] = cpu_num - 1; sz = sizeof(one_states); if (-1 == sysctl(mib, 3, &one_states, &sz, NULL, 0) || sz != sizeof(one_states)) { update_cpu_counters(&pcpus->cpu[cpu_num], NULL); continue; } counter[ZBX_CPU_STATE_USER] = (zbx_uint64_t)one_states[CP_USER]; counter[ZBX_CPU_STATE_NICE] = (zbx_uint64_t)one_states[CP_NICE]; counter[ZBX_CPU_STATE_SYSTEM] = (zbx_uint64_t)one_states[CP_SYS]; counter[ZBX_CPU_STATE_INTERRUPT] = (zbx_uint64_t)one_states[CP_INTR]; counter[ZBX_CPU_STATE_IDLE] = (zbx_uint64_t)one_states[CP_IDLE]; } update_cpu_counters(&pcpus->cpu[cpu_num], counter); } #elif defined(HAVE_LIBPERFSTAT) /* AIX 6.1 */ for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) { memset(counter, 0, sizeof(counter)); if (0 == cpu_num) { if (-1 == perfstat_cpu_total(NULL, &ps_cpu_total, sizeof(ps_cpu_total), 1)) { update_cpu_counters(&pcpus->cpu[cpu_num], NULL); continue; } counter[ZBX_CPU_STATE_USER] = (zbx_uint64_t)ps_cpu_total.user; counter[ZBX_CPU_STATE_SYSTEM] = (zbx_uint64_t)ps_cpu_total.sys; counter[ZBX_CPU_STATE_IDLE] = (zbx_uint64_t)ps_cpu_total.idle; counter[ZBX_CPU_STATE_IOWAIT] = (zbx_uint64_t)ps_cpu_total.wait; } else { zbx_snprintf(ps_id.name, sizeof(ps_id.name), "cpu%d", cpu_num - 1); if (-1 == perfstat_cpu(&ps_id, &ps_cpu, sizeof(ps_cpu), 1)) { update_cpu_counters(&pcpus->cpu[cpu_num], NULL); continue; } counter[ZBX_CPU_STATE_USER] = (zbx_uint64_t)ps_cpu.user; counter[ZBX_CPU_STATE_SYSTEM] = (zbx_uint64_t)ps_cpu.sys; counter[ZBX_CPU_STATE_IDLE] = (zbx_uint64_t)ps_cpu.idle; counter[ZBX_CPU_STATE_IOWAIT] = (zbx_uint64_t)ps_cpu.wait; } update_cpu_counters(&pcpus->cpu[cpu_num], counter); } #endif /* HAVE_LIBPERFSTAT */ #undef ZBX_SET_CPUS_NOTSUPPORTED exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
float calibrate_idle_rate(int iterations, int interval) { unsigned long long firstcnt[MAXCPUS], secondcnt[MAXCPUS]; float elapsed, temp_rate, rate[MAXTIMES], local_maxrate; long sec, usec; int i, j; struct timeval time1, time2 ; struct timezone tz; perfstat_cpu_t *perfstat_buffer; perfstat_cpu_t *per_cpu_pointer; perfstat_id_t name; int ret; if (debug) { fprintf(where,"enter calibrate_perfstat\n"); fflush(where); } if (iterations > MAXTIMES) { iterations = MAXTIMES; } local_maxrate = (float)-1.0; perfstat_buffer = (perfstat_cpu_t *)malloc(lib_num_loc_cpus * sizeof(perfstat_cpu_t)); if (perfstat_buffer == NULL) { fprintf(where, "calibrate_perfstat: malloc failed errno %d\n", errno); fflush(where); exit(-1); } for(i = 0; i < iterations; i++) { rate[i] = (float)0.0; /* a name of "" will cause us to start from the beginning */ strcpy(name.name,""); /* happiness and joy, keep going */ ret = perfstat_cpu(&name, perfstat_buffer, sizeof(perfstat_cpu_t), lib_num_loc_cpus); if ((ret == -1) || (ret != lib_num_loc_cpus)) { fprintf(where, "calibrate_perfstat: perfstat_cpu failed/count off; errno %d cpus %d count %d\n", errno, lib_num_loc_cpus, ret); fflush(where); exit(-1); } per_cpu_pointer = perfstat_buffer; for (j = 0; j < lib_num_loc_cpus; j++) { firstcnt[j] = per_cpu_pointer->idle; per_cpu_pointer++; } gettimeofday (&time1, &tz); sleep(interval); gettimeofday (&time2, &tz); if (time2.tv_usec < time1.tv_usec) { time2.tv_usec += 1000000; time2.tv_sec -=1; } sec = time2.tv_sec - time1.tv_sec; usec = time2.tv_usec - time1.tv_usec; elapsed = (float)sec + ((float)usec/(float)1000000.0); /* happiness and joy, keep going */ ret = perfstat_cpu(&name, perfstat_buffer, sizeof(perfstat_cpu_t), lib_num_loc_cpus); if ((ret == -1) || (ret != lib_num_loc_cpus)) { fprintf(where, "calibrate_perfstat: perfstat_cpu failed/count off; errno %d cpus %d count %d\n", errno, lib_num_loc_cpus, ret); fflush(where); exit(-1); } per_cpu_pointer = perfstat_buffer; if(debug) { fprintf(where, "Calibration for perfstat counter run: %d\n" "\tsec = %ld usec = %ld\n" "\telapsed time = %g\n", i, sec,usec, elapsed); } for (j = 0; j < lib_num_loc_cpus; j++) { secondcnt[j] = per_cpu_pointer->idle; per_cpu_pointer++; if(debug) { /* I know that there are situations where compilers know about long long, but the library functions do not... raj 4/95 */ fprintf(where, "\tfirstcnt[%d] = 0x%8.8lx%8.8lx secondcnt[%d] = 0x%8.8lx%8.8lx\n", j, firstcnt[j], firstcnt[j], j, secondcnt[j], secondcnt[j]); } /* we assume that it would wrap no more than once. we also assume that the result of subtracting will "fit" raj 4/95 */ temp_rate = (secondcnt[j] >= firstcnt[j]) ? (float)(secondcnt[j] - firstcnt[j])/elapsed : (float)(secondcnt[j]-firstcnt[j]+MAXLONG)/elapsed; if (temp_rate > rate[i]) rate[i] = temp_rate; if(debug) { fprintf(where,"\trate[%d] = %g\n",i,rate[i]); fflush(where); } if (local_maxrate < rate[i]) local_maxrate = rate[i]; } } if(debug) { fprintf(where,"\tlocal maxrate = %g per sec. \n",local_maxrate); fflush(where); } free(perfstat_buffer); return local_maxrate; }