SIGAR_DECLARE(char *)sigar_net_services_name_get(sigar_t *sigar, int protocol, unsigned long port) { sigar_cache_entry_t *entry; sigar_cache_t **names; char *pname; switch (protocol) { case SIGAR_NETCONN_TCP: names = &sigar->net_services_tcp; pname = "tcp"; break; case SIGAR_NETCONN_UDP: names = &sigar->net_services_udp; pname = "udp"; break; default: return NULL; } if (*names == NULL) { *names = sigar_cache_new(1024); net_services_parse(*names, pname); } if ((entry = sigar_cache_find(*names, port))) { return (char *)entry->value; } else { return NULL; } }
static int create_fsdev_cache(sigar_t *sigar) { sigar_file_system_list_t fslist; int i; int status = sigar_file_system_list_get(sigar, &fslist); if (status != SIGAR_OK) { return status; } sigar->fsdev = sigar_cache_new(15); for (i=0; i<fslist.number; i++) { sigar_file_system_t *fsp = &fslist.data[i]; if (fsp->type == SIGAR_FSTYPE_LOCAL_DISK) { sigar_cache_entry_t *ent; struct stat sb; if (stat(fsp->dir_name, &sb) < 0) { continue; } ent = sigar_cache_get(sigar->fsdev, SIGAR_FSDEV_ID(sb)); ent->value = strdup(fsp->dev_name); } } return SIGAR_OK; }
/* XXX: check for stale-ness using start_time */ SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_cpu_t *proccpu) { sigar_cache_entry_t *entry; sigar_proc_cpu_t *prev; sigar_uint64_t otime, time_now = sigar_time_now_millis(); sigar_uint64_t time_diff, total_diff; int status; if (!sigar->proc_cpu) { sigar->proc_cpu = sigar_cache_new(128); } entry = sigar_cache_get(sigar->proc_cpu, pid); if (entry->value) { prev = (sigar_proc_cpu_t *)entry->value; } else { prev = entry->value = malloc(sizeof(*prev)); SIGAR_ZERO(prev); } time_diff = time_now - prev->last_time; proccpu->last_time = prev->last_time = time_now; if (time_diff == 0) { /* we were just called within < 1 second ago. */ memcpy(proccpu, prev, sizeof(*proccpu)); return SIGAR_OK; } otime = prev->total; status = sigar_proc_time_get(sigar, pid, (sigar_proc_time_t *)proccpu); if (status != SIGAR_OK) { return status; } memcpy(prev, proccpu, sizeof(*prev)); if (proccpu->total < otime) { /* XXX this should not happen */ otime = 0; } if (otime == 0) { proccpu->percent = 0.0; /* first time called */ return SIGAR_OK; } total_diff = proccpu->total - otime; proccpu->percent = total_diff / (double)time_diff; return SIGAR_OK; }
static int sigar_cpu_list_get(sigar_t *sigar, sigar_cpu_list_t *cpulist) { kstat_ctl_t *kc = sigar->kc; kstat_t *ksp; uint_t cpuinfo[CPU_STATES]; unsigned int i; int is_debug = SIGAR_LOG_IS_DEBUG(sigar); sigar_cache_t *chips; if (sigar_kstat_update(sigar) == -1) { return errno; } if (cpulist == &sigar->cpulist) { if (sigar->cpulist.size == 0) { /* create once */ sigar_cpu_list_create(cpulist); } else { /* reset, re-using cpulist.data */ sigar->cpulist.number = 0; } } else { sigar_cpu_list_create(cpulist); } if (is_debug) { sigar_log_printf(sigar, SIGAR_LOG_DEBUG, "[cpu_list] OS reports %d CPUs", sigar->ncpu); } chips = sigar_cache_new(16); chips->free_value = free_chip_id; for (i=0; i<sigar->ncpu; i++) { sigar_cpu_t *cpu; char *buf; int chip_id; sigar_cache_entry_t *ent; if (!CPU_ONLINE(sigar->ks.cpuid[i])) { sigar_log_printf(sigar, SIGAR_LOG_INFO, "cpu %d (id=%d) is offline", i, sigar->ks.cpuid[i]); continue; } if (!(ksp = sigar->ks.cpu[i])) { sigar_log_printf(sigar, SIGAR_LOG_ERROR, "NULL ksp for cpu %d (id=%d)", i, sigar->ks.cpuid[i]); continue; /* shouldnot happen */ } if (kstat_read(kc, ksp, NULL) < 0) { sigar_log_printf(sigar, SIGAR_LOG_ERROR, "kstat_read failed for cpu %d (id=%d): %s", i, sigar->ks.cpuid[i], sigar_strerror(sigar, errno)); continue; /* shouldnot happen */ } /* * cpu_stat_t is not binary compatible between solaris versions. * since cpu_stat is a 'raw' kstat and not 'named' we cannot * use name based lookups as we do for others. * the start of the cpu_stat_t structure is binary compatible, * which looks like so: * typedef struct cpu_stat { * kmutex_t cpu_stat_lock; * cpu_sysinfo_t cpu_sysinfo; * ... * typedef struct cpu_sysinfo { * ulong cpu[CPU_STATES]; * ... * we just copy the piece we need below: */ buf = ksp->ks_data; buf += sizeof(kmutex_t); memcpy(&cpuinfo[0], buf, sizeof(cpuinfo)); chip_id = sigar->cpu_list_cores ? -1 : get_chip_id(sigar, i); if (chip_id == -1) { SIGAR_CPU_LIST_GROW(cpulist); cpu = &cpulist->data[cpulist->number++]; SIGAR_ZERO(cpu); } else { /* merge times of logical processors */ ent = sigar_cache_get(chips, chip_id); if (ent->value) { cpu = &cpulist->data[(long)ent->value-1]; } else { SIGAR_CPU_LIST_GROW(cpulist); cpu = &cpulist->data[cpulist->number++]; ent->value = (void *)(long)cpulist->number; SIGAR_ZERO(cpu); if (is_debug) { sigar_log_printf(sigar, SIGAR_LOG_DEBUG, "[cpu_list] Merging times of" " logical processors for chip_id=%d", chip_id); } } } cpu->user += SIGAR_TICK2MSEC(cpuinfo[CPU_USER]); cpu->sys += SIGAR_TICK2MSEC(cpuinfo[CPU_KERNEL]); cpu->idle += SIGAR_TICK2MSEC(cpuinfo[CPU_IDLE]); cpu->wait += SIGAR_TICK2MSEC(cpuinfo[CPU_WAIT]); cpu->nice += 0; /* no cpu->nice */ cpu->total = cpu->user + cpu->sys + cpu->idle + cpu->wait; } sigar_cache_destroy(chips); return SIGAR_OK; }