Blame SOURCES/rcs-5.9-coperf.patch

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