diff options
| author | Richard M. Stallman | 1999-05-19 01:30:15 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1999-05-19 01:30:15 +0000 |
| commit | b97771fc17f53e7b3e0e145fda14730abc9b1e4e (patch) | |
| tree | fa05c342d5c19578fd5040e10902008d80ca447a /src | |
| parent | fc303b0a677aa4dcfed1e239b1cbca467ce0866c (diff) | |
| download | emacs-b97771fc17f53e7b3e0e145fda14730abc9b1e4e.tar.gz emacs-b97771fc17f53e7b3e0e145fda14730abc9b1e4e.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/filelock.c | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/src/filelock.c b/src/filelock.c index d441d235770..cbdf8468da5 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | /* Copyright (C) 1985, 86, 87, 93, 94, 96 Free Software Foundation, Inc. | 1 | /* Lock files for editing. |
| 2 | Copyright (C) 1985, 86, 87, 93, 94, 96, 98, 1999 Free Software Foundation, Inc. | ||
| 2 | 3 | ||
| 3 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 4 | 5 | ||
| @@ -104,6 +105,7 @@ extern int errno; | |||
| 104 | /* Return the time of the last system boot. */ | 105 | /* Return the time of the last system boot. */ |
| 105 | 106 | ||
| 106 | static time_t boot_time; | 107 | static time_t boot_time; |
| 108 | static int boot_time_initialized; | ||
| 107 | 109 | ||
| 108 | extern Lisp_Object Vshell_file_name; | 110 | extern Lisp_Object Vshell_file_name; |
| 109 | 111 | ||
| @@ -115,8 +117,9 @@ get_boot_time () | |||
| 115 | EMACS_TIME time_before, after; | 117 | EMACS_TIME time_before, after; |
| 116 | int counter; | 118 | int counter; |
| 117 | 119 | ||
| 118 | if (boot_time) | 120 | if (boot_time_initialized) |
| 119 | return boot_time; | 121 | return boot_time; |
| 122 | boot_time_initialized = 1; | ||
| 120 | 123 | ||
| 121 | EMACS_GET_TIME (time_before); | 124 | EMACS_GET_TIME (time_before); |
| 122 | 125 | ||
| @@ -166,11 +169,27 @@ get_boot_time () | |||
| 166 | #endif /* defined (CTL_KERN) && defined (KERN_BOOTTIME) */ | 169 | #endif /* defined (CTL_KERN) && defined (KERN_BOOTTIME) */ |
| 167 | 170 | ||
| 168 | #if defined (BOOT_TIME) && ! defined (NO_WTMP_FILE) | 171 | #if defined (BOOT_TIME) && ! defined (NO_WTMP_FILE) |
| 172 | #ifndef CANNOT_DUMP | ||
| 173 | /* The utmp routines maintain static state. | ||
| 174 | Don't touch that state unless we are initialized, | ||
| 175 | since it might not survive dumping. */ | ||
| 176 | if (! initialized) | ||
| 177 | return boot_time; | ||
| 178 | #endif /* not CANNOT_DUMP */ | ||
| 179 | |||
| 180 | /* Try to get boot time from utmp before wtmp, | ||
| 181 | since utmp is typically much smaller than wtmp. | ||
| 182 | Passing a null pointer causes get_boot_time_1 | ||
| 183 | to inspect the default file, namely utmp. */ | ||
| 184 | get_boot_time_1 ((char *) 0, 0); | ||
| 185 | if (boot_time) | ||
| 186 | return boot_time; | ||
| 187 | |||
| 169 | /* Try to get boot time from the current wtmp file. */ | 188 | /* Try to get boot time from the current wtmp file. */ |
| 170 | get_boot_time_1 (WTMP_FILE); | 189 | get_boot_time_1 (WTMP_FILE, 1); |
| 171 | 190 | ||
| 172 | /* If we did not find a boot time in wtmp, look at wtmp, and so on. */ | 191 | /* If we did not find a boot time in wtmp, look at wtmp, and so on. */ |
| 173 | for (counter = 0; counter < 20 && boot_time == 1; counter++) | 192 | for (counter = 0; counter < 20 && ! boot_time; counter++) |
| 174 | { | 193 | { |
| 175 | char cmd_string[100]; | 194 | char cmd_string[100]; |
| 176 | Lisp_Object tempname, filename; | 195 | Lisp_Object tempname, filename; |
| @@ -206,7 +225,7 @@ get_boot_time () | |||
| 206 | 225 | ||
| 207 | if (! NILP (filename)) | 226 | if (! NILP (filename)) |
| 208 | { | 227 | { |
| 209 | get_boot_time_1 (XSTRING (filename)->data); | 228 | get_boot_time_1 (XSTRING (filename)->data, 1); |
| 210 | if (delete_flag) | 229 | if (delete_flag) |
| 211 | unlink (XSTRING (filename)->data); | 230 | unlink (XSTRING (filename)->data); |
| 212 | } | 231 | } |
| @@ -221,24 +240,36 @@ get_boot_time () | |||
| 221 | #ifdef BOOT_TIME | 240 | #ifdef BOOT_TIME |
| 222 | /* Try to get the boot time from wtmp file FILENAME. | 241 | /* Try to get the boot time from wtmp file FILENAME. |
| 223 | This succeeds if that file contains a reboot record. | 242 | This succeeds if that file contains a reboot record. |
| 224 | Success is indicated by setting BOOT_TIME. */ | ||
| 225 | 243 | ||
| 226 | get_boot_time_1 (filename) | 244 | If FILENAME is zero, use the same file as before; |
| 245 | if no FILENAME has ever been specified, this is the utmp file. | ||
| 246 | Use the newest reboot record if NEWEST is nonzero, | ||
| 247 | the first reboot record otherwise. | ||
| 248 | Ignore all reboot records on or before BOOT_TIME. | ||
| 249 | Success is indicated by setting BOOT_TIME to a larger value. */ | ||
| 250 | |||
| 251 | get_boot_time_1 (filename, newest) | ||
| 227 | char *filename; | 252 | char *filename; |
| 253 | int newest; | ||
| 228 | { | 254 | { |
| 229 | struct utmp ut, *utp; | 255 | struct utmp ut, *utp; |
| 230 | int desc; | 256 | int desc; |
| 231 | 257 | ||
| 232 | /* On some versions of IRIX, opening a nonexistent file name | 258 | if (filename) |
| 233 | is likely to crash in the utmp routines. */ | 259 | { |
| 234 | desc = open (filename, O_RDONLY); | 260 | /* On some versions of IRIX, opening a nonexistent file name |
| 235 | if (desc < 0) | 261 | is likely to crash in the utmp routines. */ |
| 236 | return; | 262 | desc = open (filename, O_RDONLY); |
| 263 | if (desc < 0) | ||
| 264 | return; | ||
| 265 | |||
| 266 | close (desc); | ||
| 267 | |||
| 268 | utmpname (filename); | ||
| 269 | } | ||
| 237 | 270 | ||
| 238 | close (desc); | ||
| 239 | |||
| 240 | utmpname (filename); | ||
| 241 | setutent (); | 271 | setutent (); |
| 272 | |||
| 242 | while (1) | 273 | while (1) |
| 243 | { | 274 | { |
| 244 | /* Find the next reboot record. */ | 275 | /* Find the next reboot record. */ |
| @@ -248,7 +279,11 @@ get_boot_time_1 (filename) | |||
| 248 | break; | 279 | break; |
| 249 | /* Compare reboot times and use the newest one. */ | 280 | /* Compare reboot times and use the newest one. */ |
| 250 | if (utp->ut_time > boot_time) | 281 | if (utp->ut_time > boot_time) |
| 251 | boot_time = utp->ut_time; | 282 | { |
| 283 | boot_time = utp->ut_time; | ||
| 284 | if (! newest) | ||
| 285 | break; | ||
| 286 | } | ||
| 252 | /* Advance on element in the file | 287 | /* Advance on element in the file |
| 253 | so that getutid won't repeat the same one. */ | 288 | so that getutid won't repeat the same one. */ |
| 254 | utp = getutent (); | 289 | utp = getutent (); |
| @@ -684,6 +719,7 @@ void | |||
| 684 | init_filelock () | 719 | init_filelock () |
| 685 | { | 720 | { |
| 686 | boot_time = 0; | 721 | boot_time = 0; |
| 722 | boot_time_initialized = 0; | ||
| 687 | } | 723 | } |
| 688 | 724 | ||
| 689 | void | 725 | void |