Ultrix-3.1/src/cmd/memstat.c

Compare this file to the similar file:
Show the results in this format:


/**********************************************************************
 *   Copyright (c) Digital Equipment Corporation 1984, 1985, 1986.    *
 *   All Rights Reserved. 					      *
 *   Reference "/usr/src/COPYRIGHT" for applicable restrictions.      *
 **********************************************************************/

static char Sccsid[] = "@(#)memstat.c	3.1	10/27/87";
#include <stdio.h>
#include <sys/param.h>
#include <a.out.h>
#include <sys/proc.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <time.h>
#include <sys/timeb.h>
#include <core.h>
#include <sys/text.h>
#include <sys/map.h>
#include <sys/clist.h>
#include <sys/ipc.h>
#include <sys/msg.h>

long	timbuf;
char	*ap;
char	*timezone();
char	*asctime();
struct	tm *localtime();

struct nlist nli[] = {
	{ "_proc" },
#define				X_PROC		0
	{ "_nproc" },
#define				X_NPROC		1
	{ "_mapsize" },
#define				X_MAPSIZE	2
	{ "_coremap" },
#define				X_COREMAP	3
	{ "_usermem" },
#define				X_USERMEM	4
	{ "_realmem" },
#define				X_REALMEM	5
#define				X_REQUIRED	5
	{ "_bpaddr" },
#define				X_BPADDR	6
	{ "_nbuf" },
#define				X_NBUF		7
	{ "_clststrt" },
#define				X_CLSTSTRT	8
	{ "_nclist" },
#define				X_NCLIST	9
	{ "_mbbase" },
#define				X_MBBASE	10
	{ "_mbsize" },
#define				X_MBSIZE	11
	{ "_mauscore" },
#define				X_MAUSCORE	12
	{ "_mausend" },
#define				X_MAUSEND	13
	{ "_msgbase" },
#define				X_MSGBASE	14
	{ "_msginfo" },
#define				X_MSGINFO	15
	{ "_de_dmaa" },
#define				X_DE_DMAA	16
	{ "_de_dmas" },
#define				X_DE_DMAS	17
	{ 0 }
 };

int mem, swmem, interval;
int nprc, dsrt;
int	mapsiz;
char *infile = "/unix";
char *coref = "/dev/mem";
unsigned realmem;
unsigned usrbase;
char *usage = "memstat: usage  memstat [ifn] [interval] [corefile] [namelist]\n";

char *memtypes[] = {
	"",
	"*FREE MEMORY*",
#define MFRE	1
	"*TEXT SEGMENT*",
#define TXT	2
	"*BUFFERS*",
#define	BUFS	3
	"*CLISTS*",
#define	CLISTS	4
	"*MBUFS*",
#define	MBUFS	5
	"*MAUS*",
#define	MAUS	6
	"*MESSAGES*",
#define	MSG	7
	"*DEUNA DMA*",
#define	DE_DMA	8
	"*(UNKNOWN)*",
#define	MISSING	9
};

struct prcsrt{
	int		srtsts;
	int		srtpid;
	unsigned	srtsadr;
	unsigned	srtxadr;
	unsigned	srtxsiz;
	unsigned	srttsiz;
	unsigned	srtdsiz;
	unsigned	srtssiz;
	char		srtarg[DIRSIZ+2];
};

struct proc prcs;
struct text txt;
struct user u;
struct map  cmp;
struct prcsrt prc[256];
int soscnt, sopcnt;
int sospnt;
unsigned de_dmaa;
unsigned de_dmas;

main(argc, argp)
int argc;
char *argp[];
{
	int cnt, cnt1;
	char *ap;
	int	compare();

	argp++;
	for(ap = *argp++; ap && *ap; ap++)
		switch(*ap){
			case 'f':
				coref = *argp++;
				break;
			case 'i':
				interval = atoi(*argp++);
				break;
			case 'n':
				infile = *argp++;
				break;
			case '-':
				break;
			default:
				fprintf(stderr, "%s", usage);
				exit(1);
				break;
		}
	initmem();
	while(1){
		dsrt = lprc();
		qsort(prc, dsrt, sizeof(struct prcsrt), compare);
		memsts();
		if(interval)
			sleep(interval);
		else
			exit(0);
	}
}

lprc()
{
	register int cnt;
	register struct prcsrt *ptr;

	for(cnt = 0, ptr = &prc[0]; cnt < nprc; cnt++) {
		lseek(mem, (long)(nli[X_PROC].n_value+(sizeof(struct proc)*cnt)), 0);
		read(mem, &prcs, sizeof(struct proc));
		if(prcs.p_stat == 0 || prcs.p_flag == 0)
			continue;
		if((prcs.p_flag & SLOAD) == 0)
			continue;
		if(prcs.p_stat == SZOMB)
			continue;
		lseek(swmem, ctob((long)prcs.p_addr), 0);
		if(read(swmem, &u, sizeof(struct user)) != sizeof(struct user)){
			printf("Fatal Ublock read. PID = %d\n", prcs.p_pid);
			exit(1);
		}
		if(prcs.p_pid == 0){
			strcpy(ptr->srtarg, "swapper");
			usrbase = prcs.p_addr;
		} else
			strcpy(ptr->srtarg, &u.u_comm);
		ptr->srtxadr = 0;
		ptr->srtsts = u.u_exdata.ux_mag;
		ptr->srtxsiz = prcs.p_size;
		ptr->srttsiz = u.u_tsize;
		if(prcs.p_textp){
			lseek(mem, (long)prcs.p_textp, 0);
			read(mem, &txt, sizeof(struct text));
			ptr->srtxadr = txt.x_caddr;
			ptr->srttsiz = txt.x_size;
		}
		ptr->srtpid = prcs.p_pid;
		ptr->srtsadr = prcs.p_addr;
		ptr->srtdsiz = u.u_dsize;
		ptr->srtssiz = u.u_ssize;
		ptr++;
		if(prcs.p_textp){
			if(found(txt.x_caddr, ptr)){
				ptr->srtsts = TXT;
				ptr->srtsadr = txt.x_caddr;
				ptr->srtxsiz = txt.x_size;
				strcpy(ptr->srtarg, &u.u_comm);
				ptr++;
			}
		}
	}

	lseek(mem, (long)nli[X_COREMAP].n_value, 0);
	read(mem, &cmp, sizeof(struct map));	/* skip the first entry */
	for(cnt = 1; cnt < mapsiz; cnt++) {
		read(mem, &cmp, sizeof(struct map));
		if(cmp.m_size == 0)
			continue;
		ptr->srtsts = MFRE;
		ptr->srtsadr = cmp.m_addr;
		ptr->srtxsiz = cmp.m_size;
		ptr++;
	}
	if (nli[X_BPADDR].n_value) {
		lseek(mem, (long)nli[X_NBUF].n_value, 0);
		read(mem, &(ptr->srtxsiz), sizeof(ptr->srtxsiz));
		ptr->srtxsiz <<= (BSHIFT-6);
		lseek(mem, (long)nli[X_BPADDR].n_value, 0);
		read(mem, &(ptr->srtsadr), sizeof(ptr->srtsadr));
		ptr->srtsts = BUFS;
		ptr++;
	}
	if (nli[X_CLSTSTRT].n_value && nli[X_NCLIST].n_value) {
		lseek(mem, (long)nli[X_NCLIST].n_value, 0);
		read(mem, &(ptr->srtxsiz), sizeof(ptr->srtxsiz));
		ptr->srtxsiz = ((long)(ptr->srtxsiz+1)*sizeof(struct cblock))/64;
		lseek(mem, (long)nli[X_CLSTSTRT].n_value, 0);
		read(mem, &(ptr->srtsadr), sizeof(ptr->srtsadr));
		ptr->srtsts = CLISTS;
		ptr++;
	}
	if (nli[X_MBBASE].n_value && nli[X_MBSIZE].n_value) {
		lseek(mem, (long)nli[X_MBSIZE].n_value, 0);
		read(mem, &(ptr->srtxsiz), sizeof(ptr->srtxsiz));
		ptr->srtxsiz /= 64;
		lseek(mem, (long)nli[X_MBBASE].n_value, 0);
		read(mem, &(ptr->srtsadr), sizeof(ptr->srtsadr));
		if (ptr->srtxsiz && ptr->srtsadr) {
			ptr->srtsts = MBUFS;
			ptr++;
		}
	}
	if (nli[X_MAUSCORE].n_value && nli[X_MAUSEND].n_value) {
		lseek(mem, (long)nli[X_MAUSEND].n_value, 0);
		read(mem, &(ptr->srtxsiz), sizeof(ptr->srtxsiz));
		lseek(mem, (long)nli[X_MAUSCORE].n_value, 0);
		read(mem, &(ptr->srtsadr), sizeof(ptr->srtsadr));
		ptr->srtxsiz -= ptr->srtsadr;
		ptr->srtsts = MAUS;
		ptr++;
	}
	if (nli[X_MSGBASE].n_value && nli[X_MSGINFO].n_value) {
		struct msginfo msginfo;
		lseek(mem, (long)nli[X_MSGINFO].n_value, 0);
		read(mem, &msginfo, sizeof(msginfo));
		if (ptr->srtxsiz = ((long)msginfo.msgseg * msginfo.msgssz)/64) {
			lseek(mem, (long)nli[X_MSGBASE].n_value, 0);
			read(mem, &(ptr->srtsadr), sizeof(ptr->srtsadr));
			ptr->srtsts = MSG;
			ptr++;
		}
	}
	if (nli[X_DE_DMAA].n_value) {
		lseek(mem, (long)nli[X_DE_DMAA].n_value, 0);
		read(mem, &de_dmaa, sizeof(de_dmaa));
		lseek(mem, (long)nli[X_DE_DMAS].n_value, 0);
		read(mem, &de_dmas, sizeof(de_dmas));
printf("%o %d\n", de_dmaa, de_dmas);
		if (de_dmaa) {
			ptr->srtsts = DE_DMA;
			ptr->srtsadr = de_dmaa;
			ptr->srtxsiz = de_dmas;
			ptr++;
		}
	}
	lseek(mem, (long)nli[X_REALMEM].n_value, 0);
	read(mem, &realmem, sizeof(realmem));
	return(ptr - prc);
}

memsts()
{
	int scnt;
	unsigned tadr, dadr, sadr;
	register struct prcsrt *ptr;
	unsigned missing;
	char *s;

	printf("\nTotal Memory = %u Kbytes\t", realmem/16);
	date();
	printf("\n");
printf("  Addr    Command          Pid    Size   Ublock     Text     Data      Stack\n");
printf("------------------------------------------------------------------------------\n");
	printf("    0     %-14s        %6ld\n    v\n",
		"ULTRIX-11", ctob((long)usrbase));
	missing = usrbase;
	for (ptr = &prc[0]; ptr < &prc[dsrt]; ptr++) {
		if (missing != ptr->srtsadr) {
			printf("%06o00  %-14s         %5ld\n    v\n",
				missing, memtypes[MISSING],
				(long)(ptr->srtsadr - missing)*64);
			missing = ptr->srtsadr;
		}
		missing += ptr->srtxsiz;
		switch (ptr->srtsts) {
		case MFRE:
		case BUFS:
		case CLISTS:
		case MBUFS:
		case MAUS:
		case MSG:
		case DE_DMA:
			printf("%06o00  %-14s         %5ld\n    v\n",
				ptr->srtsadr, memtypes[ptr->srtsts],
				(long)ptr->srtxsiz*64);
			continue;
		case TXT:
			printf("%06o00  %-14s         %5ld\n",
				ptr->srtsadr, memtypes[TXT],
				(long)ptr->srtxsiz*64);
			printf("    |\t  %-14s\n    v\n", ptr->srtarg);
			continue;
		default:
			break;
		}

		tadr = ptr->srtxadr > 0 ? ptr->srtxadr : ptr->srtsadr + USIZE;
		if(ptr->srtxadr == 0)
			dadr = ptr->srtdsiz > 0 ? tadr + ptr->srttsiz : 0;
		else
			dadr = ptr->srtdsiz > 0 ? ptr->srtsadr + USIZE : 0;
		sadr = ptr->srtssiz > 0 ? dadr + ptr->srtdsiz : 0;
		printf("%06o00  %-14s  %5d  %5ld  ", ptr->srtsadr,
			ptr->srtarg, ptr->srtpid, ((long)ptr->srtxsiz)*64);

		switch (ptr->srtsts) {
		case 0407:
			sadr = tadr + ptr->srtdsiz;
			printf("%06o00  %06o00  %8s  %06o00\n",
				ptr->srtsadr, tadr, "------->", sadr);
			printf("    v\t\t\t\t\t  %5d     %5ld     %5s     %5ld\n",
				USIZE*64, ((long)ptr->srtdsiz)*64,
				"     ", ((long)ptr->srtssiz)*64);
			break;
		case 0410:
		case 0411:
		case 0430:
		case 0431:
		case 0450:
		case 0451:
			printf("%06o00 *%06o00* %06o00  %06o00\n",
				ptr->srtsadr, tadr, dadr, sadr);
			printf("    v\t\t\t\t\t  %5d     %5ld     %5ld     %5ld\n",
				USIZE*64, ((long)ptr->srttsiz)*64,
				((long)ptr->srtdsiz)*64,
				((long)ptr->srtssiz)*64);
			break;
		case 0:
			printf("%06o00", ptr->srtsadr);
			/*FALLTHROUGH*/
		default:
			printf("\n    v\n");
			break;
		}
	}
	if (missing != realmem) {
		printf("%06o00  %-14s         %5ld\n    v\n", missing,
			memtypes[MISSING], (long)(realmem - missing)*64);
	}
	printf("%06o00\n", realmem);
}

date()
{
	register char *tzn;
	struct timeb info;
	struct tm *tp;

	ftime(&info);
	time(&timbuf);
	tp = localtime(&timbuf);
	ap = asctime(tp);
	tzn = timezone(info.timezone, tp->tm_isdst);
	printf("%.20s", ap);
	if (tzn)
		printf("%s", tzn);
	printf("%s", ap+19);
}

initmem()
{
	int cnt, cnt1;

	nlist(infile, nli);
	for(cnt = 0; cnt <= X_REQUIRED && nli[cnt].n_name[0]; cnt++){
		if(nli[cnt].n_value == 0){
			printf("memstat: FATAL: nlist failed for entry %s\n", nli[cnt].n_name);
			exit(1);
		}
	}
	if((mem = open(coref, 0)) <= 0){
		printf("memstat: FATAL : could not open %s\n", coref);
		exit(1);
	}
	swmem = open(coref, 0);
	/*
	 * get number of processes, base of swap, and mapsize
	 */
	lseek(mem, (long)nli[X_NPROC].n_value, 0);
	read(mem, &nprc, sizeof(nprc));
	lseek(mem, (long)nli[X_MAPSIZE].n_value, 0);
	read(mem, (char *)&mapsiz, sizeof(mapsiz));
}

found(tpnt, eprc)
register unsigned tpnt;
register struct prcsrt *eprc;
{
	register struct prcsrt *pt1;

	for (pt1 = &prc[0]; pt1 < eprc; pt1++)
		if(pt1->srtsadr == tpnt)
			return(0);
	return(1);
}

compare(p1, p2)
register struct prcsrt *p1, *p2;
{
	return((p1->srtsadr < p2->srtsadr) ? -1 : 1);
}