Module Name:    src
Committed By:   rillig
Date:           Wed Sep  2 04:08:54 UTC 2020

Modified Files:
        src/usr.bin/make: dir.c dir.h make.h meta.c

Log Message:
make(1): reduce number of stat fields returned by cached_stat

Only st_mtime and st_mode are actually filled, the remaining fields had
been set to zero.  To prevent these from ever being accessed, a custom
struct make_stat replaces the previously used struct stat.

The fields in struct make_stat are intentionally named different from
the fields in struct stat because NetBSD and some other operating
systems define st_mtime as a macro, and that would not work in a field
declaration.


To generate a diff of this commit:
cvs rdiff -u -r1.132 -r1.133 src/usr.bin/make/dir.c
cvs rdiff -u -r1.22 -r1.23 src/usr.bin/make/dir.h
cvs rdiff -u -r1.135 -r1.136 src/usr.bin/make/make.h
cvs rdiff -u -r1.112 -r1.113 src/usr.bin/make/meta.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/dir.c
diff -u src/usr.bin/make/dir.c:1.132 src/usr.bin/make/dir.c:1.133
--- src/usr.bin/make/dir.c:1.132	Wed Sep  2 03:28:12 2020
+++ src/usr.bin/make/dir.c	Wed Sep  2 04:08:54 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: dir.c,v 1.132 2020/09/02 03:28:12 rillig Exp $	*/
+/*	$NetBSD: dir.c,v 1.133 2020/09/02 04:08:54 rillig 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.132 2020/09/02 03:28:12 rillig Exp $";
+static char rcsid[] = "$NetBSD: dir.c,v 1.133 2020/09/02 04:08:54 rillig 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.132 2020/09/02 03:28:12 rillig Exp $");
+__RCSID("$NetBSD: dir.c,v 1.133 2020/09/02 04:08:54 rillig Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -282,13 +282,13 @@ typedef enum {
     CST_UPDATE = 0x02		/* ignore existing cached entry */
 } CachedStatsFlags;
 
-/* Returns 0 and the result of stat(2) or lstat(2) in *st, or -1 on error.
- * Only st->st_mode and st->st_mtime are filled. */
+/* Returns 0 and the result of stat(2) or lstat(2) in *mst, or -1 on error. */
 static int
-cached_stats(Hash_Table *htp, const char *pathname, struct stat *st,
+cached_stats(Hash_Table *htp, const char *pathname, struct make_stat *mst,
 	     CachedStatsFlags flags)
 {
     Hash_Entry *entry;
+    struct stat sys_st;
     struct cache_st *cst;
     int rc;
 
@@ -300,22 +300,23 @@ cached_stats(Hash_Table *htp, const char
     if (entry && !(flags & CST_UPDATE)) {
 	cst = Hash_GetValue(entry);
 
-	memset(st, 0, sizeof(*st));
-	st->st_mode = cst->mode;
-	st->st_mtime = (flags & CST_LSTAT) ? cst->lmtime : cst->mtime;
-	if (st->st_mtime) {
+	mst->mst_mode = cst->mode;
+	mst->mst_mtime = (flags & CST_LSTAT) ? cst->lmtime : cst->mtime;
+	if (mst->mst_mtime) {
 	    DIR_DEBUG2("Using cached time %s for %s\n",
-		       Targ_FmtTime(st->st_mtime), pathname);
+		       Targ_FmtTime(mst->mst_mtime), pathname);
 	    return 0;
 	}
     }
 
-    rc = (flags & CST_LSTAT) ? lstat(pathname, st) : stat(pathname, st);
+    rc = (flags & CST_LSTAT)
+	 ? lstat(pathname, &sys_st)
+	 : stat(pathname, &sys_st);
     if (rc == -1)
 	return -1;
 
-    if (st->st_mtime == 0)
-	st->st_mtime = 1;	/* avoid confusion with missing file */
+    if (sys_st.st_mtime == 0)
+	sys_st.st_mtime = 1;	/* avoid confusion with missing file */
 
     if (entry == NULL)
 	entry = Hash_CreateEntry(htp, pathname, NULL);
@@ -325,25 +326,25 @@ cached_stats(Hash_Table *htp, const char
     }
     cst = Hash_GetValue(entry);
     if (flags & CST_LSTAT) {
-	cst->lmtime = st->st_mtime;
+	cst->lmtime = sys_st.st_mtime;
     } else {
-	cst->mtime = st->st_mtime;
+	cst->mtime = sys_st.st_mtime;
     }
-    cst->mode = st->st_mode;
+    cst->mode = sys_st.st_mode;
     DIR_DEBUG2("   Caching %s for %s\n",
-	       Targ_FmtTime(st->st_mtime), pathname);
+	       Targ_FmtTime(sys_st.st_mtime), pathname);
 
     return 0;
 }
 
 int
-cached_stat(const char *pathname, struct stat *st)
+cached_stat(const char *pathname, struct make_stat *st)
 {
     return cached_stats(&mtimes, pathname, st, 0);
 }
 
 int
-cached_lstat(const char *pathname, struct stat *st)
+cached_lstat(const char *pathname, struct make_stat *st)
 {
     return cached_stats(&lmtimes, pathname, st, CST_LSTAT);
 }
@@ -935,7 +936,7 @@ DirLookup(Path *p, const char *name MAKE
 static char *
 DirLookupSubdir(Path *p, const char *name)
 {
-    struct stat stb;		/* Buffer for stat, if necessary */
+    struct make_stat mst;
     char *file;			/* the current filename to check */
 
     if (p != dot) {
@@ -949,7 +950,7 @@ DirLookupSubdir(Path *p, const char *nam
 
     DIR_DEBUG1("checking %s ...\n", file);
 
-    if (cached_stat(file, &stb) == 0) {
+    if (cached_stat(file, &mst) == 0) {
 	nearmisses += 1;
 	return file;
     }
@@ -1069,7 +1070,7 @@ Dir_FindFile(const char *name, Lst path)
     const char *cp;		/* Terminal name of file */
     Boolean hasLastDot = FALSE;	/* true we should search dot last */
     Boolean hasSlash;		/* true if 'name' contains a / */
-    struct stat stb;		/* Buffer for stat, if necessary */
+    struct make_stat mst;	/* Buffer for stat, if necessary */
     const char *trailing_dot = ".";
 
     /*
@@ -1312,7 +1313,7 @@ Dir_FindFile(const char *name, Lst path)
     DIR_DEBUG1("   Looking for \"%s\" ...\n", name);
 
     bigmisses += 1;
-    if (cached_stat(name, &stb) == 0) {
+    if (cached_stat(name, &mst) == 0) {
 	return bmake_strdup(name);
     }
 
@@ -1346,7 +1347,7 @@ Boolean
 Dir_FindHereOrAbove(const char *here, const char *search_path,
 		    char *result, int result_len)
 {
-    struct stat st;
+    struct make_stat mst;
     char dirbase[MAXPATHLEN + 1], *dirbase_end;
     char try[MAXPATHLEN + 1], *try_end;
 
@@ -1359,12 +1360,12 @@ Dir_FindHereOrAbove(const char *here, co
 
 	/* try and stat(2) it ... */
 	snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
-	if (cached_stat(try, &st) != -1) {
+	if (cached_stat(try, &mst) != -1) {
 	    /*
 	     * success!  if we found a file, chop off
 	     * the filename so we return a directory.
 	     */
-	    if ((st.st_mode & S_IFMT) != S_IFDIR) {
+	    if ((mst.mst_mode & S_IFMT) != S_IFDIR) {
 		try_end = try + strlen(try);
 		while (try_end > try && *try_end != '/')
 		    try_end--;
@@ -1417,7 +1418,7 @@ int
 Dir_MTime(GNode *gn, Boolean recheck)
 {
     char *fullName;		/* the full pathname of name */
-    struct stat stb;		/* buffer for finding the mod time */
+    struct make_stat mst;	/* buffer for finding the mod time */
 
     if (gn->type & OP_ARCHV) {
 	return Arch_MTime(gn);
@@ -1468,13 +1469,13 @@ Dir_MTime(GNode *gn, Boolean recheck)
 	fullName = bmake_strdup(gn->name);
     }
 
-    if (cached_stats(&mtimes, fullName, &stb, recheck ? CST_UPDATE : 0) < 0) {
+    if (cached_stats(&mtimes, fullName, &mst, recheck ? CST_UPDATE : 0) < 0) {
 	if (gn->type & OP_MEMBER) {
 	    if (fullName != gn->path)
 		free(fullName);
 	    return Arch_MemMTime(gn);
 	} else {
-	    stb.st_mtime = 0;
+	    mst.mst_mtime = 0;
 	}
     }
 
@@ -1482,7 +1483,7 @@ Dir_MTime(GNode *gn, Boolean recheck)
 	gn->path = fullName;
     }
 
-    gn->mtime = stb.st_mtime;
+    gn->mtime = mst.mst_mtime;
     return gn->mtime;
 }
 

Index: src/usr.bin/make/dir.h
diff -u src/usr.bin/make/dir.h:1.22 src/usr.bin/make/dir.h:1.23
--- src/usr.bin/make/dir.h:1.22	Tue Sep  1 20:17:18 2020
+++ src/usr.bin/make/dir.h	Wed Sep  2 04:08:54 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: dir.h,v 1.22 2020/09/01 20:17:18 rillig Exp $	*/
+/*	$NetBSD: dir.h,v 1.23 2020/09/02 04:08:54 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -85,6 +85,11 @@ typedef struct {
     Hash_Table    files;    	/* Hash set of files in directory */
 } Path;
 
+struct make_stat {
+    time_t mst_mtime;
+    mode_t mst_mode;
+};
+
 void Dir_Init(void);
 void Dir_InitDir(const char *);
 void Dir_InitCur(const char *);
@@ -105,4 +110,7 @@ void Dir_PrintPath(Lst);
 void Dir_Destroy(void *);
 void *Dir_CopyDir(void *);
 
+int cached_lstat(const char *, struct make_stat *);
+int cached_stat(const char *, struct make_stat *);
+
 #endif /* MAKE_DIR_H */

Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.135 src/usr.bin/make/make.h:1.136
--- src/usr.bin/make/make.h:1.135	Wed Sep  2 03:28:12 2020
+++ src/usr.bin/make/make.h	Wed Sep  2 04:08:54 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: make.h,v 1.135 2020/09/02 03:28:12 rillig Exp $	*/
+/*	$NetBSD: make.h,v 1.136 2020/09/02 04:08:54 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -537,8 +537,6 @@ void Main_ExportMAKEFLAGS(Boolean);
 Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
 int mkTempFile(const char *, char **);
 int str2Lst_Append(Lst, char *, const char *);
-int cached_lstat(const char *, struct stat *);
-int cached_stat(const char *, struct stat *);
 void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
 
 #ifdef __GNUC__

Index: src/usr.bin/make/meta.c
diff -u src/usr.bin/make/meta.c:1.112 src/usr.bin/make/meta.c:1.113
--- src/usr.bin/make/meta.c:1.112	Sun Aug 30 11:15:05 2020
+++ src/usr.bin/make/meta.c	Wed Sep  2 04:08:54 2020
@@ -1,4 +1,4 @@
-/*      $NetBSD: meta.c,v 1.112 2020/08/30 11:15:05 rillig Exp $ */
+/*      $NetBSD: meta.c,v 1.113 2020/09/02 04:08:54 rillig Exp $ */
 
 /*
  * Implement 'meta' mode.
@@ -43,6 +43,7 @@
 #endif
 
 #include "make.h"
+#include "dir.h"
 #include "job.h"
 
 #ifdef USE_FILEMON
@@ -399,7 +400,7 @@ static Boolean
 meta_needed(GNode *gn, const char *dname, const char *tname,
 	     char *objdir, int verbose)
 {
-    struct stat fs;
+    struct make_stat mst;
 
     if (verbose)
 	verbose = DEBUG(META);
@@ -433,7 +434,7 @@ meta_needed(GNode *gn, const char *dname
     }
 
     /* The object directory may not exist. Check it.. */
-    if (cached_stat(dname, &fs) != 0) {
+    if (cached_stat(dname, &mst) != 0) {
 	if (verbose)
 	    fprintf(debug_file, "Skipping meta for %s: no .OBJDIR\n",
 		    gn->name);
@@ -1124,7 +1125,7 @@ meta_oodate(GNode *gn, Boolean oodate)
 	int pid;
 	int x;
 	LstNode ln;
-	struct stat fs;
+	struct make_stat mst;
 
 	if (!buf) {
 	    bufsz = 8 * BUFSIZ;
@@ -1389,8 +1390,8 @@ meta_oodate(GNode *gn, Boolean oodate)
 		    if ((strstr("tmp", p)))
 			break;
 
-		    if ((link_src != NULL && cached_lstat(p, &fs) < 0) ||
-			(link_src == NULL && cached_stat(p, &fs) < 0)) {
+		    if ((link_src != NULL && cached_lstat(p, &mst) < 0) ||
+			(link_src == NULL && cached_stat(p, &mst) < 0)) {
 			if (!meta_ignore(gn, p)) {
 			    if (Lst_Find(missingFiles, string_match, p) == NULL)
 				Lst_Append(missingFiles, bmake_strdup(p));
@@ -1453,7 +1454,7 @@ meta_oodate(GNode *gn, Boolean oodate)
 			    if (DEBUG(META))
 				fprintf(debug_file, "%s: %d: looking for: %s\n", fname, lineno, *sdp);
 #endif
-			    if (cached_stat(*sdp, &fs) == 0) {
+			    if (cached_stat(*sdp, &mst) == 0) {
 				found = 1;
 				p = *sdp;
 			    }
@@ -1463,12 +1464,12 @@ meta_oodate(GNode *gn, Boolean oodate)
 			    if (DEBUG(META))
 				fprintf(debug_file, "%s: %d: found: %s\n", fname, lineno, p);
 #endif
-			    if (!S_ISDIR(fs.st_mode) &&
-				fs.st_mtime > gn->mtime) {
+			    if (!S_ISDIR(mst.mst_mode) &&
+				mst.mst_mtime > gn->mtime) {
 				if (DEBUG(META))
 				    fprintf(debug_file, "%s: %d: file '%s' is newer than the target...\n", fname, lineno, p);
 				oodate = TRUE;
-			    } else if (S_ISDIR(fs.st_mode)) {
+			    } else if (S_ISDIR(mst.mst_mode)) {
 				/* Update the latest directory. */
 				cached_realpath(p, latestdir);
 			    }

Reply via email to