/***************************************************************************** ** MEMSTAT: A set of routines to determine where all that bloody memory ** is going to! ****************************************************************************/ #include <stdlib.h> #include <sys/time.h> #include <sys/resource.h> #include <unistd.h> #include <sys/types.h> #include "gen.h" #include "events.h" #include "config.h" /* Definition for a linked list with all used types in it, where we can store * how many entries of each block have been allocated. */ typedef struct _memoryBlock { size_t count; int typenr; struct _memoryBlock *next; } memoryBlock; typedef struct _dataType { char *name; int typenr; size_t datasize; } dataType; dataType LocalTypes[] = { { "token_record", REC_TOKEN, sizeof(token_record) }, { "string_record", REC_STRING, sizeof(string_record) }, { "loc_str_record", REC_LOCSTR, sizeof(loc_str_record) }, { "location_record", REC_LOCATION, sizeof(location_record) }, { "mobile_record", REC_MOBILE, sizeof(mobile_record) }, { "object_record", REC_OBJECT, sizeof(object_record) }, { "zone_record", REC_ZONE, sizeof(zone_record) }, { "thecode_record", REC_THECODE, sizeof(thecode_record) }, { "param_record", REC_PARAM, sizeof(param_record) }, { "mudcode_record", REC_MUDCODE, sizeof(mudcode_record) }, { "stmt_list_record", REC_STMTLIST, sizeof(stmt_list_record) }, { "trap_desc", REC_TRAPDESC, sizeof(trap_desc) }, { "trap_record", REC_TRAP, sizeof(trap_record) }, { "memoryBlock", REC_MEMSTAT, sizeof(memoryBlock) }, { "arith_number", REC_ARITHNR, sizeof(arith_number) }, { "arith_string", REC_ARITHSTR, sizeof(arith_string) }, { "mudfunct_param", REC_MFPARAM, sizeof(mudfunct_param) }, { "mudfunct_decl", REC_MFDECL, sizeof(mudfunct_decl) }, { "ident_decl", REC_IDENTDECL, sizeof(ident_decl) }, { "raw_decl", REC_RAWDECL, sizeof(raw_decl) }, { "block_decl", REC_BLOCKDECL, sizeof(block_decl) }, { "if_decl", REC_IFDECL, sizeof(if_decl) }, { "while_decl", REC_WHILEDECL, sizeof(while_decl) }, { "for_decl", REC_FORDECL, sizeof(for_decl) }, { "const_decl", REC_CONSTDECL, sizeof(const_decl) }, { "var_decl", REC_VARDECL, sizeof(var_decl) }, { "the_stmt", REC_THESTMT, sizeof(the_stmt) }, { "stmt_record", REC_STMT, sizeof(stmt_record) }, { "hashRecord", REC_HRECORD, sizeof(hashRecord) }, { "hashTable", REC_HTABLE, sizeof(hashTable) }, { "string", REC_CHAR, sizeof(char) }, { "ConfigOpt", REC_CONFIG, sizeof(ConfigOpt) }, { "event_record", REC_EVENT, sizeof(event_record) }, { "bool_stmt", REC_BOOLSTMT, sizeof(bool_stmt) }, { TABLE_END, -1 , -1} }; memoryBlock *dynamicList = NULL; void updateMemStat(int typenr, int count) { memoryBlock *p = dynamicList; while (p != NULL && p->typenr != typenr) p = p->next; if (p != NULL) p->count += count; } void initializeMemStat() { memoryBlock *p; int i; for (i = 0; LocalTypes[i].name != TABLE_END; i++) { p = (memoryBlock *)malloc(sizeof(memoryBlock)); p->typenr = LocalTypes[i].typenr; p->count = 0; p->next = dynamicList; dynamicList = p; } updateMemStat(REC_MEMSTAT,i); } void xfree(void *p, int typenr) { #ifdef MEMORY_STATISTIC if (typenr == REC_CHAR) updateMemStat(typenr,(strlen(p) + 1) * (-1)); else updateMemStat(typenr,-1); #endif free(p); } #ifdef MEMORY_STATISTIC static memoryBlock *findMemoryBlock(int typenr) { memoryBlock *p = dynamicList; while (p != NULL && p->typenr != typenr) p = p->next; return p; } #endif void printMemStat(void) { #ifdef MEMORY_STATISTIC memoryBlock *p; struct rusage r; int i; getrusage(RUSAGE_SELF,&r); printf("Data Type Size Number Total Allocated\n"); for (i = 0; LocalTypes[i].name != TABLE_END; i++) { p = findMemoryBlock(LocalTypes[i].typenr); if (p != NULL) printf("%-15.15s %-4d %-6d %d\n",LocalTypes[i].name, LocalTypes[i].datasize, p->count, p->count * LocalTypes[i].datasize); } printf("RUSAGE Stats:\n" " Max Resident Size = %ld\n" " Integral Shared Memory Size = %ld\n" "Integral Unshared Memory Size = %ld\n" " Integral Unshared Stack Size = %ld\n\n" " Page recliams = %ld\n" " Page Faults = %ld\n\n", r.ru_maxrss,r.ru_ixrss,r.ru_idrss,r.ru_isrss,r.ru_minflt,r.ru_majflt); #else printf("Memory statistics have been disabled.\n"); #endif }