Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make Extend the mtimes cache used by dir.c so it can...



details:   https://anonhg.NetBSD.org/src/rev/7939d2a5e6e0
branches:  trunk
changeset: 345750:7939d2a5e6e0
user:      sjg <sjg%NetBSD.org@localhost>
date:      Tue Jun 07 00:40:00 2016 +0000

description:
Extend the mtimes cache used by dir.c so it can be used by others.

We store both st_mtime and st_mode, since some callers care about the
later.

Reviewed by: christos

diffstat:

 usr.bin/make/dir.c  |  115 ++++++++++++++++++++++++++++++++++++++-------------
 usr.bin/make/hash.h |   13 +----
 usr.bin/make/make.h |    4 +-
 usr.bin/make/meta.c |   10 ++--
 4 files changed, 98 insertions(+), 44 deletions(-)

diffs (truncated from 310 to 300 lines):

diff -r 7abeee04bdd2 -r 7939d2a5e6e0 usr.bin/make/dir.c
--- a/usr.bin/make/dir.c        Mon Jun 06 21:06:33 2016 +0000
+++ b/usr.bin/make/dir.c        Tue Jun 07 00:40:00 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $        */
+/*     $NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $     */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $";
+static char rcsid[] = "$NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)dir.c      8.2 (Berkeley) 1/2/94";
 #else
-__RCSID("$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $");
+__RCSID("$NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -244,6 +244,7 @@
                             * be two rules to update a single file, so this
                             * should be ok, but... */
 
+static Hash_Table lmtimes;  /* same as mtimes but for lstat */
 
 static int DirFindName(const void *, const void *);
 static int DirMatchFiles(const char *, Path *, Lst);
@@ -256,6 +257,80 @@
 static char *DirFindDot(Boolean, const char *, const char *);
 static char *DirLookupAbs(Path *, const char *, const char *);
 
+
+/*
+ * We use stat(2) a lot, cache the results
+ * mtime and mode are all we care about.
+ */
+struct cache_st {
+    time_t mtime;
+    mode_t  mode;
+};
+
+/* minimize changes below */
+static time_t
+Hash_GetTimeValue(Hash_Entry *entry)
+{
+    struct cache_st *cst;
+
+    cst = entry->clientPtr;
+    return cst->mtime;
+}
+
+#define CST_LSTAT 1
+#define CST_UPDATE 2
+
+static int
+cached_stats(Hash_Table *htp, const char *pathname, struct stat *st, int flags)
+{
+    Hash_Entry *entry;
+    struct cache_st *cst;
+    int rc;
+
+    if (!pathname || !pathname[0])
+       return -1;
+
+    entry = Hash_FindEntry(htp, pathname);
+
+    if (entry && (flags & CST_UPDATE) == 0) {
+       cst = entry->clientPtr;
+
+       memset(st, 0, sizeof(*st));
+       st->st_mtime = cst->mtime;
+       st->st_mode = cst->mode;
+       return 0;
+    }
+
+    rc = (flags & CST_LSTAT) ? lstat(pathname, st) : stat(pathname, st);
+    if (rc == -1)
+       return -1;
+
+    if (st->st_mtime == 0)
+       st->st_mtime = 1;      /* avoid confusion with missing file */
+
+    if (!entry)
+       entry = Hash_CreateEntry(htp, pathname, NULL);
+    if (!entry->clientPtr)
+       entry->clientPtr = bmake_malloc(sizeof(*cst));
+    cst = entry->clientPtr;
+    cst->mtime = st->st_mtime;
+    cst->mode = st->st_mode;
+
+    return 0;
+}
+
+int
+cached_stat(const char *pathname, void *st)
+{
+    return cached_stats(&mtimes, pathname, st, 0);
+}
+
+int
+cached_lstat(const char *pathname, void *st)
+{
+    return cached_stats(&lmtimes, pathname, st, CST_LSTAT);
+}
+
 /*-
  *-----------------------------------------------------------------------
  * Dir_Init --
@@ -274,6 +349,7 @@
     dirSearchPath = Lst_Init(FALSE);
     openDirectories = Lst_Init(FALSE);
     Hash_InitTable(&mtimes, 0);
+    Hash_InitTable(&lmtimes, 0);
 
     Dir_InitCur(cdname);
 
@@ -901,7 +977,6 @@
 DirLookupSubdir(Path *p, const char *name)
 {
     struct stat          stb;          /* Buffer for stat, if necessary */
-    Hash_Entry  *entry;        /* Entry for mtimes table */
     char        *file;         /* the current filename to check */
 
     if (p != dot) {
@@ -917,9 +992,7 @@
        fprintf(debug_file, "checking %s ...\n", file);
     }
 
-    if (stat(file, &stb) == 0) {
-       if (stb.st_mtime == 0)
-               stb.st_mtime = 1;
+    if (cached_stat(file, &stb) == 0) {
        /*
         * Save the modification time so if it's needed, we don't have
         * to fetch it again.
@@ -928,8 +1001,6 @@
            fprintf(debug_file, "   Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
                    file);
        }
-       entry = Hash_CreateEntry(&mtimes, file, NULL);
-       Hash_SetTimeValue(entry, stb.st_mtime);
        nearmisses += 1;
        return (file);
     }
@@ -1312,15 +1383,11 @@
            fprintf(debug_file, "   got it (in mtime cache)\n");
        }
        return(bmake_strdup(name));
-    } else if (stat(name, &stb) == 0) {
-       if (stb.st_mtime == 0)
-               stb.st_mtime = 1;
-       entry = Hash_CreateEntry(&mtimes, name, NULL);
+    } else if (cached_stat(name, &stb) == 0) {
        if (DEBUG(DIR)) {
            fprintf(debug_file, "   Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
                    name);
        }
-       Hash_SetTimeValue(entry, stb.st_mtime);
        return (bmake_strdup(name));
     } else {
        if (DEBUG(DIR)) {
@@ -1368,7 +1435,7 @@
 
                /* try and stat(2) it ... */
                snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
-               if (stat(try, &st) != -1) {
+               if (cached_stat(try, &st) != -1) {
                        /*
                         * success!  if we found a file, chop off
                         * the filename so we return a directory.
@@ -1489,12 +1556,12 @@
     else
        entry = NULL;
     if (entry != NULL) {
+       stb.st_mtime = Hash_GetTimeValue(entry);
        if (DEBUG(DIR)) {
            fprintf(debug_file, "Using cached time %s for %s\n",
-                   Targ_FmtTime(Hash_GetTimeValue(entry)), fullName);
+                   Targ_FmtTime(stb.st_mtime), fullName);
        }
-       stb.st_mtime = Hash_GetTimeValue(entry);
-    } else if (stat(fullName, &stb) < 0) {
+    } else if (cached_stats(&mtimes, fullName, &stb, recheck ? CST_UPDATE : 0) < 0) {
        if (gn->type & OP_MEMBER) {
            if (fullName != gn->path)
                free(fullName);
@@ -1502,18 +1569,8 @@
        } else {
            stb.st_mtime = 0;
        }
-    } else {
-       if (stb.st_mtime == 0) {
-               /*
-                * 0 handled specially by the code, if the time is really 0,
-                * return something else instead
-                */
-               stb.st_mtime = 1;
-       }
-       entry = Hash_CreateEntry(&mtimes, fullName, NULL);
-       Hash_SetTimeValue(entry, stb.st_mtime);
     }
-       
+
     if (fullName && gn->path == NULL) {
        gn->path = fullName;
     }
diff -r 7abeee04bdd2 -r 7939d2a5e6e0 usr.bin/make/hash.h
--- a/usr.bin/make/hash.h       Mon Jun 06 21:06:33 2016 +0000
+++ b/usr.bin/make/hash.h       Tue Jun 07 00:40:00 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hash.h,v 1.10 2009/01/24 10:59:09 dsl Exp $    */
+/*     $NetBSD: hash.h,v 1.11 2016/06/07 00:40:00 sjg Exp $    */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -89,10 +89,7 @@
     struct Hash_Entry *next;           /* Used to link together all the
                                         * entries associated with the same
                                         * bucket. */
-    union {
-       void          *clientPtr;       /* Arbitrary pointer */
-       time_t        clientTime;       /* Arbitrary Time */
-    } clientInfo;
+    void             *clientPtr;       /* Arbitrary pointer */
     unsigned         namehash;         /* hash value of key */
     char             name[1];          /* key string */
 } Hash_Entry;
@@ -125,8 +122,7 @@
  *     Hash_Entry *h;
  */
 
-#define Hash_GetValue(h) ((h)->clientInfo.clientPtr)
-#define Hash_GetTimeValue(h) ((h)->clientInfo.clientTime)
+#define Hash_GetValue(h) ((h)->clientPtr)
 
 /*
  * Hash_SetValue(h, val);
@@ -134,8 +130,7 @@
  *     char *val;
  */
 
-#define Hash_SetValue(h, val) ((h)->clientInfo.clientPtr = (val))
-#define Hash_SetTimeValue(h, val) ((h)->clientInfo.clientTime = (val))
+#define Hash_SetValue(h, val) ((h)->clientPtr = (val))
 
 /*
  * Hash_Size(n) returns the number of words in an object of n bytes
diff -r 7abeee04bdd2 -r 7939d2a5e6e0 usr.bin/make/make.h
--- a/usr.bin/make/make.h       Mon Jun 06 21:06:33 2016 +0000
+++ b/usr.bin/make/make.h       Tue Jun 07 00:40:00 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: make.h,v 1.99 2016/06/03 01:21:59 sjg Exp $    */
+/*     $NetBSD: make.h,v 1.100 2016/06/07 00:40:00 sjg Exp $   */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -490,6 +490,8 @@
 Boolean Main_SetObjdir(const char *);
 int mkTempFile(const char *, char **);
 int str2Lst_Append(Lst, char *, const char *);
+int cached_lstat(const char *, void *);
+int cached_stat(const char *, void *);
 
 #define        VARF_UNDEFERR   1
 #define        VARF_WANTRES    2
diff -r 7abeee04bdd2 -r 7939d2a5e6e0 usr.bin/make/meta.c
--- a/usr.bin/make/meta.c       Mon Jun 06 21:06:33 2016 +0000
+++ b/usr.bin/make/meta.c       Tue Jun 07 00:40:00 2016 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: meta.c,v 1.60 2016/06/04 22:17:14 sjg Exp $ */
+/*      $NetBSD: meta.c,v 1.61 2016/06/07 00:40:00 sjg Exp $ */
 
 /*
  * Implement 'meta' mode.
@@ -425,7 +425,7 @@
     }
 
     /* The object directory may not exist. Check it.. */
-    if (stat(dname, &fs) != 0) {
+    if (cached_stat(dname, &fs) != 0) {
        if (verbose)
            fprintf(debug_file, "Skipping meta for %s: no .OBJDIR\n",
                    gn->name);
@@ -1234,8 +1234,8 @@
                    if ((strstr("tmp", p)))
                        break;
 
-                   if ((link_src != NULL && lstat(p, &fs) < 0) ||
-                       (link_src == NULL && stat(p, &fs) < 0)) {
+                   if ((link_src != NULL && cached_lstat(p, &fs) < 0) ||
+                       (link_src == NULL && cached_stat(p, &fs) < 0)) {
                        if (Lst_Find(missingFiles, p, string_match) == NULL)
                                Lst_AtEnd(missingFiles, bmake_strdup(p));



Home | Main Index | Thread Index | Old Index