[tlbuild] kpathsea/line.c using getc_unlocked

Karl Berry karl at freefriends.org
Fri Oct 17 19:17:44 CEST 2014


Hello TL builders,

Adam Maxwell discovered that using getc_unlocked() is much faster than
getc() on Macs.  Of course we want to keep kpathsea thread-safe for the
sake of, e.g., the MetaPost library, but it can be a noticeable speedup
to lock the stream with flockfile, use getc_unlocked, and then
funlockfile.  Therefore we've committed a change to kpathsea/line.c to
do that (r35390).

The question for this group, and whoever may read this in the future, is
whether TL is ever built on systems that lack getc_unlocked() and
related.  At the moment the functions are used unconditionally, but it
should be no problem to add configure tests if they are needed.  Since
the functions were only added to POSIX a decade ago or so, it won't
surprise me if something out there (that we care about) lacks them.  It
did build on Solaris 5.10 with Sun cc, I was pleasantly surprised to
discovered.

We do not attempt to use the functions on Windows; should be no change
there.  There is no speedup on my CentOS 5 system, but no harm either.

Let us know if questions/problems.

Karl

--- line.c	(revision 35389)
+++ line.c	(working copy)
@@ -18,13 +18,29 @@
 
 #include <kpathsea/config.h>
 #include <kpathsea/line.h>
+
 #ifdef WIN32
 #undef getc
 #undef ungetc
 #define getc   win32_getc
 #define ungetc win32_ungetc
-#endif
+#define FLOCKFILE(x)
+#define FUNLOCKFILE(x)
 
+#else /* not WIN32 */
+/* By POSIX, getc() has to be thread-safe, which means (un)locking on
+   every character read.  It is much faster to lock the stream (once),
+   use getc_unlocked to read, and then unlock the stream.  We need to be
+   thread-safe especially for the sake of MPlib.
+   
+   Perhaps we will be lucky enough to be able to do this
+   unconditionally, without checking in configure.  We'll see.  */
+#undef getc
+#define getc           getc_unlocked
+#define FLOCKFILE(x)   flockfile(x)
+#define FUNLOCKFILE(x) funlockfile(x)
+#endif /* not WIN32 */
+
 /* Allocate in increments of this size.  */
 #define BLOCK_SIZE 75
 
@@ -35,6 +51,8 @@
   unsigned limit = BLOCK_SIZE;
   unsigned loc = 0;
   char *line = xmalloc (limit);
+  
+  FLOCKFILE (f);
 
   while ((c = getc (f)) != EOF && c != '\n' && c != '\r') {
     line[loc] = c;
@@ -67,6 +85,8 @@
       }
     }
   }
+  
+  FUNLOCKFILE (f);
 
   return line;
 }


More information about the tlbuild mailing list