Module Name: src
Committed By: sjg
Date: Fri Jun 3 01:21:59 UTC 2016
Modified Files:
src/usr.bin/make: main.c make.h meta.c nonints.h var.c
Log Message:
Add cached_realpath()
realpath(3) is expensive, and meta mode at least uses it extensively.
We use cached_realpath() to save the result of successful calls to
realpath(3) in a private variable context.
This improves the worst case performance (eg examining libc with
nothing to do) by a factor of 4.
Reviewed by: christos
To generate a diff of this commit:
cvs rdiff -u -r1.244 -r1.245 src/usr.bin/make/main.c
cvs rdiff -u -r1.98 -r1.99 src/usr.bin/make/make.h
cvs rdiff -u -r1.58 -r1.59 src/usr.bin/make/meta.c
cvs rdiff -u -r1.72 -r1.73 src/usr.bin/make/nonints.h
cvs rdiff -u -r1.207 -r1.208 src/usr.bin/make/var.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/make/main.c
diff -u src/usr.bin/make/main.c:1.244 src/usr.bin/make/main.c:1.245
--- src/usr.bin/make/main.c:1.244 Tue Apr 5 04:25:43 2016
+++ src/usr.bin/make/main.c Fri Jun 3 01:21:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.244 2016/04/05 04:25:43 sjg Exp $ */
+/* $NetBSD: main.c,v 1.245 2016/06/03 01:21:59 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.244 2016/04/05 04:25:43 sjg Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.245 2016/06/03 01:21:59 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 19
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: main.c,v 1.244 2016/04/05 04:25:43 sjg Exp $");
+__RCSID("$NetBSD: main.c,v 1.245 2016/06/03 01:21:59 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -979,7 +979,7 @@ main(int argc, char **argv)
/*
* A relative path, canonicalize it.
*/
- p1 = realpath(argv[0], mdpath);
+ p1 = cached_realpath(argv[0], mdpath);
if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) {
p1 = argv[0]; /* realpath failed */
}
@@ -1850,6 +1850,40 @@ usage(void)
}
+/*
+ * realpath(3) can get expensive, cache results...
+ */
+char *
+cached_realpath(const char *pathname, char *resolved)
+{
+ static GNode *cache;
+ char *rp, *cp;
+
+ if (!pathname || !pathname[0])
+ return NULL;
+
+ if (!cache) {
+ cache = Targ_NewGN("Realpath");
+#ifndef DEBUG_REALPATH_CACHE
+ cache->flags = INTERNAL;
+#endif
+ }
+
+ rp = Var_Value(pathname, cache, &cp);
+ if (rp) {
+ /* a hit */
+ if (resolved)
+ strlcpy(resolved, rp, MAXPATHLEN);
+ else
+ resolved = bmake_strdup(rp);
+ } else {
+ if ((rp = realpath(pathname, resolved))) {
+ Var_Set(pathname, rp, cache, 0);
+ }
+ }
+ return rp ? resolved : NULL;
+}
+
int
PrintAddr(void *a, void *b)
{
Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.98 src/usr.bin/make/make.h:1.99
--- src/usr.bin/make/make.h:1.98 Thu Feb 18 18:29:14 2016
+++ src/usr.bin/make/make.h Fri Jun 3 01:21:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.98 2016/02/18 18:29:14 christos Exp $ */
+/* $NetBSD: make.h,v 1.99 2016/06/03 01:21:59 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -183,6 +183,7 @@ typedef struct GNode {
#define DONE_ALLSRC 0x40 /* We do it once only */
#define CYCLE 0x1000 /* Used by MakePrintStatus */
#define DONECYCLE 0x2000 /* Used by MakePrintStatus */
+#define INTERNAL 0x4000 /* Internal use only */
enum enum_made {
UNMADE, DEFERRED, REQUESTED, BEINGMADE,
MADE, UPTODATE, ERROR, ABORTED
Index: src/usr.bin/make/meta.c
diff -u src/usr.bin/make/meta.c:1.58 src/usr.bin/make/meta.c:1.59
--- src/usr.bin/make/meta.c:1.58 Fri Jun 3 01:16:27 2016
+++ src/usr.bin/make/meta.c Fri Jun 3 01:21:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: meta.c,v 1.58 2016/06/03 01:16:27 sjg Exp $ */
+/* $NetBSD: meta.c,v 1.59 2016/06/03 01:21:59 sjg Exp $ */
/*
* Implement 'meta' mode.
@@ -251,7 +251,7 @@ meta_name(struct GNode *gn, char *mname,
* basename as given to us.
*/
if ((cp = strrchr(tname, '/'))) {
- if (realpath(tname, buf)) {
+ if (cached_realpath(tname, buf)) {
if ((rp = strrchr(buf, '/'))) {
rp++;
cp++;
@@ -433,7 +433,7 @@ meta_needed(GNode *gn, const char *dname
}
/* make sure these are canonical */
- if (realpath(dname, objdir))
+ if (cached_realpath(dname, objdir))
dname = objdir;
/* If we aren't in the object directory, don't create a meta file. */
@@ -1256,7 +1256,7 @@ meta_oodate(GNode *gn, Boolean oodate)
* they are _expected_ to change.
*/
if (*p == '/') {
- realpath(p, fname1); /* clean it up */
+ cached_realpath(p, fname1); /* clean it up */
if (Lst_ForEach(metaIgnorePaths, prefix_match, fname1)) {
#ifdef DEBUG_META_MODE
if (DEBUG(META))
@@ -1341,7 +1341,7 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE;
} else if (S_ISDIR(fs.st_mode)) {
/* Update the latest directory. */
- realpath(p, latestdir);
+ cached_realpath(p, latestdir);
}
} else if (errno == ENOENT && *p == '/' &&
strncmp(p, cwd, cwdlen) != 0) {
Index: src/usr.bin/make/nonints.h
diff -u src/usr.bin/make/nonints.h:1.72 src/usr.bin/make/nonints.h:1.73
--- src/usr.bin/make/nonints.h:1.72 Thu Feb 18 20:25:08 2016
+++ src/usr.bin/make/nonints.h Fri Jun 3 01:21:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: nonints.h,v 1.72 2016/02/18 20:25:08 sjg Exp $ */
+/* $NetBSD: nonints.h,v 1.73 2016/06/03 01:21:59 sjg Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -120,6 +120,7 @@ void execError(const char *, const char
char *getTmpdir(void);
Boolean s2Boolean(const char *, Boolean);
Boolean getBoolean(const char *, Boolean);
+char *cached_realpath(const char *, char *);
/* parse.c */
void Parse_Error(int, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.207 src/usr.bin/make/var.c:1.208
--- src/usr.bin/make/var.c:1.207 Fri Mar 11 15:12:39 2016
+++ src/usr.bin/make/var.c Fri Jun 3 01:21:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.207 2016/03/11 15:12:39 matthias Exp $ */
+/* $NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.207 2016/03/11 15:12:39 matthias Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: var.c,v 1.207 2016/03/11 15:12:39 matthias Exp $");
+__RCSID("$NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -531,7 +531,7 @@ VarAdd(const char *name, const char *val
h = Hash_CreateEntry(&ctxt->context, name, NULL);
Hash_SetValue(h, v);
v->name = h->name;
- if (DEBUG(VAR)) {
+ if (DEBUG(VAR) && (ctxt->flags & INTERNAL) == 0) {
fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
}
}
@@ -1951,7 +1951,7 @@ VarRealpath(GNode *ctx MAKE_ATTR_UNUSED,
Buf_AddByte(buf, vpstate->varSpace);
}
addSpace = TRUE;
- rp = realpath(word, rbuf);
+ rp = cached_realpath(word, rbuf);
if (rp && *rp == '/' && stat(rp, &st) == 0)
word = rp;