|
|
405007 |
There seems to be a performance regression in 5.8+ versions of RCS.
|
|
|
405007 |
|
|
|
405007 |
RCS consults env var ‘RCS_MEM_LIMIT’ to determine whether or not to fall
|
|
|
405007 |
back to (slow) stdio mode (which uses temporary files) from the default
|
|
|
405007 |
in-memory (mmap et al) mode. The default value is "256" (kilobytes), which
|
|
|
405007 |
is probably too low these days on most workstations.
|
|
|
405007 |
|
|
|
405007 |
RHBZ#1036527
|
|
|
405007 |
Upstream: https://savannah.gnu.org/bugs/index.php?40200
|
|
|
405007 |
|
|
|
405007 |
diff -U0 rcs-5.9.0/ChangeLog.coperf rcs-5.9.0/ChangeLog
|
|
|
405007 |
--- rcs-5.9.0/ChangeLog.coperf 2013-12-03 13:33:59.544075057 +0100
|
|
|
405007 |
+++ rcs-5.9.0/ChangeLog 2013-12-03 13:38:42.814534824 +0100
|
|
|
405007 |
@@ -0,0 +1,7 @@
|
|
|
405007 |
+2013-10-20 Thien-Thi Nguyen <ttn@gnu.org>
|
|
|
405007 |
+
|
|
|
405007 |
+ Relax RCS_MEM_LIMIT default; fall back if unspecified.
|
|
|
405007 |
+
|
|
|
405007 |
+ * doc/rcs.texi (Environment): Update ‘RCS_MEM_LIMIT’ description;
|
|
|
405007 |
+ add a willful ignorance hint and speculation on its removal.
|
|
|
405007 |
+
|
|
|
405007 |
diff -up rcs-5.9.0/doc/rcs.texi.coperf rcs-5.9.0/doc/rcs.texi
|
|
|
405007 |
--- rcs-5.9.0/doc/rcs.texi.coperf 2013-05-06 10:29:41.000000000 +0200
|
|
|
405007 |
+++ rcs-5.9.0/doc/rcs.texi 2013-12-03 13:33:59.545075058 +0100
|
|
|
405007 |
@@ -1002,12 +1002,20 @@ the rest of the command-line. The effec
|
|
|
405007 |
@cindex memory limit
|
|
|
405007 |
Normally, for speed, commands either memory map or copy into memory
|
|
|
405007 |
the @repo{} if its size is less than the @dfn{memory limit}, currently
|
|
|
405007 |
-defaulting to 256 kilobytes. Otherwise the commands fall back to using
|
|
|
405007 |
+defaulting to ``unlimited''.
|
|
|
405007 |
+Otherwise (or if the initially-tried speedy ways fail),
|
|
|
405007 |
+the commands fall back to using
|
|
|
405007 |
standard i/o routines.
|
|
|
405007 |
|
|
|
405007 |
You can adjust the memory limit by setting the @samp{RCS_MEM_LIMIT}
|
|
|
405007 |
environment variable to a numeric value (measured in kilobytes).
|
|
|
405007 |
An empty value is silently ignored.
|
|
|
405007 |
+
|
|
|
405007 |
+As a side effect, specifying the memory limit inhibits
|
|
|
405007 |
+fall-back to slower routines.
|
|
|
405007 |
+(This env var is mostly intended for testing RCS;
|
|
|
405007 |
+normally, you can leave it unset. Probably it will be
|
|
|
405007 |
+removed in a future release.)
|
|
|
405007 |
@end defvr
|
|
|
405007 |
|
|
|
405007 |
@defvr {Environment Variable} TMPDIR
|
|
|
405007 |
diff -up rcs-5.9.0/src/base.h.coperf rcs-5.9.0/src/base.h
|
|
|
405007 |
--- rcs-5.9.0/src/base.h.coperf 2013-05-03 10:25:05.000000000 +0200
|
|
|
405007 |
+++ rcs-5.9.0/src/base.h 2013-12-03 13:33:59.548075060 +0100
|
|
|
405007 |
@@ -522,6 +522,7 @@ struct behavior
|
|
|
405007 |
(if mmap(2)), or operate on a copy of it in core (if no mmap(2)).
|
|
|
405007 |
Otherwise, use standard i/o routines as the fallback.
|
|
|
405007 |
Set by env var ‘RCS_MEM_LIMIT’.
|
|
|
405007 |
+ See also ‘MEMORY_UNLIMITED’.
|
|
|
405007 |
-- gnurcs_init */
|
|
|
405007 |
|
|
|
405007 |
struct sff *sff;
|
|
|
405007 |
@@ -861,6 +862,8 @@ int getRCSINIT (int argc, char **argv, c
|
|
|
405007 |
|
|
|
405007 |
/* Idioms. */
|
|
|
405007 |
|
|
|
405007 |
+#define MEMORY_UNLIMITED -1
|
|
|
405007 |
+
|
|
|
405007 |
#define BOG_DIFF (TYAG_TEMPUNLINK | TYAG_DIFF)
|
|
|
405007 |
#define BOG_ZONK (TYAG_DIRTMPUNLINK | TYAG_TEMPUNLINK)
|
|
|
405007 |
#define BOG_FULL (TYAG_ORCSERROR | BOG_ZONK)
|
|
|
405007 |
diff -up rcs-5.9.0/src/b-fro.c.coperf rcs-5.9.0/src/b-fro.c
|
|
|
405007 |
--- rcs-5.9.0/src/b-fro.c.coperf 2013-04-30 17:52:07.000000000 +0200
|
|
|
405007 |
+++ rcs-5.9.0/src/b-fro.c 2013-12-03 13:37:07.237305286 +0100
|
|
|
405007 |
@@ -61,6 +61,7 @@ fro_open (char const *name, char const *
|
|
|
405007 |
| (strchr (type, 'b') ? OPEN_O_BINARY : 0)
|
|
|
405007 |
#endif
|
|
|
405007 |
));
|
|
|
405007 |
+ bool unlimited = MEMORY_UNLIMITED == BE (mem_limit);
|
|
|
405007 |
|
|
|
405007 |
if (PROB (fd))
|
|
|
405007 |
return NULL;
|
|
|
405007 |
@@ -81,12 +82,25 @@ fro_open (char const *name, char const *
|
|
|
405007 |
f->end = s;
|
|
|
405007 |
|
|
|
405007 |
/* Determine the read method. */
|
|
|
405007 |
- f->rm = status->st_size < 1024 * BE (mem_limit)
|
|
|
405007 |
+ f->rm = (unlimited
|
|
|
405007 |
+ || status->st_size < 1024 * BE (mem_limit))
|
|
|
405007 |
? (MMAP_SIGNAL && status->st_size
|
|
|
405007 |
? RM_MMAP
|
|
|
405007 |
: RM_MEM)
|
|
|
405007 |
: RM_STDIO;
|
|
|
405007 |
|
|
|
405007 |
+#define STUBBORNLY_RETRY_MAYBE(METHOD) do \
|
|
|
405007 |
+ { \
|
|
|
405007 |
+ if (unlimited) \
|
|
|
405007 |
+ { \
|
|
|
405007 |
+ f->rm = METHOD; \
|
|
|
405007 |
+ goto retry; \
|
|
|
405007 |
+ } \
|
|
|
405007 |
+ fatal_sys (name); \
|
|
|
405007 |
+ } \
|
|
|
405007 |
+ while (0)
|
|
|
405007 |
+
|
|
|
405007 |
+ retry:
|
|
|
405007 |
switch (f->rm)
|
|
|
405007 |
{
|
|
|
405007 |
case RM_MMAP:
|
|
|
405007 |
@@ -98,7 +112,7 @@ fro_open (char const *name, char const *
|
|
|
405007 |
ISR_DO (CATCHMMAPINTS);
|
|
|
405007 |
f->base = mmap (NULL, s, PROT_READ, MAP_SHARED, fd, 0);
|
|
|
405007 |
if (f->base == MAP_FAILED)
|
|
|
405007 |
- fatal_sys (name);
|
|
|
405007 |
+ STUBBORNLY_RETRY_MAYBE (RM_MEM);
|
|
|
405007 |
/* On many hosts, the superuser can mmap an NFS file
|
|
|
405007 |
it can't read. So access the first page now, and
|
|
|
405007 |
print a nice message if a bus error occurs. */
|
|
|
405007 |
@@ -131,7 +145,7 @@ fro_open (char const *name, char const *
|
|
|
405007 |
do
|
|
|
405007 |
{
|
|
|
405007 |
if (PROB (r = read (fd, bufptr, bufsiz)))
|
|
|
405007 |
- fatal_sys (name);
|
|
|
405007 |
+ STUBBORNLY_RETRY_MAYBE (RM_STDIO);
|
|
|
405007 |
|
|
|
405007 |
if (!r)
|
|
|
405007 |
{
|
|
|
405007 |
@@ -147,7 +161,7 @@ fro_open (char const *name, char const *
|
|
|
405007 |
}
|
|
|
405007 |
while (bufsiz);
|
|
|
405007 |
if (PROB (lseek (fd, 0, SEEK_SET)))
|
|
|
405007 |
- fatal_sys (name);
|
|
|
405007 |
+ STUBBORNLY_RETRY_MAYBE (RM_STDIO);
|
|
|
405007 |
}
|
|
|
405007 |
f->ptr = f->base;
|
|
|
405007 |
f->lim = f->base + s;
|
|
|
405007 |
@@ -162,6 +176,8 @@ fro_open (char const *name, char const *
|
|
|
405007 |
|
|
|
405007 |
f->fd = fd;
|
|
|
405007 |
return f;
|
|
|
405007 |
+
|
|
|
405007 |
+#undef STUBBORNLY_RETRY_MAYBE
|
|
|
405007 |
}
|
|
|
405007 |
|
|
|
405007 |
void
|
|
|
405007 |
diff -U0 rcs-5.9.0/src/ChangeLog.coperf rcs-5.9.0/src/ChangeLog
|
|
|
405007 |
--- rcs-5.9.0/src/ChangeLog.coperf 2013-12-03 13:33:59.547075059 +0100
|
|
|
405007 |
+++ rcs-5.9.0/src/ChangeLog 2013-12-03 13:38:52.305555851 +0100
|
|
|
405007 |
@@ -0,0 +1,12 @@
|
|
|
405007 |
+2013-10-20 Thien-Thi Nguyen <ttn@gnu.org>
|
|
|
405007 |
+
|
|
|
405007 |
+ Relax RCS_MEM_LIMIT default; fall back if unspecified.
|
|
|
405007 |
+
|
|
|
405007 |
+ * base.h (MEMORY_UNLIMITED): New #define.
|
|
|
405007 |
+ * rcsutil.c (gnurcs_init): If unspecified,
|
|
|
405007 |
+ default ‘BE (mem_limit)’ to ‘MEMORY_UNLIMITED’.
|
|
|
405007 |
+ * b-fro.c (fro_open): Notice ‘MEMORY_UNLIMITED’ mem limit;
|
|
|
405007 |
+ in that case, don't check file size, and on ‘RM_MMAP’ or
|
|
|
405007 |
+ ‘RM_MEM’ failure, retry w/ the "next" method: ‘RM_MEM’ or
|
|
|
405007 |
+ ‘RM_STDIO’, respectively.
|
|
|
405007 |
+
|
|
|
405007 |
diff -up rcs-5.9.0/src/rcsutil.c.coperf rcs-5.9.0/src/rcsutil.c
|
|
|
405007 |
--- rcs-5.9.0/src/rcsutil.c.coperf 2013-05-03 13:52:56.000000000 +0200
|
|
|
405007 |
+++ rcs-5.9.0/src/rcsutil.c 2013-12-03 13:33:59.548075060 +0100
|
|
|
405007 |
@@ -103,7 +103,7 @@ gnurcs_init (struct program const *progr
|
|
|
405007 |
? 0
|
|
|
405007 |
: lim)
|
|
|
405007 |
/* Default value. */
|
|
|
405007 |
- : 256;
|
|
|
405007 |
+ : MEMORY_UNLIMITED;
|
|
|
405007 |
}
|
|
|
405007 |
}
|
|
|
405007 |
|
|
|
405007 |
diff -up rcs-5.9.0/THANKS.coperf rcs-5.9.0/THANKS
|
|
|
405007 |
--- rcs-5.9.0/THANKS.coperf 2013-12-03 13:33:59.544075057 +0100
|
|
|
405007 |
+++ rcs-5.9.0/THANKS 2013-12-03 13:34:57.565111763 +0100
|
|
|
405007 |
@@ -47,4 +47,5 @@ and reporting bugs (sometimes with fixes
|
|
|
405007 |
Jiri Moskovcak
|
|
|
405007 |
James Olin Oden
|
|
|
405007 |
Derek McEachern
|
|
|
405007 |
+ Andrew J. Schorr
|
|
|
405007 |
(and others who prefer anonymity)
|