Re: svn commit: r1715876 - in /httpd/httpd/trunk: modules/cache/ modules/filters/ modules/generators/ modules/http/ modules/http2/ modules/loggers/ modules/mappers/ modules/metadata/ modules/proxy/ mo

2015-11-23 Thread Ruediger Pluem


On 11/23/2015 05:46 PM, yla...@apache.org wrote:
> Author: ylavic
> Date: Mon Nov 23 16:46:01 2015
> New Revision: 1715876
> 
> URL: http://svn.apache.org/viewvc?rev=1715876=rev
> Log:
> Use new ap_casecmpstr[n]() functions where appropriate (not exhaustive).
> 
> Modified:
> httpd/httpd/trunk/modules/cache/cache_util.c
> httpd/httpd/trunk/modules/filters/mod_deflate.c
> httpd/httpd/trunk/modules/filters/mod_include.c
> httpd/httpd/trunk/modules/filters/mod_proxy_html.c
> httpd/httpd/trunk/modules/generators/mod_autoindex.c
> httpd/httpd/trunk/modules/generators/mod_cgi.c
> httpd/httpd/trunk/modules/generators/mod_cgid.c
> httpd/httpd/trunk/modules/http/byterange_filter.c
> httpd/httpd/trunk/modules/http/http_filters.c
> httpd/httpd/trunk/modules/http2/h2_from_h1.c
> httpd/httpd/trunk/modules/loggers/mod_log_config.c
> httpd/httpd/trunk/modules/mappers/mod_rewrite.c
> httpd/httpd/trunk/modules/metadata/mod_cern_meta.c
> httpd/httpd/trunk/modules/metadata/mod_headers.c
> httpd/httpd/trunk/modules/proxy/ajp_header.c
> httpd/httpd/trunk/modules/proxy/mod_proxy.c
> httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c
> httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c
> httpd/httpd/trunk/modules/proxy/mod_proxy_fcgi.c
> httpd/httpd/trunk/modules/proxy/mod_proxy_fdpass.c
> httpd/httpd/trunk/modules/proxy/mod_proxy_ftp.c
> httpd/httpd/trunk/modules/proxy/mod_proxy_http.c
> httpd/httpd/trunk/modules/proxy/mod_proxy_scgi.c
> httpd/httpd/trunk/modules/proxy/mod_proxy_wstunnel.c
> httpd/httpd/trunk/modules/proxy/mod_serf.c
> httpd/httpd/trunk/modules/proxy/proxy_util.c
> httpd/httpd/trunk/modules/slotmem/mod_slotmem_shm.c
> httpd/httpd/trunk/modules/test/mod_policy.c
> httpd/httpd/trunk/server/mpm_unix.c
> httpd/httpd/trunk/server/protocol.c
> httpd/httpd/trunk/server/util.c
> httpd/httpd/trunk/server/util_expr_eval.c
> httpd/httpd/trunk/server/util_script.c
> 
> Modified: httpd/httpd/trunk/modules/cache/cache_util.c
> URL: 
> http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/cache_util.c?rev=1715876=1715875=1715876=diff
> ==
> --- httpd/httpd/trunk/modules/cache/cache_util.c (original)
> +++ httpd/httpd/trunk/modules/cache/cache_util.c Mon Nov 23 16:46:01 2015

> @@ -1066,59 +1045,46 @@ int ap_cache_control(request_rec *r, cac
>  cc->max_stale = 1;
>  cc->max_stale_value = -1;
>  }
> -break;
>  }
> -else if (!strncasecmp(token, "min-fresh", 9)) {
> +else if (!ap_casecmpstrn(token, "min-fresh", 9)) {
>  if (token[9] == '=') {
>  cc->min_fresh = 1;
>  cc->min_fresh_value = apr_atoi64(token + 10);
>  }
> -break;
> -}
> -else if (!strcasecmp(token, "must-revalidate")) {
> -cc->must_revalidate = 1;
>  }
>  break;
>  }
>  case 'o':
>  case 'O': {
> -if (!strcasecmp(token, "only-if-cached")) {
> +if (!ap_casecmpstr(token, "only-if-cached")) {
>  cc->only_if_cached = 1;
>  }
>  break;
>  }
> -case 'p':
> -case 'P': {
> -/* handle most common quickest cases... */
> -if (!strcmp(token, "private")) {
> -cc->private = 1;
> -}
> -/* ...then try slowest cases */
> -else if (!strcasecmp(token, "public")) {
> +case 'p': {

Why removing the uppercase 'P' case here?

Regards

Rüdiger


Re: svn commit: r1715876 - in /httpd/httpd/trunk: modules/cache/ modules/filters/ modules/generators/ modules/http/ modules/http2/ modules/loggers/ modules/mappers/ modules/metadata/ modules/proxy/ mo

2015-11-23 Thread Marion & Christophe JAILLET

Hi,

1 typo below.

Moreover, this kind of patch is a good candidate for backport as it 
introduces many small differences between 2.4 and trunk.

Without a backport, backporting future patches may become a nightmare.

I would find useful to split it into several pieces.
The first one should apply cleanly to 2.4.x to ease backport.
Other parts should be splitted in "as many piece as necessary" for 
potential future backport.


CJ


Le 23/11/2015 17:46, yla...@apache.org a écrit :

Author: ylavic
Date: Mon Nov 23 16:46:01 2015
New Revision: 1715876

URL: http://svn.apache.org/viewvc?rev=1715876=rev
Log:
Use new ap_casecmpstr[n]() functions where appropriate (not exhaustive).

Modified:

Modified: httpd/httpd/trunk/modules/cache/cache_util.c
URL: 
http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/cache_util.c?rev=1715876=1715875=1715876=diff
==
--- httpd/httpd/trunk/modules/cache/cache_util.c (original)
+++ httpd/httpd/trunk/modules/cache/cache_util.c Mon Nov 23 16:46:01 2015

[...]

@@ -1066,59 +1045,46 @@ int ap_cache_control(request_rec *r, cac
  cc->max_stale = 1;
  cc->max_stale_value = -1;
  }
-break;
  }
-else if (!strncasecmp(token, "min-fresh", 9)) {
+else if (!ap_casecmpstrn(token, "min-fresh", 9)) {
  if (token[9] == '=') {
  cc->min_fresh = 1;
  cc->min_fresh_value = apr_atoi64(token + 10);
  }
-break;
Thanks for that. I was about to commit the same kind of patch (remove 
useless break).



-}
-else if (!strcasecmp(token, "must-revalidate")) {
-cc->must_revalidate = 1;
  }
  break;
  }
  case 'o':
  case 'O': {
-if (!strcasecmp(token, "only-if-cached")) {
+if (!ap_casecmpstr(token, "only-if-cached")) {
  cc->only_if_cached = 1;
  }
  break;
  }
-case 'p':
-case 'P': {
-/* handle most common quickest cases... */
-if (!strcmp(token, "private")) {
-cc->private = 1;
-}
-/* ...then try slowest cases */
-else if (!strcasecmp(token, "public")) {
+case 'p': {

case 'P' removed?

Best regards,
CJ



Re: svn commit: r1715876 - in /httpd/httpd/trunk: modules/cache/ modules/filters/ modules/generators/ modules/http/ modules/http2/ modules/loggers/ modules/mappers/ modules/metadata/ modules/proxy/ mo

2015-11-23 Thread Yann Ylavic
On Mon, Nov 23, 2015 at 8:37 PM, Ruediger Pluem  wrote:
>
> On 11/23/2015 05:46 PM, yla...@apache.org wrote:
>>
>> -case 'p':
>> -case 'P': {
>> -/* handle most common quickest cases... */
>> -if (!strcmp(token, "private")) {
>> -cc->private = 1;
>> -}
>> -/* ...then try slowest cases */
>> -else if (!strcasecmp(token, "public")) {
>> +case 'p': {
>
> Why removing the uppercase 'P' case here?

Not intentional, fixed in r1715938.
Thanks for noticing.

Regards,
Yann.


Re: svn commit: r1715876 - in /httpd/httpd/trunk: modules/cache/ modules/filters/ modules/generators/ modules/http/ modules/http2/ modules/loggers/ modules/mappers/ modules/metadata/ modules/proxy/ mo

2015-11-23 Thread Yann Ylavic
On Mon, Nov 23, 2015 at 9:00 PM, Marion & Christophe JAILLET
 wrote:
> Hi,
>
> 1 typo below.

Fixed in r1715938, thanks.

>
> Moreover, this kind of patch is a good candidate for backport as it
> introduces many small differences between 2.4 and trunk.
> Without a backport, backporting future patches may become a nightmare.

Agreed.

>
> I would find useful to split it into several pieces.
> The first one should apply cleanly to 2.4.x to ease backport.
> Other parts should be splitted in "as many piece as necessary" for potential
> future backport.

I'll try to merge with svn, and resolve conflicts...

Regards,
Yann.


Re: strncasecmp

2015-11-23 Thread Christophe JAILLET

Hi Jim,

Do you have done some benchmark and have results to share?

I tried to do some but the benefit of the optimized version is not that 
clear, at least on my system:

   gcc 5.2.1
   Linux linux 4.2.0-18-generic #22-Ubuntu SMP Fri Nov 6 18:25:50 UTC 
2015 x86_64 x86_64 x86_64 GNU/Linux


I've tried to trick gcc in order to avoid some optimization. (gcc does 
its best to remove/inline/remove from loop known standard C functions)

I've check asm output to be more confident on the code generated by gcc.

Based on my own results only, and without any becnhmark, I would -1 a 
backport.
For small strings (below identical char), your implementation looks 
faster, but above 4 identical chars it looks slower


I can provide my test program if interested.


best regards,
CJ


Le 20/11/2015 19:53, Jim Jagielski a écrit :

Implemented in r1715401

If people want to nit-pick about naming and wish to
rename it to something else, be my guest.


On Nov 20, 2015, at 1:03 PM, Yann Ylavic  wrote:

+1

On Fri, Nov 20, 2015 at 6:17 PM, Jim Jagielski  wrote:

We use str[n]casecmp quite a bit. The rub is that some
platforms use a sensible implementation (such as OSX) which
uses a upper-lowercase map and is v. fast, and others
use a brain-dead version which does an actual tolower() of
each char in the string as it tests. We actually try to
handle this in many cases by doing a switch/case test on the
1st char to fast path the strncasecmp, resulting in ugly code.

This is crazy.

I propose a ap_strncasecmp/ap_strcasecmp which we should use.
Ideally, it would be in apr but no need to wait for that
to happen :)

Unless people have heartburn about this, I will add next week.




Re: strncasecmp

2015-11-23 Thread Yann Ylavic
Hi Christophe,

On Mon, Nov 23, 2015 at 9:12 PM, Christophe JAILLET
 wrote:
>
> I tried to do some but the benefit of the optimized version is not that
> clear, at least on my system:
>gcc 5.2.1
>Linux linux 4.2.0-18-generic #22-Ubuntu SMP Fri Nov 6 18:25:50 UTC 2015
> x86_64 x86_64 x86_64 GNU/Linux

Unfortunately, gcc 5.2.1 (i.e. latest compilers' versions) are not
widely used...

Did you try a code like ap_proxy_port_of_scheme() with values which
are unknown schemes?
Or even worse cases, with similarly chained strcasecmp() looking for
eg. "httpx" in something like {"httpa", "httpb", "httpc", ...,
"httpw"}?

Regards,
Yann.


Re: svn commit: r1715554 - /httpd/httpd/trunk/server/util.c

2015-11-23 Thread Jim Jagielski
++1

> On Nov 22, 2015, at 10:33 AM, William A Rowe Jr  wrote:
> 
> On Sat, Nov 21, 2015 at 5:10 PM, Eric Covener  wrote:
> On Sat, Nov 21, 2015 at 5:47 PM, William A Rowe Jr  
> wrote:
> > I suggest this is wrong, and that the appropriate table should be built.
> >
> > EBCDIC platforms do have i18n (typicially single-byte) lower/upper
> > equivalences, and the underlying implementation should not be trusted for
> > straight ASCII token case insensitive comparisons.
> 
> I don't see it why it shouldn't be trusted, but I've reverted for now,
> 
> I'll revisit when this settles down / the function is used somewhere.
> 
> Have a look at r1715632 and let me know what you think.
> 
> I see a lot of ill-defined or otherwise vague string functions, many of them
> are somewhat duplicate in nature, several of them questionable (unbounded
> recursion, really?)  It is probably time to move these all out to 
> util_strings.c
> and really evaluate which are appropriate to use in which contexts, while
> others should probably be evicted from trunk. ap_strcmp_match looks like
> the first worst offender (apr_fnmatch is already a much safer implementation.)
> 
> 
> 



Re: svn commit: r1715789 - in /httpd/httpd/trunk: modules/cache/ modules/filters/ modules/generators/ modules/http/ modules/http2/ modules/loggers/ modules/mappers/ modules/metadata/ modules/proxy/ mo

2015-11-23 Thread Jim Jagielski

> On Nov 23, 2015, at 7:33 AM, yla...@apache.org wrote:
> 
> Author: ylavic
> Date: Mon Nov 23 12:33:09 2015
> New Revision: 1715789
> 
> URL: http://svn.apache.org/viewvc?rev=1715789=rev
> Log:
> Use new ap_casecmpstr[n]() functions where appropriate (not exhaustive).
> 
> 
> Modified: httpd/httpd/trunk/modules/cache/cache_util.c
> URL: 
> http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/cache_util.c?rev=1715789=1715788=1715789=diff
> ==
> --- httpd/httpd/trunk/modules/cache/cache_util.c (original)
> +++ httpd/httpd/trunk/modules/cache/cache_util.c Mon Nov 23 12:33:09 2015
> @@ -594,7 +594,12 @@ int cache_check_freshness(cache_handle_t
> }
> 
> if ((agestr = apr_table_get(h->resp_hdrs, "Age"))) {
> -age_c = apr_atoi64(agestr);
> +char *endp;
> +apr_off_t offt;
> +if (!apr_strtoff(, agestr, , 10)
> +&& endp > agestr && !*endp) {
> +age_c = offt;
> +}
> }
> 
> /* calculate age of object */
> 

That's cheating :)



Re: strncasecmp

2015-11-23 Thread Yann Ylavic
I modified your test program a bit (to measure time from it, see
attached), tried with -O{2,3,s}, and except -Os I always have better
results with the "optimized" version, eg:

$ ./a-O3.out 0 15000 xcxcxcxcxcxcxcxcxcxcwwaa
xcxcxcxcxcxcxcxcxcxcwwaa 0
 (nb=15000, len=0)
time = 8.424984 : res = 0

$ ./a-O3.out 1 15000 xcxcxcxcxcxcxcxcxcxcwwaa
xcxcxcxcxcxcxcxcxcxcwwaa 0
Optimized (nb=15000, len=0)
time = 8.212137 : res = 0

Possibly gcc (v4.4.5 here) is clever enough to optimize/inline/cheat
when given standard (no custom) code, since I had similar results than
yours with the original test.c...

How does this one work with gcc-5.2?

On Mon, Nov 23, 2015 at 10:07 PM, Marion & Christophe JAILLET
 wrote:
> I just made a small application which takes as command line parameters the
> number of iteration to run, which version of the algorithm to use, the 2
> strings to compare and the length to compare (or 0 for the non 'n' versions)
>
>
> Compiled using
> gcc -O3 test.c
>
> Tested using
> linux:~/Code_Source$ time ./a.out 1 1
> xcxcxcxcxcxcxcxcxcxcwwaa
> xcxcxcxcxcxcxcxcxcxcwwaa 0
> Optimized (nb=1, len=0)
> res = 0
>
> real0m4.193s
> user0m4.192s
> sys0m0.000s
>
>
>
> linux:~/Code_Source$ time ./a.out 0 1
> xcxcxcxcxcxcxcxcxcxcwwaa
> xcxcxcxcxcxcxcxcxcxcwwaa 0
>  (nb=1, len=0)
> res = 0
>
> real0m1.708s
> user0m1.704s
> sys0m0.000s
>
>
>
>
> See atatchement.
>
> CJ
>
>
>
> Le 23/11/2015 21:33, Yann Ylavic a écrit :
>>
>> Hi Christophe,
>>
>> On Mon, Nov 23, 2015 at 9:12 PM, Christophe JAILLET
>>  wrote:
>>>
>>> I tried to do some but the benefit of the optimized version is not that
>>> clear, at least on my system:
>>> gcc 5.2.1
>>> Linux linux 4.2.0-18-generic #22-Ubuntu SMP Fri Nov 6 18:25:50 UTC
>>> 2015
>>> x86_64 x86_64 x86_64 GNU/Linux
>>
>> Unfortunately, gcc 5.2.1 (i.e. latest compilers' versions) are not
>> widely used...
>>
>> Did you try a code like ap_proxy_port_of_scheme() with values which
>> are unknown schemes?
>> Or even worse cases, with similarly chained strcasecmp() looking for
>> eg. "httpx" in something like {"httpa", "httpb", "httpc", ...,
>> "httpw"}?
>>
>> Regards,
>> Yann.
>>
>


Re: strncasecmp

2015-11-23 Thread Yann Ylavic
Please note that the changes in ap_str[n]casecmp(), ie:
++ps1;
++ps2;
was a first try/change which (obviously) did nothing.
You may ignore it.


On Mon, Nov 23, 2015 at 11:43 PM, Yann Ylavic  wrote:
> with attachment...
>
> On Mon, Nov 23, 2015 at 11:42 PM, Yann Ylavic  wrote:
>> I modified your test program a bit (to measure time from it, see
>> attached), tried with -O{2,3,s}, and except -Os I always have better
>> results with the "optimized" version, eg:
>>
>> $ ./a-O3.out 0 15000 xcxcxcxcxcxcxcxcxcxcwwaa
>> xcxcxcxcxcxcxcxcxcxcwwaa 0
>>  (nb=15000, len=0)
>> time = 8.424984 : res = 0
>>
>> $ ./a-O3.out 1 15000 xcxcxcxcxcxcxcxcxcxcwwaa
>> xcxcxcxcxcxcxcxcxcxcwwaa 0
>> Optimized (nb=15000, len=0)
>> time = 8.212137 : res = 0
>>
>> Possibly gcc (v4.4.5 here) is clever enough to optimize/inline/cheat
>> when given standard (no custom) code, since I had similar results than
>> yours with the original test.c...
>>
>> How does this one work with gcc-5.2?
>>
>> On Mon, Nov 23, 2015 at 10:07 PM, Marion & Christophe JAILLET
>>  wrote:
>>> I just made a small application which takes as command line parameters the
>>> number of iteration to run, which version of the algorithm to use, the 2
>>> strings to compare and the length to compare (or 0 for the non 'n' versions)
>>>
>>>
>>> Compiled using
>>> gcc -O3 test.c
>>>
>>> Tested using
>>> linux:~/Code_Source$ time ./a.out 1 1
>>> xcxcxcxcxcxcxcxcxcxcwwaa
>>> xcxcxcxcxcxcxcxcxcxcwwaa 0
>>> Optimized (nb=1, len=0)
>>> res = 0
>>>
>>> real0m4.193s
>>> user0m4.192s
>>> sys0m0.000s
>>>
>>>
>>>
>>> linux:~/Code_Source$ time ./a.out 0 1
>>> xcxcxcxcxcxcxcxcxcxcwwaa
>>> xcxcxcxcxcxcxcxcxcxcwwaa 0
>>>  (nb=1, len=0)
>>> res = 0
>>>
>>> real0m1.708s
>>> user0m1.704s
>>> sys0m0.000s
>>>
>>>
>>>
>>>
>>> See atatchement.
>>>
>>> CJ
>>>
>>>
>>>
>>> Le 23/11/2015 21:33, Yann Ylavic a écrit :

 Hi Christophe,

 On Mon, Nov 23, 2015 at 9:12 PM, Christophe JAILLET
  wrote:
>
> I tried to do some but the benefit of the optimized version is not that
> clear, at least on my system:
> gcc 5.2.1
> Linux linux 4.2.0-18-generic #22-Ubuntu SMP Fri Nov 6 18:25:50 UTC
> 2015
> x86_64 x86_64 x86_64 GNU/Linux

 Unfortunately, gcc 5.2.1 (i.e. latest compilers' versions) are not
 widely used...

 Did you try a code like ap_proxy_port_of_scheme() with values which
 are unknown schemes?
 Or even worse cases, with similarly chained strcasecmp() looking for
 eg. "httpx" in something like {"httpa", "httpb", "httpc", ...,
 "httpw"}?

 Regards,
 Yann.

>>>


Re: strncasecmp

2015-11-23 Thread Yann Ylavic
with attachment...

On Mon, Nov 23, 2015 at 11:42 PM, Yann Ylavic  wrote:
> I modified your test program a bit (to measure time from it, see
> attached), tried with -O{2,3,s}, and except -Os I always have better
> results with the "optimized" version, eg:
>
> $ ./a-O3.out 0 15000 xcxcxcxcxcxcxcxcxcxcwwaa
> xcxcxcxcxcxcxcxcxcxcwwaa 0
>  (nb=15000, len=0)
> time = 8.424984 : res = 0
>
> $ ./a-O3.out 1 15000 xcxcxcxcxcxcxcxcxcxcwwaa
> xcxcxcxcxcxcxcxcxcxcwwaa 0
> Optimized (nb=15000, len=0)
> time = 8.212137 : res = 0
>
> Possibly gcc (v4.4.5 here) is clever enough to optimize/inline/cheat
> when given standard (no custom) code, since I had similar results than
> yours with the original test.c...
>
> How does this one work with gcc-5.2?
>
> On Mon, Nov 23, 2015 at 10:07 PM, Marion & Christophe JAILLET
>  wrote:
>> I just made a small application which takes as command line parameters the
>> number of iteration to run, which version of the algorithm to use, the 2
>> strings to compare and the length to compare (or 0 for the non 'n' versions)
>>
>>
>> Compiled using
>> gcc -O3 test.c
>>
>> Tested using
>> linux:~/Code_Source$ time ./a.out 1 1
>> xcxcxcxcxcxcxcxcxcxcwwaa
>> xcxcxcxcxcxcxcxcxcxcwwaa 0
>> Optimized (nb=1, len=0)
>> res = 0
>>
>> real0m4.193s
>> user0m4.192s
>> sys0m0.000s
>>
>>
>>
>> linux:~/Code_Source$ time ./a.out 0 1
>> xcxcxcxcxcxcxcxcxcxcwwaa
>> xcxcxcxcxcxcxcxcxcxcwwaa 0
>>  (nb=1, len=0)
>> res = 0
>>
>> real0m1.708s
>> user0m1.704s
>> sys0m0.000s
>>
>>
>>
>>
>> See atatchement.
>>
>> CJ
>>
>>
>>
>> Le 23/11/2015 21:33, Yann Ylavic a écrit :
>>>
>>> Hi Christophe,
>>>
>>> On Mon, Nov 23, 2015 at 9:12 PM, Christophe JAILLET
>>>  wrote:

 I tried to do some but the benefit of the optimized version is not that
 clear, at least on my system:
 gcc 5.2.1
 Linux linux 4.2.0-18-generic #22-Ubuntu SMP Fri Nov 6 18:25:50 UTC
 2015
 x86_64 x86_64 x86_64 GNU/Linux
>>>
>>> Unfortunately, gcc 5.2.1 (i.e. latest compilers' versions) are not
>>> widely used...
>>>
>>> Did you try a code like ap_proxy_port_of_scheme() with values which
>>> are unknown schemes?
>>> Or even worse cases, with similarly chained strcasecmp() looking for
>>> eg. "httpx" in something like {"httpa", "httpb", "httpc", ...,
>>> "httpw"}?
>>>
>>> Regards,
>>> Yann.
>>>
>>
#include 
#include 
#include 

#include 

/*
 * Provide our own known-fast implementation of str[n]casecmp()
 * NOTE: ASCII only!
 */
static const unsigned char ucharmap[] = {
0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,
0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};

int ap_strcasecmp(const char *s1, const char *s2)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;

while (ucharmap[*ps1] == ucharmap[*ps2]) {
if (*ps1 == '\0') {
return (0);
}
++ps1;
++ps2;
}
return (ucharmap[*ps1] - ucharmap[*--ps2]);
}

int ap_strncasecmp(const char *s1, const char *s2, int n)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;

Re: svn commit: r1715876 - in /httpd/httpd/trunk: modules/cache/ modules/filters/ modules/generators/ modules/http/ modules/http2/ modules/loggers/ modules/mappers/ modules/metadata/ modules/proxy/ mo

2015-11-23 Thread William A Rowe Jr
On Nov 23, 2015 14:12, "Yann Ylavic"  wrote:
>
> On Mon, Nov 23, 2015 at 9:00 PM, Marion & Christophe JAILLET
>  wrote:
> >
> > Moreover, this kind of patch is a good candidate for backport as it
> > introduces many small differences between 2.4 and trunk.
> > Without a backport, backporting future patches may become a nightmare.
>
> Agreed.
>
> >
> > I would find useful to split it into several pieces.
> > The first one should apply cleanly to 2.4.x to ease backport.
> > Other parts should be splitted in "as many piece as necessary" for
potential
> > future backport.
>
> I'll try to merge with svn, and resolve conflicts...

Moreover,

I didn't have a chance to review the patch, but all of the instances that
1. map to an RFC protocol string comparison and 2. occur in 2.4 code base
*should* be coalesced into one patch.  I'm +1 for every such change.  The
rest of the RFC token comparisons can be added individually for later
merging with their associated bug or enhancement backports.

I'm strongly -1 for using this function to 'optimize' what is otherwise a
non-spec string comparison.  There is no excuse for us to defeat good
implementations of strcasecmp for the benefit of platforms with shoddy
implementations.

Jim proposed this as an optimization but I reject that, and wholeheartedly
support his suggested use of a predictable ASCII-only folding comparison
when following any spec that defines token strings in terms of ASCII alpha
chars.

We aren't writing a clib but we do have to be mindful of i18n side-effects
of the clib we are running within.


Re: strncasecmp

2015-11-23 Thread Mikhail T.
On 23.11.2015 23:14, William A Rowe Jr wrote:
> L1 cache and other direct effects of cpu internal optimization.
Just what I was thinking. Attached is the same program with one more
pair of functions added (and an easy way to add more "candidates" to the
main-driver). I changed the FOR-loop define to obtain repeatable results:

# Test 1 -- equal strings:
foreach m ( 0 1 2 )
foreach? ./strncasecmp $m 1 a A 7
foreach? end
string.h (nb=1, len=7)
time = 6.975845 : res = 0
optimized (nb=1, len=7)
time = 1.492197 : res = 0
'A' - 'a' (nb=1, len=7)
time = 1.787807 : res = 0

# Test 2 -- immediately-different strings
foreach m ( 0 1 2 )
foreach? ./strncasecmp $m 1 a x 7
foreach? end
string.h (nb=1, len=7)
time = 2.527727 : res = -23
optimized (nb=1, len=7)
time = 0.406867 : res = -23
'A' - 'a' (nb=1, len=7)
time = 0.440320 : res = -23

# Test 3 -- strings different at the very end
foreach m ( 0 1 2 )
foreach? ./strncasecmp $m 1 a x 0
foreach? end
string.h (nb=1, len=0)
time = 9.629660 : res = -23
optimized (nb=1, len=0)
time = 1.387208 : res = -23
'A' - 'a' (nb=1, len=0)
time = 1.754683 : res = -23

The new pair (method 2) does not use the static table, which is likely
to benefit from CPU-cache unfairly in repetitive benchmarks.  It is
slower than the table-using method 1 functions. But the two pairs might
be comparable -- or even faster -- in real life.

-mi

#include 
#include 
#include 

#define gettimeofday(X) gettimeofday(X, NULL)

#include 
#include 
#include 
#include 
#include 

#include 

/*
 * Provide our own known-fast implementation of str[n]casecmp()
 * NOTE: ASCII only!
 */
static const unsigned char ucharmap[] = {
0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,
0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};

int ap_strcasecmp(const char *s1, const char *s2)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;

while (*ps1 == *ps2 || ucharmap[*ps1] == ucharmap[*ps2]) {
if (*ps1 == '\0') {
return (0);
}
++ps1;
++ps2;
}
return (ucharmap[*ps1] - ucharmap[*ps2]);
}

int ap_strncasecmp(const char *s1, const char *s2, size_t n)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;
while (n--) {
if (*ps1 == *ps2 || ucharmap[*ps1] != ucharmap[*ps2]) {
return (ucharmap[*ps1] - ucharmap[*ps2]);
}
if (*ps1 == '\0') {
break;
}
++ps1;
++ps2;
}
return (0);
}

int mi_strcasecmp(const char *s1, const char *s2)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;

for (;;) {
int diff = *ps1 - *ps2;
switch (diff) {
case 0:
break;
case 'A' - 'a':
if (*ps1 <= 'Z' && *ps1 >= 'A')
break;
return 1;
case 'a' - 'A':
if (*ps2 <= 'Z' && *ps2 >= 'A')
 

Re: strncasecmp

2015-11-23 Thread William A Rowe Jr
On Nov 23, 2015 21:12, "Mikhail T."  wrote:
>
> On 23.11.2015 19:43, Yann Ylavic wrote:
>>
>> No measured difference in my tests, I guess it depends on likelyhood to
fail/succeed early in the string or not.
>
> ? I don't see, where it wins anything -- but I do see, where it loses a
little...
>
>> That's expected (or at least no cared about in this test case). We
simply want res to not be optimized out, so print it before leaving,
without any particular relevance for its value (string.h and optimized
versions should return the same res with the same args, ascii strings only,
though).
>
> Yes, we do want the value printed -- such as to catch the kind of errors
I reported earlier. But my question was, why does the value change
depending on the number of iterations?

L1 cache and other direct effects of cpu internal optimization.

You would be better off introducing a non-optimizable operation consuming
most cpu registers and the L1 cache between iterations if you want to
predict the non-repeditive invocation of this function in different
contexts throughout the processing phases.


[Dev] GSoC Intro and Contribution to Apache

2015-11-23 Thread Vithuląñ Ḿṿ
Hi,

I'm Vithulan, Undergraduate of Computer Science and Engineering in
University of Moratuwa, Sri lanka. I have quite experience in Java,
JavaScript, Android and Open Source, Currently doing my internship in a
open source middle-ware company. I'm a potential GSoC candidate, and would
love to help your guidance on how should I proceed?

Thanks.

Regards,
Vithulan MV.

-- 
M.V.Vithulan


Re: strncasecmp

2015-11-23 Thread Mikhail T.
On 23.11.2015 19:05, Yann Ylavic wrote:
> Here is the correct (new) test, along with the diff wrt the original
> (Christophe's) test.c.
BTW, if the program measures its own time, should it not use getrusage()
instead of gettimeofday()?

-mi



Re: strncasecmp

2015-11-23 Thread Yann Ylavic
On Tue, Nov 24, 2015 at 1:07 AM, Mikhail T.  wrote:
>
> BTW, if the program measures its own time, should it not use getrusage()
> instead of gettimeofday()?

Well, it measures the time spent in the relevant code, with a
monotonic clock, that should be fair enough.
We don't care about the whole process time and other counters.

Regards,
Yann.


Re: strncasecmp

2015-11-23 Thread Yann Ylavic
On Mon, Nov 23, 2015 at 11:42 PM, Yann Ylavic  wrote:
> except -Os I always have better
> results with the "optimized" version

To reach better performances with -Os, we could possibly use:

int ap_strcasecmp(const char *s1, const char *s2)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;
for (;;) {
const unsigned int c1 = ucharmap[*ps1++],
   c2 = ucharmap[*ps2++];
if (c1 != c2) {
return c1 - c2;
}
if (c1 == '\0') {
break;
}
}
return (0);
}

int ap_strncasecmp(const char *s1, const char *s2, int n)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;
while (n--) {
const unsigned int c1 = ucharmap[*ps1++],
   c2 = ucharmap[*ps2++];
if (c1 != c2) {
return c1 - c2;
}
if (c1 == '\0') {
break;
}
}
return (0);
}

This implementation with -Os is ~13% slower than str[n]casemp(),
whereas the original ap_str[n]casemp() is ~30% slower.

Don't know if it happens/makes sense to compile httpd with -Os...
At least for APR, I think we could take that into consideration.


Re: strncasecmp

2015-11-23 Thread Mikhail T.
On 23.11.2015 17:43, Yann Ylavic wrote:
> with attachment...
There is a mistake somewhere in the optimized version:

./o 1 1  aa1a 0
Optimized (nb=1, len=0)
time = 0.611311 : res = 0

The result should not be zero. Indeed, the string.h version is correct:

./o 0 1  aa1a 0
 (nb=1, len=0)
time = 4.189366 : res = 48

Yours,

-mi



Re: strncasecmp

2015-11-23 Thread Mikhail T.
On 23.11.2015 19:05, Yann Ylavic wrote:
> while (ucharmap[*ps1] == ucharmap[*ps2++]) {
> if (*ps1++ == '\0') {
> return (0);
> }
> }
> return (ucharmap[*ps1] - ucharmap[*--ps2]);
Is there really a gain in inc- and decrementing this way? Would not it
be easier to read with the explicit increments -- and, incidentally, no
decrements at all?

while (ucharmap[*ps1] == ucharmap[*ps2]) {
if (*ps1 == '\0') {
return (0);
}
++ps1;
++ps2;
}
return (ucharmap[*ps1] - ucharmap[*ps2]);

> We don't care about the whole process time and other counters.
That's certainly true. But, then, why bother with building time-counter
into the test at all -- instead of simply relying on time(1)?

But something is still not right -- the result (for either of the
methods) can depend on the number of iterations (!!):

./strncasecmp 1 27 aCaa Ac 2
Optimized (nb=27, len=2)
time = 0.01 : res = 32
./strncasecmp 1 26 aCaa Ac 2
Optimized (nb=26, len=2)
time = 0.01 : res = 0
./strncasecmp 0 27 aCaa Ac 2
 (nb=27, len=2)
time = 0.03 : res = 32
./strncasecmp 0 26 aCaa Ac 2
 (nb=26, len=2)
time = 0.03 : res = 0

Using clang on FreeBSD/amd64 here. Yours,

-mi




Re: strncasecmp

2015-11-23 Thread Yann Ylavic
FWIW, a new version using clock_gettime() instead of gettimeofday().
Same/Comparable results for optimized vs string.h's (the former wins
but with -Os).

On Tue, Nov 24, 2015 at 1:43 AM, Yann Ylavic  wrote:
> On Tue, Nov 24, 2015 at 1:24 AM, Mikhail T.  wrote:
>>
>> Is there really a gain in inc- and decrementing this way? Would not it be
>> easier to read with the explicit increments -- and, incidentally, no
>> decrements at all?
>
> No measured difference in my tests, I guess it depends on likelyhood
> to fail/succeed early in the string or not.
>
>>>
>>> We don't care about the whole process time and other counters.
>>
>> That's certainly true. But, then, why bother with building time-counter into
>> the test at all -- instead of simply relying on time(1)?
>
> That's the purpose of newtest.c (vs Christophe's test.c): try both...
>
>>
>> But something is still not right -- the result (for either of the methods)
>> can depend on the number of iterations (!!):
>
> That's expected (or at least no cared about in this test case).
> We simply want res to not be optimized out, so print it before
> leaving, without any particular relevance for its value (string.h and
> optimized versions should return the same res with the same args,
> ascii strings only, though).
#include 
#include 
#include 
#include 

#include 
#include 

/*
 * Provide our own known-fast implementation of str[n]casecmp()
 * NOTE: ASCII only!
 */
static const unsigned char ucharmap[] = {
0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,
0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};

int ap_strcasecmp(const char *s1, const char *s2)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;

while (ucharmap[*ps1] == ucharmap[*ps2++]) {
if (*ps1++ == '\0') {
return (0);
}
}
return (ucharmap[*ps1] - ucharmap[*--ps2]);
}

int ap_strncasecmp(const char *s1, const char *s2, int n)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;
while (n--) {
if (ucharmap[*ps1] != ucharmap[*ps2++]) {
return (ucharmap[*ps1] - ucharmap[*--ps2]);
}
if (*ps1++ == '\0') {
break;
}
}
return (0);
}

#define PROG argv[0]
#define METHOD argv[1]
#define NB argv[2]
#define S1 argv[3]
#define S2 argv[4]
#define LEN argv[5]

/* The ++ are here to try to prevent some optimization done by gcc */
#define FOR for (i=0; i  S1 S2 \n", PROG);
return 0;
}

len = atoi(LEN);
nb  = atoi(NB);

if (*METHOD == '0') {
printf(" (nb=%d, len=%d)\n", nb, len);
clock_gettime(CLOCK_MONOTONIC, );
if (len == 0) {
FOR {
/* really use the result of the function */
res |= strcasecmp(S1, S2);
}
}
else {
FOR {
res |= strncasecmp(S1, S2, len);
}
}
clock_gettime(CLOCK_MONOTONIC, );
}
else {
printf("Optimized (nb=%d, len=%d)\n", nb, len);

Re: strncasecmp

2015-11-23 Thread Yann Ylavic
On Tue, Nov 24, 2015 at 12:46 AM, Mikhail T.  wrote:
> On 23.11.2015 17:43, Yann Ylavic wrote:
>
> with attachment...
>
> There is a mistake somewhere in the optimized version:

My bad, I somehow corrupted the original ap_str[n]casecmp() functions.

Here is the correct (new) test, along with the diff wrt the original
(Christophe's) test.c.

Thanks,
Yann.
--- test.c  2015-11-24 01:01:29.039339318 +0100
+++ newtest.c   2015-11-24 00:57:13.720817895 +0100
@@ -1,8 +1,10 @@
 #include 
+#include 
 #include 
 #include 
 
 #include 
+#include 
 
 /*
  * Provide our own known-fast implementation of str[n]casecmp()
@@ -83,6 +85,8 @@ int ap_strncasecmp(const char *s1, const
 
 int main(int argc, char *argv[])
 {
+int64_t diff;
+struct timeval tvs, tve;
 int i, len, nb;
 int res = 0;
 
@@ -96,6 +100,7 @@ int main(int argc, char *argv[])
 
 if (*METHOD == '0') {
 printf(" (nb=%d, len=%d)\n", nb, len);
+gettimeofday(, NULL);
 if (len == 0) {
 FOR {
 /* really use the result of the function */
@@ -107,9 +112,11 @@ int main(int argc, char *argv[])
 res |= strncasecmp(S1, S2, len);
 }
 }
+gettimeofday(, NULL);
 }
 else {
 printf("Optimized (nb=%d, len=%d)\n", nb, len);
+gettimeofday(, NULL);
 if (len == 0) {
 FOR {
 res |= ap_strcasecmp(S1, S2);
@@ -120,9 +127,16 @@ int main(int argc, char *argv[])
 res |= ap_strncasecmp(S1, S2, len);
 }
 }
+gettimeofday(, NULL);
 }
-
+
+diff  = (int64_t)tve.tv_sec * 100L + tve.tv_usec;
+diff -= (int64_t)tvs.tv_sec * 100L + tvs.tv_usec;
+
 /* really use the result of the function */
-printf("res = %d\n", res);
+printf("time = %lld.%.6lld : res = %d\n",
+(long long)diff / 100L,
+(long long)diff % 100L,
+res);
 return 0; 
 }
#include 
#include 
#include 
#include 

#include 
#include 

/*
 * Provide our own known-fast implementation of str[n]casecmp()
 * NOTE: ASCII only!
 */
static const unsigned char ucharmap[] = {
0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,
0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};

int ap_strcasecmp(const char *s1, const char *s2)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;

while (ucharmap[*ps1] == ucharmap[*ps2++]) {
if (*ps1++ == '\0') {
return (0);
}
}
return (ucharmap[*ps1] - ucharmap[*--ps2]);
}

int ap_strncasecmp(const char *s1, const char *s2, int n)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;
while (n--) {
if (ucharmap[*ps1] != ucharmap[*ps2++]) {
return (ucharmap[*ps1] - ucharmap[*--ps2]);
}
if (*ps1++ == '\0') {
break;
}
}
return (0);
}

#define PROG argv[0]
#define METHOD argv[1]
#define NB argv[2]
#define S1 argv[3]
#define S2 argv[4]
#define LEN argv[5]

/* The ++ are here to try to prevent some optimization done by gcc */
#define FOR for (i=0; i

Re: strncasecmp

2015-11-23 Thread Yann Ylavic
On Tue, Nov 24, 2015 at 1:24 AM, Mikhail T.  wrote:
>
> Is there really a gain in inc- and decrementing this way? Would not it be
> easier to read with the explicit increments -- and, incidentally, no
> decrements at all?

No measured difference in my tests, I guess it depends on likelyhood
to fail/succeed early in the string or not.

>>
>> We don't care about the whole process time and other counters.
>
> That's certainly true. But, then, why bother with building time-counter into
> the test at all -- instead of simply relying on time(1)?

That's the purpose of newtest.c (vs Christophe's test.c): try both...

>
> But something is still not right -- the result (for either of the methods)
> can depend on the number of iterations (!!):

That's expected (or at least no cared about in this test case).
We simply want res to not be optimized out, so print it before
leaving, without any particular relevance for its value (string.h and
optimized versions should return the same res with the same args,
ascii strings only, though).


Re: strncasecmp

2015-11-23 Thread Mikhail T.
On 23.11.2015 19:43, Yann Ylavic wrote:
> No measured difference in my tests, I guess it depends on likelyhood to 
> fail/succeed early in the string or not.
? I don't see, where it wins anything -- but I do see, where it loses a
little...
> That's expected (or at least no cared about in this test case). We
> simply want res to not be optimized out, so print it before leaving,
> without any particular relevance for its value (string.h and optimized
> versions should return the same res with the same args, ascii strings
> only, though). 
Yes, we do want the value printed -- such as to catch the kind of errors
I reported earlier. But my question was, why does the value change
depending on the number of iterations?

-mi




Re: svn commit: r1715789 - in /httpd/httpd/trunk: modules/cache/ modules/filters/ modules/generators/ modules/http/ modules/http2/ modules/loggers/ modules/mappers/ modules/metadata/ modules/proxy/ mo

2015-11-23 Thread Yann Ylavic
On Mon, Nov 23, 2015 at 3:05 PM, Jim Jagielski  wrote:
>
> That's cheating :)

Yeah, reverted (r1715869) and re-committed (r1715876) with no functional change.
Thanks for catching!


Re: svn commit: r1715859 - /httpd/httpd/trunk/include/httpd.h

2015-11-23 Thread William A Rowe Jr
On Mon, Nov 23, 2015 at 9:58 AM,  wrote:

> Author: jim
> Date: Mon Nov 23 15:58:25 2015
> New Revision: 1715859
>
> URL: http://svn.apache.org/viewvc?rev=1715859=rev
> Log:
> we just worry about "equality" with this implementation...
> So it's not a "real" strcasecmp replacement.
>
> Modified:
> httpd/httpd/trunk/include/httpd.h
>
> Modified: httpd/httpd/trunk/include/httpd.h
> URL:
> http://svn.apache.org/viewvc/httpd/httpd/trunk/include/httpd.h?rev=1715859=1715858=1715859=diff
>
> ==
> --- httpd/httpd/trunk/include/httpd.h (original)
> +++ httpd/httpd/trunk/include/httpd.h Mon Nov 23 15:58:25 2015
> @@ -2442,9 +2442,8 @@ AP_DECLARE(int) ap_array_str_contains(co
>   * Known-fast version of strcasecmp(): ASCII case-folding, POSIX compliant
>   * @param s1 The 1st string to compare
>   * @param s2 The 2nd string to compare
> - * @return integer greater than, equal to, or less than 0, depending on
> - * if s1 is lexicographically greater than, equal to, or less
> - * than s2 ignoring case.
> + * @return 0 if s1 is lexicographically equal to s2 ignoring case;
> + * non-0 otherwise.
>   */
>  AP_DECLARE(int) ap_casecmpstr(const char *s1, const char *s2);
>
> @@ -2453,9 +2452,8 @@ AP_DECLARE(int) ap_casecmpstr(const char
>   * @param s1 The 1st string to compare
>   * @param s2 The 2nd string to compare
>   * @param n  Maximum number of characters in the strings to compare
> - * @return integer greater than, equal to, or less than 0, depending on
> - * if s1 is lexicographically greater than, equal to, or less
> - * than s2 ignoring case.
> + * @return 0 if s1 is lexicographically equal to s2 ignoring case;
> + * non-0 otherwise.
>   */
>  AP_DECLARE(int) ap_casecmpstrn(const char *s1, const char *s2, apr_size_t
> n);
>

Howso?  The implementation does provide ASCII numeric-alpha ordering.


Re: strncasecmp

2015-11-23 Thread Marion & Christophe JAILLET
I just made a small application which takes as command line parameters 
the number of iteration to run, which version of the algorithm to use, 
the 2 strings to compare and the length to compare (or 0 for the non 'n' 
versions)



Compiled using
gcc -O3 test.c

Tested using
linux:~/Code_Source$ time ./a.out 1 1 
xcxcxcxcxcxcxcxcxcxcwwaa 
xcxcxcxcxcxcxcxcxcxcwwaa 0

Optimized (nb=1, len=0)
res = 0

real0m4.193s
user0m4.192s
sys0m0.000s



linux:~/Code_Source$ time ./a.out 0 1 
xcxcxcxcxcxcxcxcxcxcwwaa 
xcxcxcxcxcxcxcxcxcxcwwaa 0

 (nb=1, len=0)
res = 0

real0m1.708s
user0m1.704s
sys0m0.000s




See atatchement.

CJ


Le 23/11/2015 21:33, Yann Ylavic a écrit :

Hi Christophe,

On Mon, Nov 23, 2015 at 9:12 PM, Christophe JAILLET
 wrote:

I tried to do some but the benefit of the optimized version is not that
clear, at least on my system:
gcc 5.2.1
Linux linux 4.2.0-18-generic #22-Ubuntu SMP Fri Nov 6 18:25:50 UTC 2015
x86_64 x86_64 x86_64 GNU/Linux

Unfortunately, gcc 5.2.1 (i.e. latest compilers' versions) are not
widely used...

Did you try a code like ap_proxy_port_of_scheme() with values which
are unknown schemes?
Or even worse cases, with similarly chained strcasecmp() looking for
eg. "httpx" in something like {"httpa", "httpb", "httpc", ...,
"httpw"}?

Regards,
Yann.



#include 
#include 
#include 

#include 

/*
 * Provide our own known-fast implementation of str[n]casecmp()
 * NOTE: ASCII only!
 */
static const unsigned char ucharmap[] = {
0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,
0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60,  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 'x',  'y',  'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};

int ap_strcasecmp(const char *s1, const char *s2)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;

while (ucharmap[*ps1] == ucharmap[*ps2++]) {
if (*ps1++ == '\0') {
return (0);
}
}
return (ucharmap[*ps1] - ucharmap[*--ps2]);
}

int ap_strncasecmp(const char *s1, const char *s2, int n)
{
const unsigned char *ps1 = (const unsigned char *) s1;
const unsigned char *ps2 = (const unsigned char *) s2;
while (n--) {
if (ucharmap[*ps1] != ucharmap[*ps2++]) {
return (ucharmap[*ps1] - ucharmap[*--ps2]);
}
if (*ps1++ == '\0') {
break;
}
}
return (0);
}

#define PROG argv[0]
#define METHOD argv[1]
#define NB argv[2]
#define S1 argv[3]
#define S2 argv[4]
#define LEN argv[5]

/* The ++ are here to try to prevent some optimization done by gcc */
#define FOR for (i=0; i  S1 S2 \n", PROG);
return 0;
}

len = atoi(LEN);
nb  = atoi(NB);

if (*METHOD == '0') {
printf(" (nb=%d, len=%d)\n", nb, len);
if (len == 0) {
FOR {
/* really use the result of the function */
res |= strcasecmp(S1, S2);
}
}
else {
FOR {
res |= strncasecmp(S1, S2, len);
}
}
}
else {
printf("Optimized (nb=%d, len=%d)\n", nb, len);
if (len == 0) {
FOR {