1*b4dd7d09SAndy Fiddaman /*********************************************************************** 2*b4dd7d09SAndy Fiddaman * * 3*b4dd7d09SAndy Fiddaman * This software is part of the ast package * 4*b4dd7d09SAndy Fiddaman * Copyright (c) 1992-2012 AT&T Intellectual Property * 5*b4dd7d09SAndy Fiddaman * and is licensed under the * 6*b4dd7d09SAndy Fiddaman * Eclipse Public License, Version 1.0 * 7*b4dd7d09SAndy Fiddaman * by AT&T Intellectual Property * 8*b4dd7d09SAndy Fiddaman * * 9*b4dd7d09SAndy Fiddaman * A copy of the License is available at * 10*b4dd7d09SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html * 11*b4dd7d09SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12*b4dd7d09SAndy Fiddaman * * 13*b4dd7d09SAndy Fiddaman * Information and Software Systems Research * 14*b4dd7d09SAndy Fiddaman * AT&T Research * 15*b4dd7d09SAndy Fiddaman * Florham Park NJ * 16*b4dd7d09SAndy Fiddaman * * 17*b4dd7d09SAndy Fiddaman * Glenn Fowler <gsf@research.att.com> * 18*b4dd7d09SAndy Fiddaman * David Korn <dgk@research.att.com> * 19*b4dd7d09SAndy Fiddaman * * 20*b4dd7d09SAndy Fiddaman ***********************************************************************/ 21*b4dd7d09SAndy Fiddaman #pragma prototyped 22*b4dd7d09SAndy Fiddaman 23*b4dd7d09SAndy Fiddaman #define FORMAT "region=%(region)p method=%(method)s flags=%(flags)s size=%(size)d segments=%(segments)d busy=(%(busy_size)d,%(busy_blocks)d,%(busy_max)d) free=(%(free_size)d,%(free_blocks)d,%(free_max)d)" 24*b4dd7d09SAndy Fiddaman 25*b4dd7d09SAndy Fiddaman static const char usage[] = 26*b4dd7d09SAndy Fiddaman "[-?\n@(#)$Id: vmstate (AT&T Research) 2010-04-08 $\n]" 27*b4dd7d09SAndy Fiddaman USAGE_LICENSE 28*b4dd7d09SAndy Fiddaman "[+NAME?vmstate - list the calling process vmalloc region state]" 29*b4dd7d09SAndy Fiddaman "[+DESCRIPTION?When invoked as a shell builtin, \bvmstate\b lists the " 30*b4dd7d09SAndy Fiddaman "calling process \bvmalloc\b(3) state for all regions.]" 31*b4dd7d09SAndy Fiddaman "[f:format?List the ids specified by \aformat\a. \aformat\a follows " 32*b4dd7d09SAndy Fiddaman "\bprintf\b(3) conventions, except that \bsfio\b(3) inline ids are used " 33*b4dd7d09SAndy Fiddaman "instead of arguments: " 34*b4dd7d09SAndy Fiddaman "%[-+]][\awidth\a[.\aprecis\a[.\abase\a]]]]]](\aid\a)\achar\a. The " 35*b4dd7d09SAndy Fiddaman "supported \aid\as are:]:[format:=" FORMAT "]" 36*b4dd7d09SAndy Fiddaman "{" 37*b4dd7d09SAndy Fiddaman "[+method?The vmalloc method name.]" 38*b4dd7d09SAndy Fiddaman "[+flags?The vmalloc method flags.]" 39*b4dd7d09SAndy Fiddaman "[+size?The total region size.]" 40*b4dd7d09SAndy Fiddaman "[+segments?The number of segments in the region.]" 41*b4dd7d09SAndy Fiddaman "[+busy_size?The total busy block size.]" 42*b4dd7d09SAndy Fiddaman "[+busy_blocks?The number of busy blocks.]" 43*b4dd7d09SAndy Fiddaman "[+busy_max?The maximum busy block size.]" 44*b4dd7d09SAndy Fiddaman "[+free_size?The total free block size.]" 45*b4dd7d09SAndy Fiddaman "[+free_blocks?The number of free blocks.]" 46*b4dd7d09SAndy Fiddaman "[+free_max?The maximum free block size.]" 47*b4dd7d09SAndy Fiddaman "}" 48*b4dd7d09SAndy Fiddaman "[+SEE ALSO?\bvmalloc\b(3)]" 49*b4dd7d09SAndy Fiddaman ; 50*b4dd7d09SAndy Fiddaman 51*b4dd7d09SAndy Fiddaman #include <cmd.h> 52*b4dd7d09SAndy Fiddaman #include <vmalloc.h> 53*b4dd7d09SAndy Fiddaman #include <sfdisc.h> 54*b4dd7d09SAndy Fiddaman 55*b4dd7d09SAndy Fiddaman typedef struct State_s 56*b4dd7d09SAndy Fiddaman { 57*b4dd7d09SAndy Fiddaman char* format; 58*b4dd7d09SAndy Fiddaman Vmalloc_t* vm; 59*b4dd7d09SAndy Fiddaman Vmstat_t vs; 60*b4dd7d09SAndy Fiddaman unsigned int regions; 61*b4dd7d09SAndy Fiddaman Vmalloc_t* region[256]; 62*b4dd7d09SAndy Fiddaman } State_t; 63*b4dd7d09SAndy Fiddaman 64*b4dd7d09SAndy Fiddaman /* 65*b4dd7d09SAndy Fiddaman * sfkeyprintf() lookup 66*b4dd7d09SAndy Fiddaman * handle==0 for heading 67*b4dd7d09SAndy Fiddaman */ 68*b4dd7d09SAndy Fiddaman 69*b4dd7d09SAndy Fiddaman static int 70*b4dd7d09SAndy Fiddaman key(void* handle, Sffmt_t* fp, const char* arg, char** ps, Sflong_t* pn) 71*b4dd7d09SAndy Fiddaman { 72*b4dd7d09SAndy Fiddaman register State_t* state = (State_t*)handle; 73*b4dd7d09SAndy Fiddaman register char* s; 74*b4dd7d09SAndy Fiddaman 75*b4dd7d09SAndy Fiddaman if (!(s = fp->t_str) || streq(s, "size")) 76*b4dd7d09SAndy Fiddaman *pn = state->vs.extent; 77*b4dd7d09SAndy Fiddaman else if (streq(s, "region")) 78*b4dd7d09SAndy Fiddaman *pn = integralof(state->vm); 79*b4dd7d09SAndy Fiddaman else if (streq(s, "segments")) 80*b4dd7d09SAndy Fiddaman *pn = state->vs.n_seg; 81*b4dd7d09SAndy Fiddaman else if (streq(s, "busy_size")) 82*b4dd7d09SAndy Fiddaman *pn = state->vs.s_busy; 83*b4dd7d09SAndy Fiddaman else if (streq(s, "busy_blocks")) 84*b4dd7d09SAndy Fiddaman *pn = state->vs.n_busy; 85*b4dd7d09SAndy Fiddaman else if (streq(s, "busy_max")) 86*b4dd7d09SAndy Fiddaman *pn = state->vs.m_busy; 87*b4dd7d09SAndy Fiddaman else if (streq(s, "flags")) 88*b4dd7d09SAndy Fiddaman { 89*b4dd7d09SAndy Fiddaman *ps = s = fmtbuf(32); 90*b4dd7d09SAndy Fiddaman #ifdef VM_TRUST 91*b4dd7d09SAndy Fiddaman if (state->vs.mode & VM_TRUST) 92*b4dd7d09SAndy Fiddaman s = strcopy(s, "TRUST|"); 93*b4dd7d09SAndy Fiddaman #endif 94*b4dd7d09SAndy Fiddaman if (state->vs.mode & VM_TRACE) 95*b4dd7d09SAndy Fiddaman s = strcopy(s, "TRACE|"); 96*b4dd7d09SAndy Fiddaman if (state->vs.mode & VM_DBCHECK) 97*b4dd7d09SAndy Fiddaman s = strcopy(s, "DBCHECK|"); 98*b4dd7d09SAndy Fiddaman if (state->vs.mode & VM_DBABORT) 99*b4dd7d09SAndy Fiddaman s = strcopy(s, "DBABORT|"); 100*b4dd7d09SAndy Fiddaman if (s > *ps) 101*b4dd7d09SAndy Fiddaman *(s - 1) = 0; 102*b4dd7d09SAndy Fiddaman else 103*b4dd7d09SAndy Fiddaman strcpy(s, "0"); 104*b4dd7d09SAndy Fiddaman } 105*b4dd7d09SAndy Fiddaman else if (streq(s, "free_size")) 106*b4dd7d09SAndy Fiddaman *pn = state->vs.s_free; 107*b4dd7d09SAndy Fiddaman else if (streq(s, "free_blocks")) 108*b4dd7d09SAndy Fiddaman *pn = state->vs.n_free; 109*b4dd7d09SAndy Fiddaman else if (streq(s, "free_max")) 110*b4dd7d09SAndy Fiddaman *pn = state->vs.m_free; 111*b4dd7d09SAndy Fiddaman else if (streq(s, "format")) 112*b4dd7d09SAndy Fiddaman *ps = (char*)state->format; 113*b4dd7d09SAndy Fiddaman else if (streq(s, "method")) 114*b4dd7d09SAndy Fiddaman { 115*b4dd7d09SAndy Fiddaman if (state->vs.mode & VM_MTBEST) 116*b4dd7d09SAndy Fiddaman *ps = "best"; 117*b4dd7d09SAndy Fiddaman else if (state->vs.mode & VM_MTPOOL) 118*b4dd7d09SAndy Fiddaman *ps = "pool"; 119*b4dd7d09SAndy Fiddaman else if (state->vs.mode & VM_MTLAST) 120*b4dd7d09SAndy Fiddaman *ps = "last"; 121*b4dd7d09SAndy Fiddaman else if (state->vs.mode & VM_MTDEBUG) 122*b4dd7d09SAndy Fiddaman *ps = "debug"; 123*b4dd7d09SAndy Fiddaman else if (state->vs.mode & VM_MTPROFILE) 124*b4dd7d09SAndy Fiddaman *ps = "profile"; 125*b4dd7d09SAndy Fiddaman else 126*b4dd7d09SAndy Fiddaman *ps = "UNKNOWN"; 127*b4dd7d09SAndy Fiddaman } 128*b4dd7d09SAndy Fiddaman else 129*b4dd7d09SAndy Fiddaman { 130*b4dd7d09SAndy Fiddaman error(2, "%s: unknown format identifier", s); 131*b4dd7d09SAndy Fiddaman return 0; 132*b4dd7d09SAndy Fiddaman } 133*b4dd7d09SAndy Fiddaman return 1; 134*b4dd7d09SAndy Fiddaman } 135*b4dd7d09SAndy Fiddaman 136*b4dd7d09SAndy Fiddaman static int 137*b4dd7d09SAndy Fiddaman visit(Vmalloc_t* vm, void* addr, size_t size, Vmdisc_t* disc, void* handle) 138*b4dd7d09SAndy Fiddaman { 139*b4dd7d09SAndy Fiddaman State_t* state = (State_t*)handle; 140*b4dd7d09SAndy Fiddaman 141*b4dd7d09SAndy Fiddaman if (vm != state->vm) 142*b4dd7d09SAndy Fiddaman { 143*b4dd7d09SAndy Fiddaman state->vm = vm; 144*b4dd7d09SAndy Fiddaman if (state->regions < elementsof(state->region)) 145*b4dd7d09SAndy Fiddaman state->region[state->regions++] = vm; 146*b4dd7d09SAndy Fiddaman } 147*b4dd7d09SAndy Fiddaman return 0; 148*b4dd7d09SAndy Fiddaman } 149*b4dd7d09SAndy Fiddaman 150*b4dd7d09SAndy Fiddaman int 151*b4dd7d09SAndy Fiddaman b_vmstate(int argc, char** argv, Shbltin_t* context) 152*b4dd7d09SAndy Fiddaman { 153*b4dd7d09SAndy Fiddaman register int i; 154*b4dd7d09SAndy Fiddaman State_t state; 155*b4dd7d09SAndy Fiddaman 156*b4dd7d09SAndy Fiddaman memset(&state, 0, sizeof(state)); 157*b4dd7d09SAndy Fiddaman cmdinit(argc, argv, context, ERROR_CATALOG, 0); 158*b4dd7d09SAndy Fiddaman for (;;) 159*b4dd7d09SAndy Fiddaman { 160*b4dd7d09SAndy Fiddaman switch (optget(argv, usage)) 161*b4dd7d09SAndy Fiddaman { 162*b4dd7d09SAndy Fiddaman case 'f': 163*b4dd7d09SAndy Fiddaman state.format = opt_info.arg; 164*b4dd7d09SAndy Fiddaman continue; 165*b4dd7d09SAndy Fiddaman case '?': 166*b4dd7d09SAndy Fiddaman error(ERROR_USAGE|4, "%s", opt_info.arg); 167*b4dd7d09SAndy Fiddaman break; 168*b4dd7d09SAndy Fiddaman case ':': 169*b4dd7d09SAndy Fiddaman error(2, "%s", opt_info.arg); 170*b4dd7d09SAndy Fiddaman break; 171*b4dd7d09SAndy Fiddaman } 172*b4dd7d09SAndy Fiddaman break; 173*b4dd7d09SAndy Fiddaman } 174*b4dd7d09SAndy Fiddaman argv += opt_info.index; 175*b4dd7d09SAndy Fiddaman if (error_info.errors || *argv) 176*b4dd7d09SAndy Fiddaman error(ERROR_USAGE|4, "%s", optusage(NiL)); 177*b4dd7d09SAndy Fiddaman if (!state.format) 178*b4dd7d09SAndy Fiddaman state.format = FORMAT; 179*b4dd7d09SAndy Fiddaman 180*b4dd7d09SAndy Fiddaman /* 181*b4dd7d09SAndy Fiddaman * the walk must do no allocations because it locks the regions 182*b4dd7d09SAndy Fiddaman */ 183*b4dd7d09SAndy Fiddaman 184*b4dd7d09SAndy Fiddaman vmwalk(NiL, visit, &state); 185*b4dd7d09SAndy Fiddaman 186*b4dd7d09SAndy Fiddaman /* 187*b4dd7d09SAndy Fiddaman * now we can compute and list the state of each region 188*b4dd7d09SAndy Fiddaman */ 189*b4dd7d09SAndy Fiddaman 190*b4dd7d09SAndy Fiddaman for (i = 0; i < state.regions; i++) 191*b4dd7d09SAndy Fiddaman { 192*b4dd7d09SAndy Fiddaman state.vm = state.region[i]; 193*b4dd7d09SAndy Fiddaman vmstat(state.vm, &state.vs); 194*b4dd7d09SAndy Fiddaman sfkeyprintf(sfstdout, &state, state.format, key, NiL); 195*b4dd7d09SAndy Fiddaman sfprintf(sfstdout, "\n"); 196*b4dd7d09SAndy Fiddaman } 197*b4dd7d09SAndy Fiddaman return 0; 198*b4dd7d09SAndy Fiddaman } 199