/*
* pg_top - a top PostgreSQL users display for Unix
*
* SYNOPSIS: For FreeBSD-2.x, 3.x, 4.x, and 5.x
*
* DESCRIPTION:
* Originally written for BSD4.4 system by Christos Zoulas.
* Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider
* Order support hacked in from top-3.5beta6/machine/m_aix41.c
* by Monte Mitzelfelt
* Ported to FreeBSD 5.x by William LeFebvre
*
* AUTHOR: Christos Zoulas <christos@ee.cornell.edu>
* Steven Wallace <swallace@freebsd.org>
* Wolfram Schneider <wosch@FreeBSD.org>
*/
#include <sys/time.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <err.h>
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <nlist.h>
#include <math.h>
#include <kvm.h>
#include <pwd.h>
#include <sys/errno.h>
#include <sys/sysctl.h>
#include <sys/dkstat.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/vmmeter.h>
#include <sys/resource.h>
#include <sys/rtprio.h>
#include <sys/tree.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* Swap */
#include <stdlib.h>
#include <sys/conf.h>
#include <osreldate.h> /* for changes in kernel structures */
#include "pg_top.h"
#include "machine.h"
#include "utils.h"
/* declarations for load_avg */
#include "loadavg.h"
#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
static int getkval __P((unsigned long, int *, int, char *));
extern char *printable __P((char *));
static void getsysctl(const char *name, void *ptr, size_t len);
int swapmode __P((int *retavail, int *retfree));
static int maxcpu;
static int maxid;
static int ncpus;
static u_long cpumask;
static long *times;
static long *pcpu_cp_time;
static long *pcpu_cp_old;
static long *pcpu_cp_diff;
static int64_t * pcpu_cpu_states;
static int smpmode;
static int namelength;
static int cmdlength;
/* get_process_info passes back a handle. This is what it looks like: */
struct handle
{
struct kinfo_proc **next_proc; /* points to next valid proc pointer */
int remaining; /* number of pointers remaining */
};
struct pg_proc
{
RB_ENTRY(pg_proc) entry;
pid_t pid;
/* This will be the previous copy of ki_rusage. */
struct rusage ki_rusage;
char *name;
char *usename;
int pgstate;
unsigned long xtime;
unsigned long qtime;
unsigned int locks;
/* Replication data */
char *application_name;
char *client_addr;
char *repstate;
char *primary;
char *sent;
char *write;
char *flush;
char *replay;
long long sent_lag;
long long write_lag;
long long flush_lag;
long long replay_lag;
};
int topproccmp(struct pg_proc *, struct pg_proc *);
RB_HEAD(pgproc, pg_proc) head_proc = RB_INITIALIZER(&head_proc);
RB_PROTOTYPE(pgproc, pg_proc, entry, topproccmp)
RB_GENERATE(pgproc, pg_proc, entry, topproccmp)
/* macros to access process information */
#if OSMAJOR <= 4
#define PP(pp, field) ((pp)->kp_proc . p_##field)
#define EP(pp, field) ((pp)->kp_eproc . e_##field)
#define VP(pp, field) ((pp)->kp_eproc.e_vm . vm_##field)
#define PRUID(pp) ((pp)