changeset 24744:0e99bc70cf07

Fix performance bug on hosts with large /var/adm/wtmp files with no boot records. (boot_time_initialized): New var. (init_filelock): Initialize it. (get_boot_time): Use it, instead of nonzero boot_time, to test whether boot_time is initialized. Don't invoke utmp routines when dumping. (get_boot_time): First, try to get the boot time from the current utmp file, as this can be much faster. Don't try to get the boot time from utmp and/or wtmp more than once. (get_boot_time_1): When passed null pointer, don't invoke utmpname. New arg LATEST. All uses changed.
author Richard M. Stallman <rms@gnu.org>
date Wed, 19 May 1999 01:30:15 +0000
parents 003fb3ca1618
children aa8417416f03
files src/filelock.c
diffstat 1 files changed, 52 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/filelock.c	Tue May 18 06:15:43 1999 +0000
+++ b/src/filelock.c	Wed May 19 01:30:15 1999 +0000
@@ -1,4 +1,5 @@
-/* Copyright (C) 1985, 86, 87, 93, 94, 96 Free Software Foundation, Inc.
+/* Lock files for editing.
+   Copyright (C) 1985, 86, 87, 93, 94, 96, 98, 1999 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -104,6 +105,7 @@
 /* Return the time of the last system boot.  */
 
 static time_t boot_time;
+static int boot_time_initialized;
 
 extern Lisp_Object Vshell_file_name;
 
@@ -115,8 +117,9 @@
   EMACS_TIME time_before, after;
   int counter;
 
-  if (boot_time)
+  if (boot_time_initialized)
     return boot_time;
+  boot_time_initialized = 1;
 
   EMACS_GET_TIME (time_before);
 
@@ -166,11 +169,27 @@
 #endif /* defined (CTL_KERN) && defined (KERN_BOOTTIME) */
 
 #if defined (BOOT_TIME) && ! defined (NO_WTMP_FILE)
+#ifndef CANNOT_DUMP
+  /* The utmp routines maintain static state.
+     Don't touch that state unless we are initialized,
+     since it might not survive dumping.  */
+  if (! initialized)
+    return boot_time;
+#endif /* not CANNOT_DUMP */
+
+  /* Try to get boot time from utmp before wtmp,
+     since utmp is typically much smaller than wtmp.
+     Passing a null pointer causes get_boot_time_1
+     to inspect the default file, namely utmp.  */
+  get_boot_time_1 ((char *) 0, 0);
+  if (boot_time)
+    return boot_time;
+
   /* Try to get boot time from the current wtmp file.  */
-  get_boot_time_1 (WTMP_FILE);
+  get_boot_time_1 (WTMP_FILE, 1);
 
   /* If we did not find a boot time in wtmp, look at wtmp, and so on.  */
-  for (counter = 0; counter < 20 && boot_time == 1; counter++)
+  for (counter = 0; counter < 20 && ! boot_time; counter++)
     {
       char cmd_string[100];
       Lisp_Object tempname, filename;
@@ -206,7 +225,7 @@
 
       if (! NILP (filename))
 	{
-	  get_boot_time_1 (XSTRING (filename)->data);
+	  get_boot_time_1 (XSTRING (filename)->data, 1);
 	  if (delete_flag)
 	    unlink (XSTRING (filename)->data);
 	}
@@ -221,24 +240,36 @@
 #ifdef BOOT_TIME
 /* Try to get the boot time from wtmp file FILENAME.
    This succeeds if that file contains a reboot record.
-   Success is indicated by setting BOOT_TIME.  */
 
-get_boot_time_1 (filename)
+   If FILENAME is zero, use the same file as before;
+   if no FILENAME has ever been specified, this is the utmp file.
+   Use the newest reboot record if NEWEST is nonzero,
+   the first reboot record otherwise.
+   Ignore all reboot records on or before BOOT_TIME.
+   Success is indicated by setting BOOT_TIME to a larger value.  */
+
+get_boot_time_1 (filename, newest)
      char *filename;
+     int newest;
 {
   struct utmp ut, *utp;
   int desc;
 
-  /* On some versions of IRIX, opening a nonexistent file name
-     is likely to crash in the utmp routines.  */
-  desc = open (filename, O_RDONLY);
-  if (desc < 0)
-    return;
+  if (filename)
+    {
+      /* On some versions of IRIX, opening a nonexistent file name
+	 is likely to crash in the utmp routines.  */
+      desc = open (filename, O_RDONLY);
+      if (desc < 0)
+	return;
 
-  close (desc);
-      
-  utmpname (filename);
+      close (desc);
+
+      utmpname (filename);
+    }
+
   setutent ();
+
   while (1)
     {
       /* Find the next reboot record.  */
@@ -248,7 +279,11 @@
 	break;
       /* Compare reboot times and use the newest one.  */
       if (utp->ut_time > boot_time)
-	boot_time = utp->ut_time;
+	{
+	  boot_time = utp->ut_time;
+	  if (! newest)
+	    break;
+	}
       /* Advance on element in the file
 	 so that getutid won't repeat the same one.  */
       utp = getutent ();
@@ -684,6 +719,7 @@
 init_filelock ()
 {
   boot_time = 0;
+  boot_time_initialized = 0;
 }
 
 void