diff --git a/sysdeps/freebsd/mem.c b/sysdeps/freebsd/mem.c index 36b89551..2081381c 100644 --- a/sysdeps/freebsd/mem.c +++ b/sysdeps/freebsd/mem.c @@ -35,6 +35,16 @@ static const unsigned long _glibtop_sysdeps_mem = (1 << GLIBTOP_MEM_BUFFER) + (1 << GLIBTOP_MEM_CACHED) + (1 << GLIBTOP_MEM_USER); +#ifndef LOG1024 +#define LOG1024 10 +#endif + +/* these are for getting the memory statistics */ +static int pageshift; /* log base 2 of the pagesize */ + +/* define pagetok in terms of pageshift */ +#define pagetok(size) ((size) << pageshift) + /* nlist structure for kernel access */ static struct nlist nlst [] = { { "_cnt" }, @@ -51,17 +61,30 @@ static const int mib [] = { CTL_VM, VM_METER }; void glibtop_init_mem_p (glibtop *server) { + register int pagesize; + server->sysdeps.mem = _glibtop_sysdeps_mem; if (kvm_nlist (server->machine.kd, nlst) != 0) glibtop_error_io_r (server, "kvm_nlist"); + + /* get the page size with "getpagesize" and calculate pageshift + * from it */ + pagesize = getpagesize (); + pageshift = 0; + while (pagesize > 1) { + pageshift++; + pagesize >>= 1; + } + + /* we only need the amount of log(2)1024 for our conversion */ + pageshift -= LOG1024; } void glibtop_get_mem_p (glibtop *server, glibtop_mem *buf) { struct vmtotal vmt; - /* for sysctl(3) */ size_t length_vmt; struct vmmeter vmm; int bufspace; @@ -70,6 +93,10 @@ glibtop_get_mem_p (glibtop *server, glibtop_mem *buf) memset (buf, 0, sizeof (glibtop_mem)); + /* [FIXME: On FreeBSD 2.2.6, sysctl () returns an incorrect + * value for `vmt.vm'. We use some code from Unix top + * here.] */ + /* Get the data from sysctl */ length_vmt = sizeof (vmt); if (sysctl (mib, 2, &vmt, &length_vmt, NULL, 0)) @@ -86,18 +113,29 @@ glibtop_get_mem_p (glibtop *server, glibtop_mem *buf) /* Set the values to return */ buf->flags = _glibtop_sysdeps_mem; - /* total */ - buf->total = (u_int64_t) vmt.t_vm; - /* used */ - buf->used = (u_int64_t) vmt.t_avm; - /* free */ - buf->free = (u_int64_t) vmt.t_free; - /* shared */ - buf->shared = (u_int64_t) vmt.t_vmshr; - /* buffer */ + + /* convert memory stats to Kbytes */ + + buf->total = (u_int64_t) pagetok (vmm.v_page_count) << LOG1024; + buf->used = (u_int64_t) pagetok (vmm.v_active_count) << LOG1024; + buf->free = (u_int64_t) pagetok (vmm.v_free_count) << LOG1024; + + buf->cached = (u_int64_t) pagetok (vmm.v_cache_count) << LOG1024; + buf->shared = (u_int64_t) pagetok (vmt.t_vmshr) << LOG1024; + buf->buffer = (u_int64_t) bufspace; - /* cached */ - buf->cached = (u_int64_t) (vmm.v_cache_count * vmm.v_page_size); + +#if 0 + if (swappgsin < 0) { + memory_stats[5] = 0; + memory_stats[6] = 0; + } else { + memory_stats[5] = pagetok(((vmm.v_swappgsin - swappgsin))); + memory_stats[6] = pagetok(((vmm.v_swappgsout - swappgsout))); + } + swappgsin = vmm.v_swappgsin; + swappgsout = vmm.v_swappgsout; +#endif /* user */ buf->user = buf->total - buf->free - buf->shared - buf->buffer; diff --git a/sysdeps/freebsd/msg_limits.c b/sysdeps/freebsd/msg_limits.c index 533363f4..0be8ffe9 100644 --- a/sysdeps/freebsd/msg_limits.c +++ b/sysdeps/freebsd/msg_limits.c @@ -2,7 +2,7 @@ /* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the Gnome Top Library. - Contributed by Joshua Sled , July 1998. + Contributed by Martin Baulig , August 1998. The Gnome Top Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -25,9 +25,28 @@ #include +/* #define KERNEL to get declaration of `struct msginfo'. */ + +#define KERNEL + +#include #include -static const unsigned long _glibtop_sysdeps_msg_limits = 0; +static const unsigned long _glibtop_sysdeps_msg_limits = +(1 << GLIBTOP_IPC_MSGMAX) + (1 << GLIBTOP_IPC_MSGMNI) + +(1 << GLIBTOP_IPC_MSGMNB) + (1 << GLIBTOP_IPC_MSGTQL) + +(1 << GLIBTOP_IPC_MSGSSZ); + +/* The values in this structure never change at runtime, so we only + * read it once during initialization. We have to use the name `_msginfo' + * since `msginfo' is already declared external in . */ +static struct msginfo _msginfo; + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_msginfo" }, + { 0 } +}; /* Init function. */ @@ -35,6 +54,13 @@ void glibtop_init_msg_limits_p (glibtop *server) { server->sysdeps.msg_limits = _glibtop_sysdeps_msg_limits; + + if (kvm_nlist (server->machine.kd, nlst) != 0) + glibtop_error_io_r (server, "kvm_nlist"); + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &_msginfo, sizeof (_msginfo)) != sizeof (_msginfo)) + glibtop_error_io_r (server, "kvm_read (msginfo)"); } /* Provides information about sysv ipc limits. */ @@ -45,4 +71,12 @@ glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf) glibtop_init_p (server, GLIBTOP_SYSDEPS_MSG_LIMITS, 0); memset (buf, 0, sizeof (glibtop_msg_limits)); + + buf->msgmax = _msginfo.msgmax; + buf->msgmni = _msginfo.msgmni; + buf->msgmnb = _msginfo.msgmnb; + buf->msgtql = _msginfo.msgtql; + buf->msgssz = _msginfo.msgtql; + + buf->flags = _glibtop_sysdeps_msg_limits; } diff --git a/sysdeps/freebsd/open.c b/sysdeps/freebsd/open.c index 99255850..123d1352 100644 --- a/sysdeps/freebsd/open.c +++ b/sysdeps/freebsd/open.c @@ -36,13 +36,13 @@ glibtop_init_p (glibtop *server, const unsigned long features, /* Do the initialization, but only if not already initialized. */ - if ((server->flags & _GLIBTOP_INIT_STATE_INIT) == 0) { + if ((server->flags & _GLIBTOP_INIT_STATE_SYSDEPS) == 0) { glibtop_open_p (server, "glibtop", features, flags); for (init_fkt = _glibtop_init_hook_p; *init_fkt; init_fkt++) (*init_fkt) (server); - server->flags |= _GLIBTOP_INIT_STATE_INIT; + server->flags |= _GLIBTOP_INIT_STATE_SYSDEPS; } } @@ -52,6 +52,8 @@ glibtop_open_p (glibtop *server, const char *program_name, { fprintf (stderr, "DEBUG (%d): glibtop_open_p ()\n", getpid ()); + sleep (5); + /* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */ server->name = program_name; diff --git a/sysdeps/freebsd/prockernel.c b/sysdeps/freebsd/prockernel.c index ee0015a6..17a42c29 100644 --- a/sysdeps/freebsd/prockernel.c +++ b/sysdeps/freebsd/prockernel.c @@ -61,9 +61,9 @@ glibtop_get_proc_kernel_p (glibtop *server, { struct kinfo_proc *pinfo; struct i386tss *pcb_tss; - int f, count, kmem; struct pstats ps; struct user usr; + int f, count; glibtop_init_p (server, GLIBTOP_SYSDEPS_PROC_KERNEL, 0); @@ -75,7 +75,7 @@ glibtop_get_proc_kernel_p (glibtop *server, return; /* the 0-filled struct, since we can't get any info */ } - kmem = open ("/dev/kmem", O_RDONLY, NULL); + f = open ("/dev/kmem", O_RDONLY, NULL); if (f == NULL) glibtop_error_io_r (server, "open (/dev/kmem)"); diff --git a/sysdeps/freebsd/sem_limits.c b/sysdeps/freebsd/sem_limits.c index 188dc4d9..c6330b47 100644 --- a/sysdeps/freebsd/sem_limits.c +++ b/sysdeps/freebsd/sem_limits.c @@ -2,7 +2,7 @@ /* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the Gnome Top Library. - Contributed by Martin Baulig , April 1998. + Contributed by Martin Baulig , August 1998. The Gnome Top Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -25,7 +25,30 @@ #include -static const unsigned long _glibtop_sysdeps_sem_limits = 0; +/* #define KERNEL to get declaration of `struct seminfo'. */ + +#define KERNEL + +#include +#include + +static unsigned long _glibtop_sysdeps_sem_limits = +(1 << GLIBTOP_IPC_SEMMAP) + (1 << GLIBTOP_IPC_SEMMNI) + +(1 << GLIBTOP_IPC_SEMMNS) + (1 << GLIBTOP_IPC_SEMMNU) + +(1 << GLIBTOP_IPC_SEMMSL) + (1 << GLIBTOP_IPC_SEMOPM) + +(1 << GLIBTOP_IPC_SEMUME) + (1 << GLIBTOP_IPC_SEMUSZ) + +(1 << GLIBTOP_IPC_SEMVMX) + (1 << GLIBTOP_IPC_SEMAEM); + +/* The values in this structure never change at runtime, so we only + * read it once during initialization. We have to use the name `_seminfo' + * since `seminfo' is already declared external in . */ +static struct seminfo _seminfo; + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_seminfo" }, + { 0 } +}; /* Init function. */ @@ -33,6 +56,13 @@ void glibtop_init_sem_limits_p (glibtop *server) { server->sysdeps.sem_limits = _glibtop_sysdeps_sem_limits; + + if (kvm_nlist (server->machine.kd, nlst) != 0) + glibtop_error_io_r (server, "kvm_nlist"); + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &_seminfo, sizeof (_seminfo)) != sizeof (_seminfo)) + glibtop_error_io_r (server, "kvm_read (seminfo)"); } /* Provides information about sysv sem limits. */ @@ -43,4 +73,15 @@ glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf) glibtop_init_p (server, GLIBTOP_SYSDEPS_SEM_LIMITS, 0); memset (buf, 0, sizeof (glibtop_sem_limits)); + + buf->semmap = _seminfo.semmap; + buf->semmni = _seminfo.semmni; + buf->semmns = _seminfo.semmns; + buf->semmnu = _seminfo.semmnu; + buf->semmsl = _seminfo.semmsl; + buf->semopm = _seminfo.semopm; + buf->semvmx = _seminfo.semvmx; + buf->semaem = _seminfo.semaem; + + buf->flags = _glibtop_sysdeps_sem_limits; } diff --git a/sysdeps/freebsd/shm_limits.c b/sysdeps/freebsd/shm_limits.c index 6f81c819..6b4653ed 100644 --- a/sysdeps/freebsd/shm_limits.c +++ b/sysdeps/freebsd/shm_limits.c @@ -2,7 +2,7 @@ /* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the Gnome Top Library. - Contributed by Martin Baulig , April 1998. + Contributed by Martin Baulig , August 1998. The Gnome Top Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -25,7 +25,28 @@ #include -static const unsigned long _glibtop_sysdeps_shm_limits = 0; +/* #define KERNEL to get declaration of `struct shminfo'. */ + +#define KERNEL + +#include +#include + +static unsigned long _glibtop_sysdeps_shm_limits = +(1 << GLIBTOP_IPC_SHMMAX) + (1 << GLIBTOP_IPC_SHMMIN) + +(1 << GLIBTOP_IPC_SHMMNI) + (1 << GLIBTOP_IPC_SHMSEG) + +(1 << GLIBTOP_IPC_SHMALL); + +/* The values in this structure never change at runtime, so we only + * read it once during initialization. We have to use the name `_shminfo' + * since `shminfo' is already declared external in . */ +static struct shminfo _shminfo; + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_shminfo" }, + { 0 } +}; /* Init function. */ @@ -33,6 +54,13 @@ void glibtop_init_shm_limits_p (glibtop *server) { server->sysdeps.shm_limits = _glibtop_sysdeps_shm_limits; + + if (kvm_nlist (server->machine.kd, nlst) != 0) + glibtop_error_io_r (server, "kvm_nlist"); + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &_shminfo, sizeof (_shminfo)) != sizeof (_shminfo)) + glibtop_error_io_r (server, "kvm_read (shminfo)"); } /* Provides information about sysv ipc limits. */ @@ -43,4 +71,12 @@ glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) glibtop_init_p (server, GLIBTOP_SYSDEPS_SHM_LIMITS, 0); memset (buf, 0, sizeof (glibtop_shm_limits)); + + buf->shmmax = _shminfo.shmmax; + buf->shmmin = _shminfo.shmmin; + buf->shmmni = _shminfo.shmmni; + buf->shmseg = _shminfo.shmseg; + buf->shmall = _shminfo.shmall; + + buf->flags = _glibtop_sysdeps_shm_limits; } diff --git a/sysdeps/freebsd/swap.c b/sysdeps/freebsd/swap.c index c2b5c406..2367c790 100644 --- a/sysdeps/freebsd/swap.c +++ b/sysdeps/freebsd/swap.c @@ -29,8 +29,12 @@ #include #include +#include -static const unsigned long _glibtop_sysdeps_swap = 0; +static const unsigned long _glibtop_sysdeps_swap = +(1 << GLIBTOP_SWAP_TOTAL) + (1 << GLIBTOP_SWAP_USED) + +(1 << GLIBTOP_SWAP_FREE) + (1 << GLIBTOP_SWAP_PAGEIN) + +(1 << GLIBTOP_SWAP_PAGEOUT); /* nlist structure for kernel access */ static struct nlist nlst [] = { @@ -60,6 +64,11 @@ glibtop_init_swap_p (glibtop *server) /* Provides information about swap usage. */ +/* + * This function is based on a program called swapinfo written + * by Kevin Lahey . + */ + void glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) { @@ -74,10 +83,32 @@ glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) size_t sw_size; u_long ptr; + /* To get `pagein' and `pageout'. */ + struct vmmeter vmm; + static int swappgsin = -1; + static int swappgsout = -1; + glibtop_init_p (server, GLIBTOP_SYSDEPS_SWAP, 0); memset (buf, 0, sizeof (glibtop_swap)); + /* This is used to get the `pagein' and `pageout' members. */ + + if (kvm_read (server->machine.kd, nlst[0].n_value, + &vmm, sizeof (vmm)) != sizeof (vmm)) + glibtop_error_io_r (server, "kvm_read (cnt)"); + + if (swappgsin < 0) { + buf->pagein = 0; + buf->pageout = 0; + } else { + buf->pagein = vmm.v_swappgsin - swappgsin; + buf->pageout = vmm.v_swappgsout - swappgsout; + } + + swappgsin = vmm.v_swappgsin; + swappgsout = vmm.v_swappgsout; + /* Size of largest swap device. */ if (kvm_read (server->machine.kd, nlst[VM_NSWAP].n_value, @@ -128,7 +159,7 @@ glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) while (swapptr) { int top, bottom, next_block; - if (kvm_read (server->machine.kd, swapptr, &head, + if (kvm_read (server->machine.kd, (int) swapptr, &head, sizeof (struct rlist)) != sizeof (struct rlist)) glibtop_error_io_r (server, "kvm_read (swapptr)"); diff --git a/sysdeps/freebsd/uptime.c b/sysdeps/freebsd/uptime.c index 5aa76522..6f78177a 100644 --- a/sysdeps/freebsd/uptime.c +++ b/sysdeps/freebsd/uptime.c @@ -23,9 +23,16 @@ #include #include +#include + #include -static const unsigned long _glibtop_sysdeps_uptime = 0; +static const unsigned long _glibtop_sysdeps_uptime = +(1 << GLIBTOP_UPTIME_UPTIME) + (1 << GLIBTOP_UPTIME_IDLETIME); + +static const unsigned long _required_cpu_flags = +(1 << GLIBTOP_CPU_TOTAL) + (1 << GLIBTOP_CPU_IDLE) + +(1 << GLIBTOP_CPU_FREQUENCY); /* Init function. */ @@ -40,7 +47,25 @@ glibtop_init_uptime_p (glibtop *server) void glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf) { + glibtop_cpu cpu; + glibtop_init_p (server, GLIBTOP_SYSDEPS_UPTIME, 0); memset (buf, 0, sizeof (glibtop_uptime)); + + /* We simply calculate it from the CPU usage. */ + + glibtop_get_cpu_p (server, &cpu); + + /* Make sure all required fields are present. */ + + if ((cpu.flags & _required_cpu_flags) != _required_cpu_flags) + return; + + /* Calculate values. */ + + buf->uptime = (double) cpu.total / (double) cpu.frequency; + buf->idletime = (double) cpu.idle / (double) cpu.frequency; + + buf->flags = _glibtop_sysdeps_uptime; }