bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] use unlocked io in getdelim


From: Paolo Bonzini
Subject: Re: [PATCH] use unlocked io in getdelim
Date: Wed, 27 Aug 2008 14:49:46 +0200
User-agent: Thunderbird 2.0.0.16 (Macintosh/20080707)

Eric Blake wrote:
> According to Paolo Bonzini on 8/27/2008 5:48 AM:
>> Under MacOS, getc is not a macro, only getc_unlocked is.  This patch
>> does two things: 1) it makes getdelim use getc_unlocked if it can wrap
>> the calls with flockfile/funlockfile; 2) it makes getdelim omit the
>> locking altogether if unlocked-io is in effect.  It speeds up sed by
>> almost 2x in very simple scripts with very little regular expression
>> matching (such as '/^something/!d').
> 
>> Ok?
> 
> Sounds interesting.  How does this compare with the current approach used
> by getndelim2, which uses freadptr to avoid getc?

I guess there's also this other possibility.

 lib/getdelim.c   |  107 ++---------------------------------------------
 m4/getdelim.m4   |   10 -----
 modules/getdelim |    4 --
 3 files changed, 6 insertions(+), 115 deletions(-)

The number of deletions makes it yummy...

Paolo
diff --git a/lib/getdelim.c b/lib/getdelim.c
index 2e127fc..f935d25 100644
--- a/lib/getdelim.c
+++ b/lib/getdelim.c
@@ -1,6 +1,5 @@
-/* getdelim.c --- Implementation of replacement getdelim function.
-   Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007, 2008 
Free
-   Software Foundation, Inc.
+/* getdelim.c --- Delegation of getdelim to getndelim2.
+   Copyright (C) 2008 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -17,30 +16,9 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.  */
 
-/* Ported from glibc by Simon Josefsson. */
-
 #include <config.h>
-
 #include <stdio.h>
-
-#include <limits.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-#ifndef SSIZE_MAX
-# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
-#endif
-#if !HAVE_FLOCKFILE
-# undef flockfile
-# define flockfile(x) ((void) 0)
-#endif
-#if !HAVE_FUNLOCKFILE
-# undef funlockfile
-# define funlockfile(x) ((void) 0)
-#endif
+#include "getndelim2.h"
 
 /* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
    NUL-terminate it).  *LINEPTR is a pointer returned from malloc (or
@@ -49,82 +27,7 @@
    the null terminator), or -1 on error or EOF.  */
 
 ssize_t
-getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
+getdelim (char **lineptr, size_t *n, int delim, FILE *fp)
 {
-  ssize_t result;
-  size_t cur_len = 0;
-
-  if (lineptr == NULL || n == NULL || fp == NULL)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-  flockfile (fp);
-
-  if (*lineptr == NULL || *n == 0)
-    {
-      char *new_lineptr;
-      *n = 120;
-      new_lineptr = (char *) realloc (*lineptr, *n);
-      if (new_lineptr == NULL)
-       {
-         result = -1;
-         goto unlock_return;
-       }
-      *lineptr = new_lineptr;
-    }
-
-  for (;;)
-    {
-      int i;
-
-      i = getc (fp);
-      if (i == EOF)
-       {
-         result = -1;
-         break;
-       }
-
-      /* Make enough space for len+1 (for final NUL) bytes.  */
-      if (cur_len + 1 >= *n)
-       {
-         size_t needed_max =
-           SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
-         size_t needed = 2 * *n + 1;   /* Be generous. */
-         char *new_lineptr;
-
-         if (needed_max < needed)
-           needed = needed_max;
-         if (cur_len + 1 >= needed)
-           {
-             result = -1;
-             errno = EOVERFLOW;
-             goto unlock_return;
-           }
-
-         new_lineptr = (char *) realloc (*lineptr, needed);
-         if (new_lineptr == NULL)
-           {
-             result = -1;
-             goto unlock_return;
-           }
-
-         *lineptr = new_lineptr;
-         *n = needed;
-       }
-
-      (*lineptr)[cur_len] = i;
-      cur_len++;
-
-      if (i == delimiter)
-       break;
-    }
-  (*lineptr)[cur_len] = '\0';
-  result = cur_len ? cur_len : result;
-
- unlock_return:
-  funlockfile (fp); /* doesn't set errno */
-
-  return result;
+  return getndelim2 (lineptr, n, 0, GETNLINE_NO_LIMIT, delim, delim, fp);
 }
diff --git a/m4/getdelim.m4 b/m4/getdelim.m4
index 18b96be..3342488 100644
--- a/m4/getdelim.m4
+++ b/m4/getdelim.m4
@@ -18,17 +18,7 @@ AC_DEFUN([gl_FUNC_GETDELIM],
   AC_REPLACE_FUNCS([getdelim])
   AC_CHECK_DECLS_ONCE([getdelim])
 
-  if test $ac_cv_func_getdelim = no; then
-    gl_PREREQ_GETDELIM
-  fi
-
   if test $ac_cv_have_decl_getdelim = no; then
     HAVE_DECL_GETDELIM=0
   fi
 ])
-
-# Prerequisites of lib/getdelim.c.
-AC_DEFUN([gl_PREREQ_GETDELIM],
-[
-  AC_CHECK_FUNCS([flockfile funlockfile])
-])
diff --git a/modules/getdelim b/modules/getdelim
index 1bb24f5..1dbc914 100644
--- a/modules/getdelim
+++ b/modules/getdelim
@@ -6,10 +6,8 @@ lib/getdelim.c
 m4/getdelim.m4
 
 Depends-on:
-extensions
+getndelim2
 stdio
-realloc-posix
-EOVERFLOW
 
 configure.ac:
 gl_FUNC_GETDELIM

reply via email to

[Prev in Thread] Current Thread [Next in Thread]