This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Faster strspn/strcspn implementation.


On Thu, Dec 27, 2012 at 10:21:46PM +0100, OndÅej BÃlka wrote:
> __strspn4( s,a0,a1,a2,a3) - when needle consist at most 4 characters.
> __strspn_rng(s,from,to)   - when needle is consecutive interval.
> __strspn16(s,a)           - when needle consist at most 16 characters.
> __strspn_arf(s,a)         - anything else.
> 
> In header string/bits/string2.h I changed implementation to call
> __strspn4 for small needles.  Currently I can not persudate gcc to
> recognize intervals at compile time.
> 

For backward compatibility I defined compatibility function and made it
weak alias to new function. Could be gcc taugth to unify identical
static functions?

This does not compile for rtld yet as I would need update makefile.


diff --git a/string/bits/string2.h b/string/bits/string2.h
index 2e560de..de82b77 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -925,8 +925,26 @@ __stpcpy_small (char *__dest,
 		  ? strcmp (s1, s2) : strncmp (s1, s2, n)))
 #endif
 
+#ifdef NO_STRSPN4_WEAK_ALIAS
+/* Redefition without weak alias causes error, so we need to disable
this.*/
 extern size_t __strspn4  (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3);
 extern size_t __strcspn4 (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3);
+#else
+extern size_t __strspn4  (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3)  __attribute__ ((weak, alias ("__strspn4_compat")));
+extern size_t __strcspn4 (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3)  __attribute__ ((weak, alias ("__strcspn4_compat")));
+
+static size_t __strspn4_compat  (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3) 
+{
+  char n[5];
+  n[0] = a0; n[1] = a1; n[2] = a2; n[3] = a3; n[4] = 0;
+  return strspn(a,n);
+}
+static size_t __strcspn4_compat (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3)  
+{
+  char n[5];
+  n[0] = a0; n[1] = a1; n[2] = a2; n[3] = a3; n[4] = 0;
+  return strcspn(a,n);
+}
+#endif
 
 
 /* Return the length of the initial segment of S which
diff --git a/string/strspn_internal.c b/string/strspn_internal.c
index 3962925..1cb4190 100644
--- a/string/strspn_internal.c
+++ b/string/strspn_internal.c
@@ -27,6 +27,7 @@
 #define SPN_ARY  SPN_CSPN(__strspn_ary ,__strcspn_ary)
 #define SPN_RNG  SPN_CSPN(__strspn_rng ,__strcspn_rng)
 
+#define NO_STRSPN4_WEAK_ALIAS
 #include <string.h>
 
 size_t SPN_ARY (unsigned char* s,unsigned char* n)
-- 
1.7.4.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]