diff options
Diffstat (limited to 'sysdeps/solaris/open.c')
-rw-r--r-- | sysdeps/solaris/open.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/sysdeps/solaris/open.c b/sysdeps/solaris/open.c new file mode 100644 index 00000000..7df43ca2 --- /dev/null +++ b/sysdeps/solaris/open.c @@ -0,0 +1,234 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998. + + LibGTop is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + LibGTop is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <glibtop/open.h> +#include <glibtop/cpu.h> + +#include <unistd.h> +#include <dlfcn.h> +#include <sys/types.h> +#include <sys/processor.h> + +#include <glibtop_private.h> + +/* We need to call this when kstat_chain_update() returns new KID. + * In that case all kstat pointers and data are invalid, so we + * need to reread everything. The condition shouldn't happen very + * often. + */ + +void +glibtop_get_kstats(glibtop *server) +{ + kstat_ctl_t *kc = server->machine.kc; + kstat_t *ksp; + int nproc_same, new_ncpu; + + new_ncpu = sysconf(_SC_NPROCESSORS_CONF); + + if(!kc) + { + server->ncpu = new_ncpu; + server->machine.vminfo_kstat = NULL; + server->machine.system = NULL; + server->machine.syspages = NULL; + server->machine.bunyip = NULL; + return; + } + + do { + ksp = kstat_lookup(kc, "unix", -1, "vminfo"); + server->machine.vminfo_kstat = ksp; + if(ksp) + { + kstat_read(kc, ksp, &server->machine.vminfo); + /* Don't change snaptime if we only need to reinitialize kstats */ + if(!(server->machine.vminfo_snaptime)) + server->machine.vminfo_snaptime = ksp->ks_snaptime; + } + + /* We don't know why was kstat chain invalidated. It could have + been because the number of processors changed. The sysconf() + man page says that values returned won't change during the + life time of a process, but let's hope that's just an error in + the documentation. */ + + if((nproc_same = new_ncpu) == server->ncpu) + { + int checked, i; + char cpu[20]; + + for(i = 0, checked = 0; i < GLIBTOP_NCPU || checked == new_ncpu; ++i) + if(server->machine.cpu_stat_kstat[i]) + { + sprintf(cpu, "cpu_stat%d", i); + if(!(server->machine.cpu_stat_kstat[i] = + kstat_lookup(kc, "cpu_stat", -1, cpu))) + { + nproc_same = 0; + break; + } + ++checked; + } + } + if(!nproc_same) + { + processorid_t p; + int found; + char cpu[20]; + + if(new_ncpu > GLIBTOP_NCPU) + new_ncpu = GLIBTOP_NCPU; + server->ncpu = new_ncpu; + for(p = 0, found = 0; p < GLIBTOP_NCPU && found != new_ncpu; ++p) + { + if(p_online(p, P_STATUS) < 0) + { + server->machine.cpu_stat_kstat[p] = NULL; + continue; + } + sprintf(cpu, "cpu_stat%d", (int)p); + server->machine.cpu_stat_kstat[p] = + kstat_lookup(kc, "cpu_stat", -1, cpu); + ++found; + } + } + + server->machine.system = kstat_lookup(kc, "unix", -1, "system_misc"); + server->machine.syspages = kstat_lookup(kc, "unix", -1, "system_pages"); + server->machine.bunyip = kstat_lookup(kc, "bunyip", -1, "mempages"); + + } while(kstat_chain_update(kc) > 0 && + (new_ncpu = sysconf(_SC_NPROCESSORS_CONF))); + + /* We'll ignore -1 from kstat_chain_update here, since it really + shouldn't happen */ +} + +void +glibtop_open_s (glibtop *server, const char *program_name, + const unsigned long features, const unsigned flags) +{ + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *kn; + int i, page; + void *dl; + + server->name = program_name; + + page = sysconf(_SC_PAGESIZE) >> 10; + for(i = 0; page; ++i, page >>= 1); + server->machine.pagesize = i - 1; + server->machine.ticks = sysconf(_SC_CLK_TCK); + server->machine.kc = kc = kstat_open (); + +#if 0 + for (ksp = server->machine.kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) { + if (!strcmp (ksp->ks_class, "vm") && !strcmp (ksp->ks_name, "vminfo")) { + server->machine.vminfo_kstat = ksp; + kstat_read (server->machine.kc, ksp, &server->machine.vminfo); + server->machine.vminfo_snaptime = ksp->ks_snaptime; + continue; + } + + if (!strcmp (ksp->ks_class, "misc") && !strncmp (ksp->ks_name, "cpu_stat", 8)) { + int cpu; + + if ((sscanf (ksp->ks_name+8, "%d", &cpu) != 1) || (cpu > 63)) + continue; + + if (cpu >= server->ncpu) + server->ncpu = cpu+1; + + server->machine.cpu_stat_kstat [cpu] = ksp; + continue; + } + } + +#endif + + if (!kc) + glibtop_warn_io_r (server, "kstat_open ()"); + + server->ncpu = -1; /* Force processor detection */ + server->machine.vminfo_snaptime = 0; /* Force snaptime read */ + glibtop_get_kstats(server); + + server->machine.boot = 0; + if((ksp = server->machine.system) && kstat_read(kc, ksp, NULL) >= 0) + { + kn = (kstat_named_t *)kstat_data_lookup(ksp, "boot_time"); + if(kn) + switch(kn->data_type) + { +#ifdef KSTAT_DATA_INT32 + case KSTAT_DATA_INT32: server->machine.boot = kn->value.i32; + break; + case KSTAT_DATA_UINT32: server->machine.boot = kn->value.ui32; + break; + case KSTAT_DATA_INT64: server->machine.boot = kn->value.i64; + break; + case KSTAT_DATA_UINT64: server->machine.boot = kn->value.ui64; + break; +#else + case KSTAT_DATA_LONG: server->machine.boot = kn->value.l; + break; + case KSTAT_DATA_ULONG: server->machine.boot = kn->value.ul; + break; + case KSTAT_DATA_LONGLONG: server->machine.boot = kn->value.ll; + break; + case KSTAT_DATA_ULONGLONG: server->machine.boot = kn->value.ull; + break; +#endif + } + } + + /* Now let's have a bit of magic dust... */ + +#if GLIBTOP_SOLARIS_RELEASE >= 560 + + dl = dlopen("/usr/lib/libproc.so", RTLD_LAZY); + server->machine.libproc = dl; + if(dl) + { + void *func; + + func = dlsym(dl, "Pobjname"); /* Solaris 8 */ + if(!func) + func = dlsym(dl, "proc_objname"); /* Solaris 7 */ + server->machine.objname = (void (*) + (void *, uintptr_t, const char *, size_t))func; + server->machine.pgrab = (struct ps_prochandle *(*)(pid_t, int, int *)) + dlsym(dl, "Pgrab"); + server->machine.pfree = (void (*)(void *))dlsym(dl, "Pfree"); + } + else + { + server->machine.objname = NULL; + server->machine.pgrab = NULL; + server->machine.pfree = NULL; + } +#endif + server->machine.me = getpid(); +} |