diff options
author | Roger A. Faulkner <Roger.Faulkner@Oracle.COM> | 2010-04-03 09:48:44 -0700 |
---|---|---|
committer | Roger A. Faulkner <Roger.Faulkner@Oracle.COM> | 2010-04-03 09:48:44 -0700 |
commit | 3e14f97f673e8a630f076077de35afdd43dc1587 (patch) | |
tree | 9828b6b676f58d7b27dd28e00202d3f3461a5cd8 /usr/src/lib/libcmd/common/vmstate.c | |
parent | 4f60987df4dcaa54a88b596f861fbf4f3382c65e (diff) | |
download | illumos-joyent-3e14f97f673e8a630f076077de35afdd43dc1587.tar.gz |
6939349 RFE: Update ksh93 to ast-ksh.2010-03-09
6877392 ksh93 regresses 'uniq -c' performance
6887363 Korn shell 93 sometimes mishandles return value of its child process
6900314 (while true ; do true|true ; done) hang in ioctl() with SIGTTOU
6904557 wc no longer counts number of bytes correctly
6904575 cut -d with multibyte character no longer works
6904597 paste -d no longer works with multibyte characters
6904780 /usr/bin/cksum changed output in snv_128
6904870 uniq -s does not skip multibyte characters correctly
6904878 join -t no longer works with multibyte char separator
6907460 EXIT trap handlers are sometimes executed twice
6909579 libast getopt solaris compatibility broken
6920072 ksh93 tail -f, with unconditional .25s sleep and line parsing, about 37x slower than cat
6932124 mktemp in ksh93 is broken
Contributed by Olga Kryzhanovska <olga.kryzhanovska@gmail.com>
Diffstat (limited to 'usr/src/lib/libcmd/common/vmstate.c')
-rw-r--r-- | usr/src/lib/libcmd/common/vmstate.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/usr/src/lib/libcmd/common/vmstate.c b/usr/src/lib/libcmd/common/vmstate.c new file mode 100644 index 0000000000..79722972d2 --- /dev/null +++ b/usr/src/lib/libcmd/common/vmstate.c @@ -0,0 +1,163 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1992-2010 AT&T Intellectual Property * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.opensource.org/licenses/cpl1.0.txt * +* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped + +#define FORMAT "region=%(region)p 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)" + +static const char usage[] = +"[-?\n@(#)$Id: vmstate (AT&T Research) 2010-03-05 $\n]" +USAGE_LICENSE +"[+NAME?vmstate - list the calling process vmalloc region state]" +"[+DESCRIPTION?When invoked as a shell builtin, \bvmstate\b lists the " + "calling process \bvmalloc\b(3) state for all regions.]" +"[f:format?List the ids specified by \aformat\a. \aformat\a follows " + "\bprintf\b(3) conventions, except that \bsfio\b(3) inline ids are used " + "instead of arguments: " + "%[-+]][\awidth\a[.\aprecis\a[.\abase\a]]]]]](\aid\a)\achar\a. The " + "supported \aid\as are:]:[format:=" FORMAT "]" + "{" + "[+size?The total region size.]" + "[+segments?The number of segments in the region.]" + "[+busy_size?The total busy block size.]" + "[+busy_blocks?The number of busy blocks.]" + "[+busy_max?The maximum busy block size.]" + "[+free_size?The total free block size.]" + "[+free_blocks?The number of free blocks.]" + "[+free_max?The maximum free block size.]" + "}" +"[+SEE ALSO?\bvmalloc\b(3)]" +; + +#include <cmd.h> +#include <vmalloc.h> + +typedef struct State_s +{ + char* format; + Vmalloc_t* vm; + Vmstat_t vs; + unsigned int regions; + Vmalloc_t* region[256]; +} State_t; + +/* + * sfkeyprintf() lookup + * handle==0 for heading + */ + +static int +key(void* handle, Sffmt_t* fp, const char* arg, char** ps, Sflong_t* pn) +{ + register State_t* state = (State_t*)handle; + register char* s; + + if (!(s = fp->t_str) || streq(s, "size")) + *pn = state->vs.extent; + else if (streq(s, "region")) + *pn = integralof(state->vm); + else if (streq(s, "segments")) + *pn = state->vs.n_seg; + else if (streq(s, "busy_size")) + *pn = state->vs.s_busy; + else if (streq(s, "busy_blocks")) + *pn = state->vs.n_busy; + else if (streq(s, "busy_max")) + *pn = state->vs.m_busy; + else if (streq(s, "free_size")) + *pn = state->vs.s_free; + else if (streq(s, "free_blocks")) + *pn = state->vs.n_free; + else if (streq(s, "free_max")) + *pn = state->vs.m_free; + else if (streq(s, "format")) + *ps = (char*)state->format; + else + { + error(2, "%s: unknown format identifier", s); + return 0; + } + return 1; +} + +static int +visit(Vmalloc_t* vm, void* addr, size_t size, Vmdisc_t* disc, void* handle) +{ + State_t* state = (State_t*)handle; + Vmstat_t vs; + + if (vm != state->vm) + { + state->vm = vm; + if (state->regions < elementsof(state->region)) + state->region[state->regions++] = vm; + } + return 0; +} + +int +b_vmstate(int argc, char** argv, void* context) +{ + register int i; + State_t state; + + memset(&state, 0, sizeof(state)); + cmdinit(argc, argv, context, ERROR_CATALOG, 0); + for (;;) + { + switch (optget(argv, usage)) + { + case 'f': + state.format = opt_info.arg; + continue; + case '?': + error(ERROR_USAGE|4, "%s", opt_info.arg); + continue; + case ':': + error(2, "%s", opt_info.arg); + continue; + } + break; + } + argv += opt_info.index; + if (error_info.errors || *argv) + error(ERROR_USAGE|4, "%s", optusage(NiL)); + if (!state.format) + state.format = FORMAT; + + /* + * the walk must do no allocations because it locks the regions + */ + + vmwalk(NiL, visit, &state); + + /* + * now we can compute and list the state of each region + */ + + for (i = 0; i < state.regions; i++) + { + state.vm = state.region[i]; + vmstat(state.vm, &state.vs); + sfkeyprintf(sfstdout, &state, state.format, key, NiL); + sfprintf(sfstdout, "\n"); + } + return 0; +} |