memsup.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 361 行

C
361
字号
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ ** *  Purpose:  Portprogram for supervision of memory usage. * *  Synopsis: memsup * *  PURPOSE OF THIS PROGRAM * *  This program supervises the memory status of the entire system, and *  sends status reports upon request from the Erlang system * *  SPAWNING FROM ERLANG * *  This program is started from Erlang as follows, * *      Port = open_port({spawn, 'memsup'}, [{packet,1}]) for UNIX and VxWorks * *  Erlang sends one of the request condes defined in memsup.h and this program *  answers in one of two ways: *  * If the request is for simple memory data (which is used periodically *    for monitoring) the answer is simply sent in two packets. *  * If the request is for the system specific data, the answer is delivered *    in two packets per value, first a tag value, then the actual *    value. The values are delivered "as is", this interface is *    mainly for VxWorks. *  All numbers are sent as strings of hexadecimal digits. * *  SUNOS FAKING * *  When using SunOS 4, the memory report is faked. The total physical memory *  is always reported to be 256MB, and the used fraction to be 128MB. * *  STANDARD INPUT, OUTPUT AND ERROR * *  This program communicates with Erlang through the standard *  input and output file descriptors (0 and 1). These descriptors *  (and the standard error descriptor 2) must NOT be closed *  explicitely by this program at termination (in UNIX it is *  taken care of by the operating system itself; in VxWorks *  it is taken care of by the spawn driver part of the Emulator). * *  END OF FILE * *  If a read from a file descriptor returns zero (0), it means *  that there is no process at the other end of the connection *  having the connection open for writing (end-of-file). * *  COMPILING * *  When the target is VxWorks the identifier VXWORKS must be defined for *  the preprocessor (usually by a -D option). */#ifdef sgi#include <sys/types.h>#include <sys/sysmp.h>#endif#include <stdio.h>#include <stddef.h>#include <stdlib.h>#ifndef VXWORKS#include <unistd.h>#endif#if (defined(__unix__) || defined(unix)) && !defined(USG)#include <sys/param.h>#endif#include <stdarg.h>#include <string.h>#include <time.h>#include <errno.h>#ifdef VXWORKS#include <vxWorks.h>#include <ioLib.h>#include <memLib.h>#endif#ifdef BSD4_4#include <sys/types.h>#include <sys/sysctl.h>#ifndef __OpenBSD__#include <vm/vm_param.h>#endif#ifdef __FreeBSD__#include <sys/vmmeter.h>#endif#endif/* commands */#include "memsup.h"#define CMD_SIZE      1#define MAX_CMD_BUF   10#define ERLIN_FD      0#define ERLOUT_FD     1/*  prototypes */static void print_error(const char *,...);#ifdef VXWORKSextern int erl_mem_info_get(MEM_PART_STATS *);#endif#ifdef VXWORKS#define MAIN memsupstatic MEM_PART_STATS latest;static unsigned long latest_system_total; /* does not fit in the struct */#else#define MAIN main#endif/*  static variables */static char *program_name;static voidsend(unsigned long value, unsigned long pagesize){    char buf[32];    int left, bytes, res;    int hex_zeroes;    for (hex_zeroes = 0; (pagesize % 16) == 0; pagesize /= 16) {	hex_zeroes++;    }        sprintf(buf+1, "%lx", value*pagesize);    bytes = strlen(buf+1);    while (hex_zeroes-- > 0) {	bytes++;	buf[bytes] = '0';    }    buf[0] = (char) bytes;    left = ++bytes;    while (left > 0) {	res = write(ERLOUT_FD, buf+bytes-left, left);	if (res <= 0){	    perror("Error writing to pipe");	    exit(1);	}	left -= res;    }}static voidsend_tag(int value){    unsigned char buf[2];    int res,left;    buf[0] = 1U;    buf[1] = (unsigned char) value;    left = 2;    while(left > 0)	if((res = write(ERLOUT_FD, buf+left-2,left)) <= 0){	    perror("Error writing to pipe");	    exit(1);	} else	    left -= res;}#ifdef VXWORKSstatic void load_statistics(void){    if(memPartInfoGet(memSysPartId,&latest) != OK)	memset(&latest,0,sizeof(latest));    latest_system_total = latest.numBytesFree + latest.numBytesAlloc;    erl_mem_info_get(&latest); /* if it fails, latest is untouched */}#endif#ifdef BSD4_4static intget_vmtotal(struct vmtotal *vt){	static int vmtotal_mib[] = {CTL_VM, VM_METER};	size_t size = sizeof *vt;	return sysctl(vmtotal_mib, 2, vt, &size, NULL, 0) != -1;}#endifstatic void get_basic_mem(unsigned long *tot, unsigned long *used, unsigned long *pagesize){#if defined(VXWORKS)    load_statistics();    *tot = (latest.numBytesFree + latest.numBytesAlloc);    *used = latest.numBytesAlloc;    *pagesize = 1;#elif defined(_SC_AVPHYS_PAGES)	/* Does this exist on others than Solaris2? */    unsigned long avPhys, phys, pgSz;        phys = sysconf(_SC_PHYS_PAGES);    avPhys = sysconf(_SC_AVPHYS_PAGES);    *used = (phys - avPhys);    *tot = phys;    *pagesize = sysconf(_SC_PAGESIZE);#elif defined(BSD4_4)    struct vmtotal vt;    long pgsz;    if (!get_vmtotal(&vt)) goto fail;    if ((pgsz = sysconf(_SC_PAGESIZE)) == -1) goto fail;    *tot = (vt.t_free + vt.t_rm);    *used = vt.t_rm;    *pagesize = pgsz;    return;fail:    print_error("%s", strerror(errno));    exit(1);#elif defined(sgi)	struct rminfo rmi;	if (sysmp(MP_SAGET, MPSA_RMINFO, &rmi, sizeof(rmi)) != -1) {		*tot = (unsigned long)(rmi.physmem);		*used = (unsigned long)(rmi.physmem - rmi.freemem);		*pagesize = (unsigned long)getpagesize(); }	else {		print_error("%s", strerror(errno));		exit(1); }#else  /* SunOS4 */    *used = (1<<27);	       	/* Fake! 128 MB used */    *tot = (1<<28);		/* Fake! 256 MB total */    *pagesize = 1;#endif}    static voidsimple_show_mem(void){    unsigned long tot, used, pagesize;    get_basic_mem(&tot, &used, &pagesize);    send(used, pagesize);    send(tot, pagesize);}static void extended_show_mem(void){    unsigned long tot, used, pagesize;    get_basic_mem(&tot, &used, &pagesize);    send_tag(TOTAL_MEMORY);    send(tot, pagesize);    send_tag(FREE_MEMORY);    send(tot - used, pagesize);    send_tag(SYSTEM_TOTAL_MEMORY);#ifdef VXWORKS    send(latest_system_total, 1);    send_tag(LARGEST_FREE);    send(latest.maxBlockSizeFree, 1);    send_tag(NUMBER_OF_FREE);    send(latest.numBlocksFree, 1);#else    send(tot, pagesize);#endif    send_tag(SYSTEM_MEM_SHOW_END);}    static voidmessage_loop(int erlin_fd){    char cmdLen, cmd;    int res;        while (1){	/*	 *  Wait for command from Erlang	 */	if ((res = read(erlin_fd, &cmdLen, 1)) < 0) {	    print_error("Error reading from Erlang.");	    return;	}	if (res == 1) {		/* Exactly one byte read ? */	    if (cmdLen == 1){	/* Should be! */		switch (read(erlin_fd, &cmd, 1)){		case 1:	  		    switch (cmd){		    case MEM_SHOW:			simple_show_mem();			break;		    case SYSTEM_MEM_SHOW:			extended_show_mem();			break;		    default:	/* ignore all other messages */			break;		    }		  break;		  		case 0:		  print_error("Erlang has closed.");		  return;		default:		  print_error("Error reading from Erlang.");		  return;		} /* switch() */	    } else { /* cmdLen != 1 */		print_error("Invalid command length (%d) received.", cmdLen);		return;	    }	} else {		/* Erlang end closed */	    print_error("Erlang has closed.");	    return;	}    }}/* *  main */intMAIN(int argc, char **argv){  program_name = argv[0];  message_loop(ERLIN_FD);  return 0;}/* *  print_error * */static voidprint_error(const char *format,...){  va_list args;  va_start(args, format);  fprintf(stderr, "%s: ", program_name);  vfprintf(stderr, format, args);  va_end(args);  fprintf(stderr, " \n");}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?