Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/fincore a utility to show in-core status of file pages
details: https://anonhg.NetBSD.org/src/rev/2ecaa40de752
branches: trunk
changeset: 771933:2ecaa40de752
user: yamt <yamt%NetBSD.org@localhost>
date: Fri Dec 09 15:17:34 2011 +0000
description:
a utility to show in-core status of file pages
diffstat:
usr.bin/fincore/Makefile | 5 +
usr.bin/fincore/fincore.1 | 103 ++++++++++++++++++++++
usr.bin/fincore/fincore.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 319 insertions(+), 0 deletions(-)
diffs (truncated from 331 to 300 lines):
diff -r 431975c546b1 -r 2ecaa40de752 usr.bin/fincore/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/fincore/Makefile Fri Dec 09 15:17:34 2011 +0000
@@ -0,0 +1,5 @@
+# $NetBSD: Makefile,v 1.1 2011/12/09 15:17:34 yamt Exp $
+
+PROG= fincore
+
+.include <bsd.prog.mk>
diff -r 431975c546b1 -r 2ecaa40de752 usr.bin/fincore/fincore.1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/fincore/fincore.1 Fri Dec 09 15:17:34 2011 +0000
@@ -0,0 +1,103 @@
+.\" $NetBSD: fincore.1,v 1.1 2011/12/09 15:17:34 yamt Exp $
+.\"
+.\" Copyright (c)2011 YAMAMOTO Takashi,
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" ------------------------------------------------------------
+.Dd December 9, 2011
+.Dt FINCORE 1
+.Os
+.\" ------------------------------------------------------------
+.Sh NAME
+.Nm fincore
+.Nd query in-core status of file pages
+.\" ------------------------------------------------------------
+.Sh SYNOPSIS
+.Nm
+.Op Fl qs
+.Ar file ...
+.\" ------------------------------------------------------------
+.Sh DESCRIPTION
+The
+.Nm
+utility queries and displays in-core status of specified files.
+.Pp
+Note that the result can already be stale when being output due to other
+activities in the system.
+Thus it should be used only for advisary purposes.
+.Pp
+The
+.Nm
+utility accepts the following options.
+.Bl -tag -width hogehoge
+.It Fl q
+The quiet mode.
+Outputs nothing unless the file has in-core pages.
+.It Fl s
+The summary mode.
+Only shows number of pages.
+.El
+.\" ------------------------------------------------------------
+.Sh EXAMPLES
+The following example shows that /bin/cat and /bin/cp are fully cached in-core
+while the other executables are not in-core.
+numbers shown in the default output are page indexes in the file of
+each in-core pages.
+.Bd -literal
+% fincore /bin/c*
+/bin/cat: 0 1 2 3
+/bin/chio:
+/bin/chmod:
+/bin/cp: 0 1 2 3 4 5
+/bin/cpio:
+/bin/csh:
+% fincore -s /bin/c*
+/bin/cat: 4 / 4 in-core pages (100.00%)
+/bin/chio: 0 / 5 in-core pages (0.00%)
+/bin/chmod: 0 / 3 in-core pages (0.00%)
+/bin/cp: 6 / 6 in-core pages (100.00%)
+/bin/cpio: 0 / 36 in-core pages (0.00%)
+/bin/csh: 0 / 41 in-core pages (0.00%)
+.Ed
+.\" ------------------------------------------------------------
+.\".Sh HISTORY
+.\"The
+.\".Nm
+.\"utility first appeared in
+.\".Nx XXX .
+.\" ------------------------------------------------------------
+.\".Sh SEE ALSO
+.\".Xr XXX
+.\" ------------------------------------------------------------
+.Sh AUTHORS
+The
+.Nm
+utility is written by
+.An YAMAMOTO Takashi .
+.\" ------------------------------------------------------------
+.Sh BUGS
+The amount of CPU time the current implementation of
+.Nm
+utility would take is roughly proportional to the file sizes.
+Ideally it should be proportional to the number of in-core pages.
diff -r 431975c546b1 -r 2ecaa40de752 usr.bin/fincore/fincore.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/fincore/fincore.c Fri Dec 09 15:17:34 2011 +0000
@@ -0,0 +1,211 @@
+/* $NetBSD: fincore.c,v 1.1 2011/12/09 15:17:34 yamt Exp $ */
+
+/*-
+ * Copyright (c) 2011 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * a utility to query which file pages are cached
+ *
+ * inspired by:
+ * http://net.doit.wisc.edu/~plonka/fincore/
+ * http://www.usenix.org/events/lisa07/tech/plonka.html
+ */
+
+#include <sys/cdefs.h>
+#if defined(__NetBSD__)
+#ifndef lint
+__RCSID("$NetBSD: fincore.c,v 1.1 2011/12/09 15:17:34 yamt Exp $");
+#endif /* not lint */
+#endif /* defined(__NetBSD__) */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if !defined(__arraycount)
+#define __arraycount(a) (sizeof(a)/sizeof(*a))
+#endif /* !defined(__arraycount) */
+
+size_t page_size;
+bool do_summary;
+bool be_quiet;
+
+/*
+ * fincore: query which pages of the file are in-core.
+ *
+ * this function is intended to be compatible with:
+ * http://lwn.net/Articles/371538/
+ * http://libprefetch.cs.ucla.edu/
+ *
+ * while this can be implemented in kernel much more efficiently, i'm not
+ * sure if making this a syscall in 2011 is a good idea. this API does not
+ * seem scalable for sparsely cached huge files. the expected scalability
+ * has been changed since the time when mincore was invented.
+ *
+ * some references:
+ * http://wiki.postgresql.org/images/a/a2/Pgfincore_pgday10.pdf
+ */
+
+static int
+fincore(int fd, off_t startoff, off_t endoff, unsigned char *vec)
+{
+ off_t off;
+ size_t chunk_size;
+
+ for (off = startoff; off < endoff;
+ off += chunk_size, vec += chunk_size / page_size) {
+ void *vp;
+
+ chunk_size = MIN((off_t)(1024 * page_size), endoff - off);
+ vp = mmap(NULL, chunk_size, PROT_NONE, MAP_FILE|MAP_SHARED,
+ fd, off);
+ if (vp == MAP_FAILED) {
+ return -1;
+ }
+ if (mincore(vp, chunk_size,
+#if !defined(__linux__)
+ (char *)
+#endif /* !defined(__linux__) */
+ vec)) {
+ munmap(vp, chunk_size);
+ return -1;
+ }
+ if (munmap(vp, chunk_size)) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void
+do_file(const char *name)
+{
+ unsigned char vec[4096];
+ struct stat st;
+ uintmax_t n; /* number of pages in-core */
+ off_t off;
+ size_t chunk_size;
+ int fd;
+ bool header_done = false;
+
+ fd = open(name, O_RDONLY);
+ if (fd == -1) {
+ err(EXIT_FAILURE, "open %s", name);
+ }
+ if (fstat(fd, &st)) {
+ err(EXIT_FAILURE, "fstat %s", name);
+ }
+ n = 0;
+ for (off = 0; off < st.st_size; off += chunk_size) {
+ unsigned int i;
+
+ chunk_size = MIN(__arraycount(vec) * page_size,
+ roundup(st.st_size - off, page_size));
+ if (fincore(fd, off, off + chunk_size, vec)) {
+ printf("\n");
+ err(EXIT_FAILURE, "fincore %s", name);
+ }
+ for (i = 0; i < chunk_size / page_size; i++) {
+ if (vec[i] == 0) {
+ continue;
+ }
+ if (!do_summary) {
+ if (!header_done) {
+ printf("%s:", name);
+ header_done = true;
+ }
+ printf(" %ju",
+ (uintmax_t)(off / page_size + i));
+ }
+ n++;
+ }
+ }
+ close(fd);
+ if (do_summary && (n != 0 || !be_quiet)) {
+ const uintmax_t total = howmany(st.st_size, page_size);
+ const double pct = (total != 0) ? ((double)n / total * 100) : 0;
+
+ if (!header_done) {
+ printf("%s:", name);
+ header_done = true;
+ }
+ printf(" %ju / %ju in-core pages (%0.2f%%)", n, total, pct);
+ }
+ if (header_done) {
+ printf("\n");
+ } else if (!be_quiet) {
+ printf("%s: \n", name);
+ }
+}
+
+int
+/*ARGSUSED*/
+main(int argc, char *argv[])
+{
+ extern int optind;
+ long l;
+ int ch;
+
Home |
Main Index |
Thread Index |
Old Index