mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-09 11:58:23 +08:00
Compare commits
369
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b0e50ce9e | ||
|
|
54377921e7 | ||
|
|
9a010a5f63 | ||
|
|
f03cfdf9bf | ||
|
|
6957bcb154 | ||
|
|
56532663f2 | ||
|
|
52b8d67f22 | ||
|
|
dc7ba1835b | ||
|
|
8f29d3b5ae | ||
|
|
63e9a36056 | ||
|
|
a3ed3a127c | ||
|
|
642c8732a1 | ||
|
|
eefa3be8e4 | ||
|
|
85891acadf | ||
|
|
31ad488dff | ||
|
|
db24e6842d | ||
|
|
f723285b13 | ||
|
|
30bbc0ccfa | ||
|
|
3cbc52dbbc | ||
|
|
f1a7f49259 | ||
|
|
90e62a4aae | ||
|
|
d492e6d080 | ||
|
|
641aa7b459 | ||
|
|
d4baa62d45 | ||
|
|
f8b4877a75 | ||
|
|
61a9dcb9d6 | ||
|
|
be063fa458 | ||
|
|
cb821cb175 | ||
|
|
135529b443 | ||
|
|
7b1f8b581f | ||
|
|
e7074e4c5e | ||
|
|
1fe2988f52 | ||
|
|
a8fc7a03a8 | ||
|
|
e4608715e6 | ||
|
|
da2d62df77 | ||
|
|
106bd84baa | ||
|
|
19a601f7b2 | ||
|
|
075b9322c9 | ||
|
|
d3d3ce982a | ||
|
|
d7e06450b9 | ||
|
|
f959cfd790 | ||
|
|
39f0b2e91a | ||
|
|
8ab07407ba | ||
|
|
c61f8513f7 | ||
|
|
95a4e1ea3b | ||
|
|
b68c223125 | ||
|
|
36002f0786 | ||
|
|
72c90ed01f | ||
|
|
bb3ced6f37 | ||
|
|
52dfbe137e | ||
|
|
3f16954315 | ||
|
|
521c6785e1 | ||
|
|
a0d93e9b26 | ||
|
|
52667c6cad | ||
|
|
e2a32bee75 | ||
|
|
d2cc15cb50 | ||
|
|
3aaeeca7a9 | ||
|
|
6ed4c7891a | ||
|
|
5314ed1afd | ||
|
|
62e9e9f802 | ||
|
|
b4ac1f6acb | ||
|
|
67338156ea | ||
|
|
6bed143eb4 | ||
|
|
c87156e5e9 | ||
|
|
a7cb9d67a5 | ||
|
|
1717da59ae | ||
|
|
49186d21ef | ||
|
|
e8c659d74e | ||
|
|
68cc29355f | ||
|
|
b023e4ca99 | ||
|
|
1cdbe57948 | ||
|
|
1c81621c5b | ||
|
|
77f01ab5d1 | ||
|
|
1413c693d3 | ||
|
|
c53e2f0a56 | ||
|
|
8145005c31 | ||
|
|
e7521973aa | ||
|
|
6308fd9a46 | ||
|
|
89cd956937 | ||
|
|
1ae8bfe07c | ||
|
|
8fbec01098 | ||
|
|
0432680e8c | ||
|
|
ce61a2ad2e | ||
|
|
ef65da39e6 | ||
|
|
0cad7ea248 | ||
|
|
3d0f5d0c7a | ||
|
|
f91f1c0fb8 | ||
|
|
ed0257f7d3 | ||
|
|
03ea4d9b69 | ||
|
|
fe114d2064 | ||
|
|
cbe7d24bb4 | ||
|
|
bb5bb87cd2 | ||
|
|
fc74328c1f | ||
|
|
11b8a0e1d7 | ||
|
|
b003710377 | ||
|
|
c18c701d03 | ||
|
|
89756a8cdb | ||
|
|
1d17fa5f8e | ||
|
|
8fcb833a2b | ||
|
|
5ccb431120 | ||
|
|
385fd0d524 | ||
|
|
17db6e8d6b | ||
|
|
d605071ebf | ||
|
|
e1f0b2cfa1 | ||
|
|
2f063a6e84 | ||
|
|
a74ca98fdd | ||
|
|
a31ee4b3a5 | ||
|
|
09d91fde6b | ||
|
|
e781d7c58f | ||
|
|
d8412221e6 | ||
|
|
695c378f81 | ||
|
|
d1d5471579 | ||
|
|
638faeb6fe | ||
|
|
8fdda7afb8 | ||
|
|
f3bc5e5a3e | ||
|
|
be09e8c9ec | ||
|
|
85c2e6110c | ||
|
|
b8c792af85 | ||
|
|
c91e082525 | ||
|
|
bfcacbdec0 | ||
|
|
02a809d2cd | ||
|
|
733edfb8ae | ||
|
|
d7dffa6a55 | ||
|
|
18e5cc3a82 | ||
|
|
c411604296 | ||
|
|
e55a9b256d | ||
|
|
3023a72eb8 | ||
|
|
12086fb483 | ||
|
|
346d65b33a | ||
|
|
1a8463176c | ||
|
|
3711a167f6 | ||
|
|
8fc75e6fb7 | ||
|
|
adf23d2cca | ||
|
|
61dd6208fb | ||
|
|
601eb33deb | ||
|
|
c69f6af9e5 | ||
|
|
d8572c5cfc | ||
|
|
d086fc7ba0 | ||
|
|
747ef469ff | ||
|
|
1b2feed264 | ||
|
|
c396afdfa4 | ||
|
|
a58ad3f801 | ||
|
|
5865a56bf4 | ||
|
|
c204ab284b | ||
|
|
f4a29fba07 | ||
|
|
ad36ba2bd6 | ||
|
|
1f24b9ad0f | ||
|
|
b406406a4f | ||
|
|
308d7ca933 | ||
|
|
28b8265a2c | ||
|
|
2d6f4c5b53 | ||
|
|
58206c6863 | ||
|
|
6a97b62a5b | ||
|
|
94f2c07669 | ||
|
|
e0e50a0a31 | ||
|
|
2506109403 | ||
|
|
59b3055595 | ||
|
|
f1d73d30df | ||
|
|
94aca5e740 | ||
|
|
d04310f210 | ||
|
|
fac0c5f2b1 | ||
|
|
f22bc486c1 | ||
|
|
4eacded20f | ||
|
|
fec799f823 | ||
|
|
9702047480 | ||
|
|
c1f75dc386 | ||
|
|
50fd745b4d | ||
|
|
3ee7e9fe34 | ||
|
|
a214aecf82 | ||
|
|
89fb683558 | ||
|
|
b8c61b4b1d | ||
|
|
be11d71394 | ||
|
|
0efa6f8b99 | ||
|
|
50b818bf96 | ||
|
|
416641e687 | ||
|
|
e3f36662ee | ||
|
|
4902d2c3f7 | ||
|
|
60d2f8f3c7 | ||
|
|
2e09a79ada | ||
|
|
8e254d8e0d | ||
|
|
9e54314bb0 | ||
|
|
350635a59a | ||
|
|
25506f09dd | ||
|
|
c7afae94ca | ||
|
|
ecdaa7c920 | ||
|
|
44a988afd8 | ||
|
|
9c84384cc1 | ||
|
|
5556231db2 | ||
|
|
869378a5bf | ||
|
|
840e2943e8 | ||
|
|
4c60cb0c83 | ||
|
|
96df079a42 | ||
|
|
6e445a3d2b | ||
|
|
d180203e97 | ||
|
|
8b0ccb2d7f | ||
|
|
3b3c4d40c1 | ||
|
|
fab7ce3f5b | ||
|
|
eca5920cd9 | ||
|
|
96945714ec | ||
|
|
b937534868 | ||
|
|
d0501bfbe2 | ||
|
|
8a9f20c83c | ||
|
|
0e60d68ef0 | ||
|
|
56b672e92e | ||
|
|
5e056687df | ||
|
|
528c24058f | ||
|
|
07b4c13d0b | ||
|
|
ec9dd97cec | ||
|
|
2b66ef5d55 | ||
|
|
0323d08657 | ||
|
|
dd4259b9f7 | ||
|
|
5e6fbdc58f | ||
|
|
4f8dfe270b | ||
|
|
d116b7c414 | ||
|
|
e96e37676f | ||
|
|
86bd05fbc8 | ||
|
|
e8bdba36c5 | ||
|
|
b679a606ca | ||
|
|
bae143d270 | ||
|
|
d4ea44a04b | ||
|
|
9323d39bae | ||
|
|
7b2991daea | ||
|
|
1fd885a5b3 | ||
|
|
13e23af76e | ||
|
|
351fe55087 | ||
|
|
85118d4de3 | ||
|
|
7a44c18fb4 | ||
|
|
b50a71810b | ||
|
|
3ce9e01097 | ||
|
|
051063c88b | ||
|
|
04453c5625 | ||
|
|
47c22455d4 | ||
|
|
3d04f5db20 | ||
|
|
d5dd6189d5 | ||
|
|
fef94eab0b | ||
|
|
e39adf43c7 | ||
|
|
6c14f68aab | ||
|
|
68191c1d59 | ||
|
|
b2b671b677 | ||
|
|
2d48b41c8f | ||
|
|
3e69426875 | ||
|
|
db62a90753 | ||
|
|
f16cc3eb81 | ||
|
|
2ee094ff75 | ||
|
|
3779b5b64a | ||
|
|
bb38759d6d | ||
|
|
a00bdcf0e0 | ||
|
|
de407f79a2 | ||
|
|
8269107fe6 | ||
|
|
48a18de1e1 | ||
|
|
13d3b41a36 | ||
|
|
2848b10585 | ||
|
|
c58b274f01 | ||
|
|
0ab349044b | ||
|
|
323e5cb792 | ||
|
|
e054f49430 | ||
|
|
8c75f67421 | ||
|
|
e6e49e59c1 | ||
|
|
105a07dfc0 | ||
|
|
e9eee333b9 | ||
|
|
1c38ff73fd | ||
|
|
15c7c18dc6 | ||
|
|
f137ff1383 | ||
|
|
c5d9b39ce6 | ||
|
|
3608cb241e | ||
|
|
1deff3dca1 | ||
|
|
791f3ba0db | ||
|
|
39b1f6172a | ||
|
|
ecbf434213 | ||
|
|
12fba011bd | ||
|
|
b861c6c4c9 | ||
|
|
86ee76a086 | ||
|
|
b7f7d28b61 | ||
|
|
7abeee129e | ||
|
|
cbe8c4d333 | ||
|
|
5575c0e5cd | ||
|
|
d369f53178 | ||
|
|
781fd74820 | ||
|
|
5e90827081 | ||
|
|
f71172e551 | ||
|
|
8cfa635ab8 | ||
|
|
0175558aa0 | ||
|
|
2bcb36b265 | ||
|
|
acbd839a07 | ||
|
|
e414d745ee | ||
|
|
d9c2a0fd2c | ||
|
|
9dc9095d56 | ||
|
|
87aa21df6f | ||
|
|
141af660d8 | ||
|
|
5d5ef5dbfc | ||
|
|
68fc074ca0 | ||
|
|
243216e126 | ||
|
|
6a1992e268 | ||
|
|
0e400df55d | ||
|
|
6d33265c72 | ||
|
|
f98ece5fe2 | ||
|
|
43fe811b73 | ||
|
|
0f7d347bd0 | ||
|
|
4f184d30cb | ||
|
|
081988778f | ||
|
|
d842b1440d | ||
|
|
601a3a5fd5 | ||
|
|
8329e4da35 | ||
|
|
74c574788d | ||
|
|
b4180a5ea7 | ||
|
|
7187d844a1 | ||
|
|
f63fae7378 | ||
|
|
8a67a4b343 | ||
|
|
51df539d98 | ||
|
|
5c637fe5ee | ||
|
|
ab2b94613d | ||
|
|
4c0fe6fe42 | ||
|
|
a3375d2990 | ||
|
|
3612972234 | ||
|
|
ed41ffefc3 | ||
|
|
d0213cd0b6 | ||
|
|
0d3e777af2 | ||
|
|
66c13581af | ||
|
|
24f5606614 | ||
|
|
faa7f8119f | ||
|
|
e9a5e0fd54 | ||
|
|
a0d9f9d745 | ||
|
|
ae08db3ba0 | ||
|
|
ae65139d14 | ||
|
|
f44bf14a9c | ||
|
|
d8cd06db62 | ||
|
|
bb7cf681e9 | ||
|
|
ba85394732 | ||
|
|
8347c74cc5 | ||
|
|
1a0fc08754 | ||
|
|
e8dd47916f | ||
|
|
a917305749 | ||
|
|
976e2f0381 | ||
|
|
9723ffc524 | ||
|
|
962e6658a3 | ||
|
|
ee586a6d5c | ||
|
|
355f916505 | ||
|
|
bd9ffde61a | ||
|
|
8fb16a04e6 | ||
|
|
b99b892f68 | ||
|
|
c74058300c | ||
|
|
9ea3513c91 | ||
|
|
5bf96de5ef | ||
|
|
12290c0614 | ||
|
|
16e616a72f | ||
|
|
d5e8275481 | ||
|
|
b7dab1e4d7 | ||
|
|
a7548d41a7 | ||
|
|
cc0e6ed81f | ||
|
|
60bfd54cbb | ||
|
|
83e7640f6b | ||
|
|
c31a5b1e8f | ||
|
|
d5dc2af390 | ||
|
|
164fd39d05 | ||
|
|
8237f48c90 | ||
|
|
9df02941c2 | ||
|
|
bb5f27adca | ||
|
|
d422395e31 | ||
|
|
a07c5731d6 | ||
|
|
1324e37f2e | ||
|
|
0695940b8a | ||
|
|
10de07f5fd | ||
|
|
cb4d54147e | ||
|
|
296f21e7bd | ||
|
|
caf84319c1 | ||
|
|
6dbe713d85 | ||
|
|
f0ee064b7d | ||
|
|
d569c6eeb4 | ||
|
|
a6a242fe7c |
@@ -133,6 +133,21 @@ will be used, and CFLAGS sets optimization options for the compiler.
|
||||
library. This option hardcodes the newly built C library path in
|
||||
dynamic tests so that they can be invoked directly.
|
||||
|
||||
`--enable-lock-elision=yes'
|
||||
Enable lock elision for pthread mutexes by default.
|
||||
|
||||
`--enable-pt_chown'
|
||||
The file `pt_chown' is a helper binary for `grantpt' (*note
|
||||
Pseudo-Terminals: Allocation.) that is installed setuid root to
|
||||
fix up pseudo-terminal ownership. It is not built by default
|
||||
because systems using the Linux kernel are commonly built with the
|
||||
`devpts' filesystem enabled and mounted at `/dev/pts', which
|
||||
manages pseudo-terminal ownership automatically. By using
|
||||
`--enable-pt_chown', you may build `pt_chown' and install it
|
||||
setuid and owned by `root'. The use of `pt_chown' introduces
|
||||
additional security risks to the system and you should enable it
|
||||
only if you understand and accept those risks.
|
||||
|
||||
`--build=BUILD-SYSTEM'
|
||||
`--host=HOST-SYSTEM'
|
||||
These options are for cross-compiling. If you specify both
|
||||
@@ -315,9 +330,9 @@ build the GNU C Library:
|
||||
recommend GNU `make' version 3.79. All earlier versions have
|
||||
severe bugs or lack features.
|
||||
|
||||
* GCC 4.3 or newer, GCC 4.6 recommended
|
||||
* GCC 4.4 or newer, GCC 4.6 recommended
|
||||
|
||||
GCC 4.3 or higher is required; as of this writing, GCC 4.6 is the
|
||||
GCC 4.4 or higher is required; as of this writing, GCC 4.6 is the
|
||||
compiler we advise to use to build the GNU C Library.
|
||||
|
||||
You can use whatever compiler you like to compile programs that use
|
||||
@@ -340,10 +355,11 @@ build the GNU C Library:
|
||||
installation mechanism for the info files is not present or works
|
||||
differently.
|
||||
|
||||
* GNU `awk' 3.0, or higher
|
||||
* GNU `awk' 3.1.2, or higher
|
||||
|
||||
`Awk' is used in several places to generate files. `gawk' 3.0 is
|
||||
known to work.
|
||||
`awk' is used in several places to generate files. Some `gawk'
|
||||
extensions are used, including the `asorti' function, which was
|
||||
introduced in version 3.1.2 of `gawk'.
|
||||
|
||||
* Perl 5
|
||||
|
||||
|
||||
@@ -127,6 +127,9 @@ lib: $(common-objpfx)libc.so
|
||||
|
||||
lib: $(common-objpfx)linkobj/libc.so
|
||||
|
||||
# Do not filter ld.so out of libc.so link.
|
||||
$(common-objpfx)linkobj/libc.so: link-libc-deps = # empty
|
||||
|
||||
$(common-objpfx)linkobj/libc.so: $(elfobjdir)/soinit.os \
|
||||
$(common-objpfx)linkobj/libc_pic.a \
|
||||
$(elfobjdir)/sofini.os \
|
||||
|
||||
@@ -217,14 +217,9 @@ endif
|
||||
# later directory would be chosen over a .c file in an earlier directory,
|
||||
# which does not preserve the desired sysdeps ordering behavior.
|
||||
|
||||
# System-dependent makefiles can put in `inhibit-sysdep-asm' wildcard
|
||||
# patterns matching sysdep directories whose assembly source files should
|
||||
# be suppressed.
|
||||
ifdef inhibit-sysdep-asm
|
||||
define check-inhibit-asm
|
||||
case $$sysdir in $(subst $(empty) ,|,$(inhibit-sysdep-asm))) asm= ;; esac;
|
||||
endef
|
||||
endif
|
||||
# System-dependent makefiles can put in `inhibit-sysdep-asm' regexps
|
||||
# matching sysdep directories whose assembly source files should be
|
||||
# suppressed.
|
||||
|
||||
-include $(common-objpfx)sysd-rules
|
||||
ifneq ($(sysd-rules-sysdirs),$(config-sysdirs))
|
||||
@@ -233,34 +228,16 @@ ifneq ($(sysd-rules-sysdirs),$(config-sysdirs))
|
||||
sysd-rules-force = FORCE
|
||||
FORCE:
|
||||
endif
|
||||
$(common-objpfx)sysd-rules: $(common-objpfx)config.make $(..)Makerules \
|
||||
$(common-objpfx)sysd-rules: $(..)scripts/sysd-rules.awk \
|
||||
$(common-objpfx)config.make $(..)Makerules \
|
||||
$(sysdep-makefiles) $(sysdep-makeconfigs) \
|
||||
$(sysd-rules-force)
|
||||
-@rm -f $@T
|
||||
(echo 'sysd-rules-sysdirs := $(config-sysdirs)'; \
|
||||
for dir in $(config-sysdirs); do \
|
||||
case "$$dir" in \
|
||||
/*) ;; \
|
||||
*) dir="\$$(..)$$dir" ;; \
|
||||
esac; \
|
||||
asm='.S'; \
|
||||
$(check-inhibit-asm) \
|
||||
for o in $(all-object-suffixes); do \
|
||||
set $(subst :, ,$(sysd-rules-patterns)); \
|
||||
while [ $$# -ge 2 ]; do \
|
||||
t=$$1; shift; \
|
||||
d=$$1; shift; \
|
||||
v=$${t%%%}; [ x"$$v" = x ] || v="\$$($${v}CPPFLAGS)"; \
|
||||
for s in $$asm .c; do \
|
||||
echo "\$$(objpfx)$$t$$o: $$dir/$$d$$s \$$(before-compile)"; \
|
||||
echo " \$$(compile-command$$s) $$v"; \
|
||||
done; \
|
||||
done; \
|
||||
done; \
|
||||
echo "\$$(inst_includedir)/%.h: $$dir/%.h \$$(+force)"; \
|
||||
echo " \$$(do-install)"; \
|
||||
done; \
|
||||
echo 'sysd-rules-done = t') > $@T
|
||||
LC_ALL=C $(AWK) -f $< > $@T \
|
||||
-v all_object_suffixes='$(all-object-suffixes)' \
|
||||
-v inhibit_sysdep_asm='$(inhibit-sysdep-asm)' \
|
||||
-v sysd_rules_patterns='$(sysd-rules-patterns)' \
|
||||
-v config_sysdirs='$(config-sysdirs)'
|
||||
mv -f $@T $@
|
||||
|
||||
ifndef sysd-rules-done
|
||||
@@ -432,13 +409,33 @@ map-file = $(firstword $($(@F:.so=-map)) \
|
||||
load-map-file = $(map-file:%=-Wl,--version-script=%)
|
||||
endif
|
||||
|
||||
# Compiler arguments to use to link a shared object with libc and
|
||||
# ld.so. This is intended to be as similar as possible to a default
|
||||
# link with an installed libc.
|
||||
link-libc-args = -Wl,--start-group \
|
||||
$(libc-for-link) \
|
||||
$(common-objpfx)libc_nonshared.a \
|
||||
$(as-needed) $(elfobjdir)/ld.so $(no-as-needed) \
|
||||
-Wl,--end-group
|
||||
|
||||
# The corresponding shared libc to use. This may be modified for a
|
||||
# particular target.
|
||||
libc-for-link = $(common-objpfx)libc.so
|
||||
|
||||
# The corresponding dependencies. As these are used in dependencies,
|
||||
# not just commands, they cannot use target-specific variables so need
|
||||
# to name both possible libc.so objects.
|
||||
link-libc-deps = $(common-objpfx)libc.so $(common-objpfx)linkobj/libc.so \
|
||||
$(common-objpfx)libc_nonshared.a $(elfobjdir)/ld.so
|
||||
|
||||
# Pattern rule to build a shared object from an archive of PIC objects.
|
||||
# This must come after the installation rules so Make doesn't try to
|
||||
# build shared libraries in place from the installed *_pic.a files.
|
||||
# $(LDLIBS-%.so) may contain -l switches to generate run-time dependencies
|
||||
# on other shared objects.
|
||||
lib%.so: lib%_pic.a $(+preinit) $(+postinit) $(+interp)
|
||||
$(build-shlib)
|
||||
# on other shared objects. The linking with libc and ld.so is intended
|
||||
# to be as similar as possible to a default link with an installed libc.
|
||||
lib%.so: lib%_pic.a $(+preinit) $(+postinit) $(+interp) $(link-libc-deps)
|
||||
$(build-shlib) $(link-libc-args)
|
||||
|
||||
define build-shlib-helper
|
||||
$(LINK.o) -shared $(static-libgcc) -Wl,-O1 $(sysdep-LDFLAGS) \
|
||||
@@ -513,17 +510,19 @@ endef
|
||||
# not for shared objects
|
||||
define build-module
|
||||
$(build-module-helper) -o $@ $(shlib-lds-flags) \
|
||||
$(csu-objpfx)abi-note.o $(build-module-objlist)
|
||||
$(csu-objpfx)abi-note.o $(build-module-objlist) $(link-libc-args)
|
||||
endef
|
||||
define build-module-asneeded
|
||||
$(build-module-helper) -o $@ $(shlib-lds-flags) \
|
||||
$(csu-objpfx)abi-note.o \
|
||||
-Wl,--as-needed $(build-module-objlist) -Wl,--no-as-needed
|
||||
-Wl,--as-needed $(build-module-objlist) -Wl,--no-as-needed \
|
||||
$(link-libc-args)
|
||||
endef
|
||||
|
||||
build-module-helper-objlist = \
|
||||
$(patsubst %_pic.a,$(whole-archive) %_pic.a $(no-whole-archive),\
|
||||
$(filter-out %.lds $(map-file) $(+preinit) $(+postinit),$^))
|
||||
$(filter-out %.lds $(map-file) $(+preinit) $(+postinit) \
|
||||
$(link-libc-deps),$^))
|
||||
|
||||
build-module-objlist = $(build-module-helper-objlist) $(LDLIBS-$(@F:%.so=%).so)
|
||||
build-shlib-objlist = $(build-module-helper-objlist) \
|
||||
@@ -566,6 +565,9 @@ generated += libc_pic.opts libc_pic.os.clean
|
||||
libc_pic_clean := .clean
|
||||
endif
|
||||
|
||||
# Do not filter ld.so out of libc.so link.
|
||||
$(common-objpfx)libc.so: link-libc-deps = # empty
|
||||
|
||||
# Use our own special initializer and finalizer files for libc.so.
|
||||
$(common-objpfx)libc.so: $(elfobjdir)/soinit.os \
|
||||
$(common-objpfx)libc_pic.os$(libc_pic_clean) \
|
||||
@@ -621,8 +623,7 @@ include $(patsubst %,$(..)extra-modules.mk,$(modules-names))
|
||||
|
||||
extra-modules-build := $(filter-out $(modules-names-nobuild),$(modules-names))
|
||||
$(extra-modules-build:%=$(objpfx)%.so): $(objpfx)%.so: \
|
||||
$(objpfx)%.os $(shlib-lds) \
|
||||
$(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a
|
||||
$(objpfx)%.os $(shlib-lds) $(link-libs-deps)
|
||||
$(build-module)
|
||||
endif
|
||||
|
||||
|
||||
@@ -9,13 +9,27 @@ Version 2.18
|
||||
|
||||
* The following bugs are resolved with this release:
|
||||
|
||||
10060, 10062, 10357, 11120, 11561, 12723, 13550, 13889, 13951, 13988,
|
||||
14142, 14176, 14200, 14280, 14293, 14317, 14327, 14478, 14496, 14686,
|
||||
14812, 14888, 14920, 14964, 14981, 14982, 14985, 14994, 14996, 15003,
|
||||
15006, 15007, 15020, 15023, 15036, 15054, 15055, 15062, 15078, 15084,
|
||||
15085, 15086, 15160, 15214, 15221, 15232, 15234, 15283, 15285, 15287,
|
||||
15304, 15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337, 15342,
|
||||
15346, 15361, 15366, 15380, 15394, 15405, 15406, 15409.
|
||||
2546, 2560, 5159, 6809, 7006, 10060, 10062, 10283, 10357, 10686, 11120,
|
||||
11561, 12310, 12387, 12492, 12515, 12723, 13550, 13889, 13951, 13988,
|
||||
14142, 14176, 14200, 14256, 14280, 14293, 14317, 14327, 14478, 14496,
|
||||
14582, 14686, 14812, 14888, 14894, 14907, 14908, 14909, 14920, 14952,
|
||||
14964, 14981, 14982, 14985, 14991, 14994, 14996, 15000, 15003, 15006,
|
||||
15007, 15014, 15020, 15022, 15023, 15036, 15054, 15055, 15062, 15078,
|
||||
15084, 15085, 15086, 15100, 15160, 15214, 15221, 15232, 15234, 15283,
|
||||
15285, 15287, 15304, 15305, 15307, 15309, 15327, 15330, 15335, 15336,
|
||||
15337, 15339, 15342, 15346, 15359, 15361, 15366, 15380, 15381, 15394,
|
||||
15395, 15405, 15406, 15409, 15416, 15418, 15419, 15423, 15424, 15426,
|
||||
15429, 15431, 15432, 15441, 15442, 15448, 15465, 15480, 15485, 15488,
|
||||
15490, 15492, 15493, 15497, 15506, 15529, 15536, 15553, 15577, 15583,
|
||||
15618, 15627, 15631, 15654, 15655, 15666, 15667, 15674, 15711, 15755,
|
||||
15759.
|
||||
|
||||
* CVE-2013-2207 Incorrectly granting access to another user's pseudo-terminal
|
||||
has been fixed by disabling the use of pt_chown (Bugzilla #15755).
|
||||
Distributions can re-enable building and using pt_chown via the new configure
|
||||
option `--enable-pt_chown'. Enabling the use of pt_chown carries with it
|
||||
considerable security risks and should only be used if the distribution
|
||||
understands and accepts the risks.
|
||||
|
||||
* CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
|
||||
#15078).
|
||||
@@ -33,30 +47,63 @@ Version 2.18
|
||||
* Support for priority inherited mutexes in pthread condition variables on
|
||||
non-x86 architectures.
|
||||
|
||||
* Port to Xilinx MicroBlaze contributed by David Holsgrove.
|
||||
|
||||
* Optimized string functions for AArch64. Implemented by Marcus Shawcroft.
|
||||
|
||||
* Optimized string functions for ARM. Implemented by Will Newton and
|
||||
Richard Henderson.
|
||||
|
||||
* Optimized libm functions for SPARC. Implemented by David S. Miller.
|
||||
|
||||
* Support for building more of ARM glibc as Thumb-2 code. Implemented by
|
||||
Richard Henderson.
|
||||
|
||||
* Support for building most of MIPS glibc as MIPS16 code. Implemented by
|
||||
Chung-Lin Tang, Maciej W. Rozycki and Maxim Kuvyrkov.
|
||||
|
||||
* Added a benchmark framework to track performance of functions in glibc.
|
||||
|
||||
* New <math.h> macro named issignaling to check for a signaling NaN (sNaN).
|
||||
It is based on draft TS 18661 and currently enabled as a GNU extension.
|
||||
|
||||
* On Linux, the clock function now uses the clock_gettime system call
|
||||
for improved precision, rather than old times system call.
|
||||
|
||||
* Added new API functions pthread_getattr_default_np and
|
||||
pthread_setattr_default_np to get and set the default pthread
|
||||
attributes of a process.
|
||||
|
||||
* Added support for TSX lock elision for pthread mutexes on i386 and x86-64.
|
||||
This may improve lock scaling of existing programs on TSX capable systems.
|
||||
When the --enable-lock-elision=yes parameter is specified at configure
|
||||
time lock elision will be enabled by default for all PTHREAD_MUTEX_DEFAULT
|
||||
mutexes.
|
||||
|
||||
* Support added for AT_HWCAP2 (to coincide with Linux kernel 3.10
|
||||
availability). Implemented by Ryan S. Arnold.
|
||||
|
||||
* Support added for POWER8 platform. Implemented by Ryan S. Arnold.
|
||||
|
||||
Version 2.17
|
||||
|
||||
* The following bugs are resolved with this release:
|
||||
|
||||
1349, 3439, 3479, 3665, 5044, 5246, 5298, 5400, 6530, 6677, 6778, 6808,
|
||||
9685, 9914, 10014, 10038, 10114, 10631, 10873, 11438, 11607, 11638, 11741,
|
||||
12140, 13013, 13412, 13542, 13601, 13603, 13604, 13629, 13679, 13696,
|
||||
13698, 13717, 13741, 13759, 13761, 13763, 13881, 13939, 13950, 13952,
|
||||
13966, 14042, 14047, 14090, 14150, 14151, 14152, 14154, 14157, 14166,
|
||||
14173, 14195, 14197, 14237, 14246, 14251, 14252, 14283, 14298, 14303,
|
||||
14307, 14328, 14331, 14336, 14337, 14347, 14349, 14368, 14376, 14417,
|
||||
14447, 14459, 14476, 14477, 14501, 14505, 14510, 14516, 14518, 14519,
|
||||
14530, 14532, 14538, 14543, 14544, 14545, 14557, 14562, 14568, 14576,
|
||||
14579, 14583, 14587, 14595, 14602, 14610, 14621, 14638, 14645, 14648,
|
||||
14652, 14660, 14661, 14669, 14672, 14683, 14694, 14716, 14719, 14743,
|
||||
14767, 14783, 14784, 14785, 14793, 14796, 14797, 14801, 14803, 14805,
|
||||
14807, 14811, 14815, 14821, 14822, 14824, 14828, 14831, 14833, 14835,
|
||||
14838, 14856, 14863, 14865, 14866, 14868, 14869, 14871, 14872, 14879,
|
||||
14889, 14893, 14898, 14914.
|
||||
9685, 9914, 10014, 10038, 10114, 10191, 10631, 10873, 11438, 11607, 11638,
|
||||
11741, 12140, 13013, 13412, 13542, 13601, 13603, 13604, 13629, 13679,
|
||||
13696, 13698, 13717, 13741, 13759, 13761, 13763, 13881, 13939, 13950,
|
||||
13952, 13966, 14042, 14047, 14090, 14150, 14151, 14152, 14154, 14157,
|
||||
14166, 14173, 14195, 14197, 14237, 14246, 14251, 14252, 14283, 14298,
|
||||
14303, 14307, 14328, 14331, 14336, 14337, 14347, 14349, 14368, 14376,
|
||||
14417, 14447, 14459, 14476, 14477, 14501, 14505, 14510, 14516, 14518,
|
||||
14519, 14530, 14532, 14538, 14543, 14544, 14545, 14557, 14562, 14568,
|
||||
14576, 14579, 14583, 14587, 14595, 14602, 14610, 14621, 14638, 14645,
|
||||
14648, 14652, 14660, 14661, 14669, 14672, 14683, 14694, 14716, 14719,
|
||||
14743, 14767, 14783, 14784, 14785, 14793, 14796, 14797, 14801, 14803,
|
||||
14805, 14807, 14811, 14815, 14821, 14822, 14824, 14828, 14831, 14833,
|
||||
14835, 14838, 14856, 14863, 14865, 14866, 14868, 14869, 14871, 14872,
|
||||
14879, 14889, 14893, 14898, 14914.
|
||||
|
||||
* Optimization of memcpy for MIPS.
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ libpthread {
|
||||
GLIBC_2.6
|
||||
GLIBC_2.11
|
||||
GLIBC_2.12
|
||||
GLIBC_2.18
|
||||
GLIBC_PRIVATE
|
||||
}
|
||||
libresolv {
|
||||
|
||||
+95
-101
@@ -17,137 +17,122 @@
|
||||
|
||||
|
||||
# Makefile for benchmark tests. The only useful target here is `bench`.
|
||||
|
||||
# Adding a new function `foo`:
|
||||
# ---------------------------
|
||||
|
||||
# - Append the function name to the bench variable
|
||||
|
||||
# - Define foo-ITER with the number of iterations you want to run. Keep it
|
||||
# high enough that the overhead of clock_gettime is only a small fraction of
|
||||
# the total run time of the test. A good idea would be to keep the run time
|
||||
# of each test at around 10 seconds for x86_64. That is just a guideline,
|
||||
# since some scenarios may require higher run times.
|
||||
|
||||
# - Define foo-ARGLIST as a colon separated list of types of the input
|
||||
# arguments. Use `void` if function does not take any inputs. Put in quotes
|
||||
# if the input argument is a pointer, e.g.:
|
||||
|
||||
# malloc-ARGLIST: "void *"
|
||||
|
||||
# - Define foo-RET as the type the function returns. Skip if the function
|
||||
# returns void. One could even skip foo-ARGLIST if the function does not
|
||||
# take any inputs AND the function returns void.
|
||||
|
||||
|
||||
# - Make a file called `foo-inputs` with one input value per line, an input
|
||||
# being a comma separated list of arguments to be passed into the function.
|
||||
# See pow-inputs for an example.
|
||||
# Add benchmark functions in alphabetical order.
|
||||
|
||||
subdir := benchtests
|
||||
bench := exp pow rint sin cos tan atan modf \
|
||||
slowexp slowpow slowsin slowcos slowtan slowatan
|
||||
bench := acos acosh asin asinh atan atanh cos cosh exp log modf pow rint sin \
|
||||
sinh tan tanh
|
||||
|
||||
# exp function fast path: sysdeps/ieee754/dbl-64/e_exp.c
|
||||
exp-ITER = 5e8
|
||||
exp-ARGLIST = double
|
||||
exp-RET = double
|
||||
LDFLAGS-bench-exp = -lm
|
||||
# String function benchmarks.
|
||||
string-bench := bcopy bzero memccpy memchr memcmp memmem memmove mempcpy \
|
||||
memset rawmemchr stpcpy stpncpy strcasecmp strcasestr strcat \
|
||||
strchr strchrnul strcmp strcpy strcspn strlen strncasecmp \
|
||||
strncat strncmp strncpy strnlen strpbrk strrchr strspn strstr \
|
||||
strcpy_chk stpcpy_chk
|
||||
string-bench-ifunc := $(addsuffix -ifunc, $(string-bench))
|
||||
string-bench-all := $(string-bench) $(string-bench-ifunc)
|
||||
|
||||
# pow function fast path: sysdeps/ieee754/dbl-64/e_pow.c
|
||||
pow-ITER = 2e8
|
||||
pow-ARGLIST = double:double
|
||||
pow-RET = double
|
||||
LDFLAGS-bench-pow = -lm
|
||||
benchset := $(string-bench-all)
|
||||
|
||||
rint-ITER = 250000000
|
||||
rint-ARGLIST = double
|
||||
rint-RET = double
|
||||
LDFLAGS-bench-rint = -lm
|
||||
acos-ARGLIST = double
|
||||
acos-RET = double
|
||||
LDFLAGS-bench-acos = -lm
|
||||
|
||||
# exp function slowest path: sysdeps/ieee754/dbl-64/mpexp.c
|
||||
slowexp-ITER = 3e5
|
||||
slowexp-ARGLIST = double
|
||||
slowexp-RET = double
|
||||
slowexp-INCLUDE = slowexp.c
|
||||
LDFLAGS-bench-slowexp = -lm
|
||||
acosh-ARGLIST = double
|
||||
acosh-RET = double
|
||||
LDFLAGS-bench-acosh = -lm
|
||||
|
||||
# sin function fast path: sysdeps/ieee754/dbl-64/s_sin.c
|
||||
sin-ITER = 3e9
|
||||
sin-ARGLIST = double
|
||||
sin-RET = double
|
||||
LDFLAGS-bench-sin = -lm
|
||||
asin-ARGLIST = double
|
||||
asin-RET = double
|
||||
LDFLAGS-bench-asin = -lm
|
||||
|
||||
# cos function fast path: sysdeps/ieee754/dbl-64/s_sin.c
|
||||
cos-ITER = 3e9
|
||||
cos-ARGLIST = double
|
||||
cos-RET = double
|
||||
LDFLAGS-bench-cos = -lm
|
||||
asinh-ARGLIST = double
|
||||
asinh-RET = double
|
||||
LDFLAGS-bench-asinh = -lm
|
||||
|
||||
# tan function fast path: sysdeps/ieee754/dbl-64/s_tan.c
|
||||
tan-ITER = 3e9
|
||||
tan-ARGLIST = double
|
||||
tan-RET = double
|
||||
LDFLAGS-bench-tan = -lm
|
||||
|
||||
# atan function fast path: sysdeps/ieee754/dbl-64/s_atan.c
|
||||
atan-ITER = 6e9
|
||||
atan-ARGLIST = double
|
||||
atan-RET = double
|
||||
LDFLAGS-bench-atan = -lm
|
||||
|
||||
# pow function slowest path: sysdeps/ieee754/dbl-64/slowpow.c
|
||||
slowpow-ITER = 1e5
|
||||
slowpow-ARGLIST = double:double
|
||||
slowpow-RET = double
|
||||
slowpow-INCLUDE = slowpow.c
|
||||
LDFLAGS-bench-slowpow = -lm
|
||||
atanh-ARGLIST = double
|
||||
atanh-RET = double
|
||||
LDFLAGS-bench-atanh = -lm
|
||||
|
||||
# sin function slowest path: sysdeps/ieee754/dbl-64/sincos32.c
|
||||
slowsin-ITER = 3e7
|
||||
slowsin-ARGLIST = double
|
||||
slowsin-RET = double
|
||||
slowsin-INCLUDE = slowsin.c
|
||||
LDFLAGS-bench-slowsin = -lm
|
||||
cos-ARGLIST = double
|
||||
cos-RET = double
|
||||
LDFLAGS-bench-cos = -lm
|
||||
|
||||
# cos function slowest path: sysdeps/ieee754/dbl-64/sincos32.c
|
||||
slowcos-ITER = 3e7
|
||||
slowcos-ARGLIST = double
|
||||
slowcos-RET = double
|
||||
slowcos-INCLUDE = slowcos.c
|
||||
LDFLAGS-bench-slowcos = -lm
|
||||
cosh-ARGLIST = double
|
||||
cosh-RET = double
|
||||
LDFLAGS-bench-cosh = -lm
|
||||
|
||||
# tan function slowest path: sysdeps/ieee754/dbl-64/mptan.c
|
||||
slowtan-ITER = 3e7
|
||||
slowtan-ARGLIST = double
|
||||
slowtan-RET = double
|
||||
slowtan-INCLUDE = slowtan.c
|
||||
LDFLAGS-bench-slowtan = -lm
|
||||
exp-ARGLIST = double
|
||||
exp-RET = double
|
||||
LDFLAGS-bench-exp = -lm
|
||||
|
||||
# atan function slowest path: sysdeps/ieee754/dbl-64/mpatan.c
|
||||
slowatan-ITER = 3e8
|
||||
slowatan-ARGLIST = double
|
||||
slowatan-RET = double
|
||||
slowatan-INCLUDE = slowatan.c
|
||||
LDFLAGS-bench-slowatan = -lm
|
||||
log-ARGLIST = double
|
||||
log-RET = double
|
||||
LDFLAGS-bench-log = -lm
|
||||
|
||||
pow-ARGLIST = double:double
|
||||
pow-RET = double
|
||||
LDFLAGS-bench-pow = -lm
|
||||
|
||||
rint-ARGLIST = double
|
||||
rint-RET = double
|
||||
LDFLAGS-bench-rint = -lm
|
||||
|
||||
sin-ARGLIST = double
|
||||
sin-RET = double
|
||||
LDFLAGS-bench-sin = -lm
|
||||
|
||||
sinh-ARGLIST = double
|
||||
sinh-RET = double
|
||||
LDFLAGS-bench-sinh = -lm
|
||||
|
||||
tan-ARGLIST = double
|
||||
tan-RET = double
|
||||
LDFLAGS-bench-tan = -lm
|
||||
|
||||
tanh-ARGLIST = double
|
||||
tanh-RET = double
|
||||
LDFLAGS-bench-tanh = -lm
|
||||
|
||||
|
||||
|
||||
# Rules to build and execute the benchmarks. Do not put any benchmark
|
||||
# parameters beyond this point.
|
||||
|
||||
# We don't want the benchmark programs to run in parallel since that could
|
||||
# affect their performance.
|
||||
.NOTPARALLEL:
|
||||
|
||||
include ../Makeconfig
|
||||
include ../Rules
|
||||
|
||||
binaries-bench := $(addprefix $(objpfx)bench-,$(bench))
|
||||
binaries-benchset := $(addprefix $(objpfx)bench-,$(benchset))
|
||||
|
||||
# The default duration: 10 seconds.
|
||||
ifndef BENCH_DURATION
|
||||
BENCH_DURATION := 10
|
||||
endif
|
||||
|
||||
CPPFLAGS-nonlib += -DDURATION=$(BENCH_DURATION)
|
||||
|
||||
# Use clock_gettime to measure performance of functions. The default is to use
|
||||
# HP_TIMING if it is available.
|
||||
ifdef USE_CLOCK_GETTIME
|
||||
CPPFLAGS-nonlib += -DUSE_CLOCK_GETTIME
|
||||
endif
|
||||
|
||||
# This makes sure CPPFLAGS-nonlib and CFLAGS-nonlib are passed
|
||||
# for all these modules.
|
||||
cpp-srcs-left := $(binaries-bench:=.c)
|
||||
cpp-srcs-left := $(binaries-benchset:=.c) $(binaries-bench:=.c)
|
||||
lib := nonlib
|
||||
include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
|
||||
|
||||
bench-deps := bench-skeleton.c Makefile
|
||||
bench-deps := bench-skeleton.c bench-timing.h Makefile
|
||||
|
||||
run-bench = $(test-wrapper-env) \
|
||||
GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
|
||||
@@ -155,8 +140,17 @@ run-bench = $(test-wrapper-env) \
|
||||
|
||||
bench-clean:
|
||||
rm -f $(binaries-bench) $(addsuffix .o,$(binaries-bench))
|
||||
rm -f $(binaries-benchset) $(addsuffix .o,$(binaries-benchset))
|
||||
|
||||
bench: $(binaries-bench)
|
||||
bench: bench-set bench-func
|
||||
|
||||
bench-set: $(binaries-benchset)
|
||||
for run in $^; do \
|
||||
echo "Running $${run}"; \
|
||||
$(run-bench) > $${run}.out; \
|
||||
done
|
||||
|
||||
bench-func: $(binaries-bench)
|
||||
{ for run in $^; do \
|
||||
echo "Running $${run}" >&2; \
|
||||
$(run-bench); \
|
||||
@@ -166,7 +160,7 @@ bench: $(binaries-bench)
|
||||
fi; \
|
||||
mv -f $(objpfx)bench.out-tmp $(objpfx)bench.out
|
||||
|
||||
$(binaries-bench): %: %.o \
|
||||
$(binaries-bench) $(binaries-benchset): %: %.o \
|
||||
$(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
|
||||
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
|
||||
$(+link)
|
||||
@@ -176,5 +170,5 @@ $(objpfx)bench-%.c: %-inputs $(bench-deps)
|
||||
cat $($*-INCLUDE); \
|
||||
fi; \
|
||||
$(..)scripts/bench.pl $(patsubst %-inputs,%,$<) \
|
||||
$($*-ITER) $($*-ARGLIST) $($*-RET); } > $@-tmp
|
||||
$($*-ARGLIST) $($*-RET); } > $@-tmp
|
||||
mv -f $@-tmp $@
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
Using the glibc microbenchmark suite
|
||||
====================================
|
||||
|
||||
The glibc microbenchmark suite automatically generates code for specified
|
||||
functions, builds and calls them repeatedly for given inputs to give some
|
||||
basic performance properties of the function.
|
||||
|
||||
Running the benchmark:
|
||||
=====================
|
||||
|
||||
The benchmark can be executed by invoking make as follows:
|
||||
|
||||
$ make bench
|
||||
|
||||
This runs each function for 10 seconds and appends its output to
|
||||
benchtests/bench.out. To ensure that the tests are rebuilt, one could run:
|
||||
|
||||
$ make bench-clean
|
||||
|
||||
The duration of each test can be configured setting the BENCH_DURATION variable
|
||||
in the call to make. One should run `make bench-clean' before changing
|
||||
BENCH_DURATION.
|
||||
|
||||
$ make BENCH_DURATION=1 bench
|
||||
|
||||
The benchmark suite does function call measurements using architecture-specific
|
||||
high precision timing instructions whenever available. When such support is
|
||||
not available, it uses clock_gettime (CLOCK_PROCESS_CPUTIME_ID). One can force
|
||||
the benchmark to use clock_gettime by invoking make as follows:
|
||||
|
||||
$ make USE_CLOCK_GETTIME=1 bench
|
||||
|
||||
Again, one must run `make bench-clean' before changing the measurement method.
|
||||
|
||||
Adding a function to benchtests:
|
||||
===============================
|
||||
|
||||
If the name of the function is `foo', then the following procedure should allow
|
||||
one to add `foo' to the bench tests:
|
||||
|
||||
- Append the function name to the bench variable in the Makefile.
|
||||
|
||||
- Define foo-ARGLIST as a colon separated list of types of the input
|
||||
arguments. Use `void' if function does not take any inputs. Put in quotes
|
||||
if the input argument is a pointer, e.g.:
|
||||
|
||||
malloc-ARGLIST: "void *"
|
||||
|
||||
- Define foo-RET as the type the function returns. Skip if the function
|
||||
returns void. One could even skip foo-ARGLIST if the function does not
|
||||
take any inputs AND the function returns void.
|
||||
|
||||
- Make a file called `foo-inputs` with one input value per line, an input
|
||||
being a comma separated list of arguments to be passed into the function.
|
||||
See pow-inputs for an example.
|
||||
|
||||
The script that parses the -inputs file treats lines beginning with a single
|
||||
`#' as comments. Lines beginning with two hashes `##' are treated specially
|
||||
as `directives'.
|
||||
|
||||
Multiple execution units per function:
|
||||
=====================================
|
||||
|
||||
Some functions have distinct performance characteristics for different input
|
||||
domains and it may be necessary to measure those separately. For example, some
|
||||
math functions perform computations at different levels of precision (64-bit vs
|
||||
240-bit vs 768-bit) and mixing them does not give a very useful picture of the
|
||||
performance of these functions. One could separate inputs for these domains in
|
||||
the same file by using the `name' directive that looks something like this:
|
||||
|
||||
##name: 240bit
|
||||
|
||||
See the pow-inputs file for an example of what such a partitioned input file
|
||||
would look like.
|
||||
|
||||
Benchmark Sets:
|
||||
==============
|
||||
|
||||
In addition to standard benchmarking of functions, one may also generate
|
||||
custom outputs for a set of functions. This is currently used by string
|
||||
function benchmarks where the aim is to compare performance between
|
||||
implementations at various alignments and for various sizes.
|
||||
|
||||
To add a benchset for `foo':
|
||||
|
||||
- Add `foo' to the benchset variable.
|
||||
- Write your bench-foo.c that prints out the measurements to stdout.
|
||||
- On execution, a bench-foo.out is created in $(objpfx) with the contents of
|
||||
stdout.
|
||||
@@ -0,0 +1,7 @@
|
||||
0.5
|
||||
0.1
|
||||
0.2
|
||||
0.3
|
||||
0.4
|
||||
0.8
|
||||
0.7
|
||||
@@ -0,0 +1,5 @@
|
||||
0.1
|
||||
0.2
|
||||
0.3
|
||||
0.4
|
||||
0.5
|
||||
@@ -0,0 +1,7 @@
|
||||
0.5
|
||||
0.1
|
||||
0.2
|
||||
0.3
|
||||
0.4
|
||||
0.8
|
||||
0.7
|
||||
@@ -0,0 +1,5 @@
|
||||
0.1
|
||||
0.2
|
||||
0.3
|
||||
0.4
|
||||
0.5
|
||||
@@ -1,3 +1,9 @@
|
||||
0x1.000000c5cba86p0
|
||||
0x1.000001883003ap0
|
||||
0x1.00000dfb2b674p0
|
||||
# atan slowest path at 768 bits
|
||||
# Implemented in sysdeps/ieee754/dbl-64/mpatan.c
|
||||
## name: 768bits
|
||||
0x1.000000c5cba87p0
|
||||
0x1.000001883003bp0
|
||||
0x1.00000dfb2b675p0
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
0.1
|
||||
0.2
|
||||
0.3
|
||||
0.4
|
||||
0.5
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Define slowcos.
|
||||
/* Measure IFUNC implementations of bcopy function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@@ -16,4 +16,5 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define slowcos cos
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-bcopy.c"
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Define slowatan.
|
||||
/* Measure bcopy functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@@ -16,4 +16,5 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define slowatan atan
|
||||
#define TEST_BCOPY
|
||||
#include "bench-memmove.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of bzero function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-bzero.c"
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Define slowexp.
|
||||
/* Measure bzero functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define slowexp exp
|
||||
#define TEST_BZERO
|
||||
#include "bench-memset.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memccpy function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-memccpy.c"
|
||||
@@ -0,0 +1,169 @@
|
||||
/* Measure memccpy functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "memccpy"
|
||||
#include "bench-string.h"
|
||||
|
||||
void *simple_memccpy (void *, const void *, int, size_t);
|
||||
void *stupid_memccpy (void *, const void *, int, size_t);
|
||||
|
||||
IMPL (stupid_memccpy, 0)
|
||||
IMPL (simple_memccpy, 0)
|
||||
IMPL (memccpy, 1)
|
||||
|
||||
void *
|
||||
simple_memccpy (void *dst, const void *src, int c, size_t n)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dst;
|
||||
|
||||
while (n-- > 0)
|
||||
if ((*d++ = *s++) == (char) c)
|
||||
return d;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
stupid_memccpy (void *dst, const void *src, int c, size_t n)
|
||||
{
|
||||
void *p = memchr (src, c, n);
|
||||
|
||||
if (p != NULL)
|
||||
return mempcpy (dst, src, p - src + 1);
|
||||
|
||||
memcpy (dst, src, n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef void *(*proto_t) (void *, const void *, int c, size_t);
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, void *dst, const void *src, int c, size_t len,
|
||||
size_t n)
|
||||
{
|
||||
void *expect = len > n ? NULL : (char *) dst + len;
|
||||
if (CALL (impl, dst, src, c, n) != expect)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
CALL (impl, dst, src, c, n), expect);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp (dst, src, len > n ? n : len) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s", impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute__ ((unused));
|
||||
hp_timing_t stop __attribute__ ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, c, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, int c, size_t len, size_t n,
|
||||
int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len - 1; ++i)
|
||||
{
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
if (s1[i] == (char) c)
|
||||
--s1[i];
|
||||
}
|
||||
s1[len - 1] = c;
|
||||
for (i = len; i + align1 < page_size && i < len + 64; ++i)
|
||||
s1[i] = 32 + 32 * i % (max_char - 32);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, n %4zd, char %d, alignment %2zd/%2zd:", len, n, c, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, c, len, n);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%28s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, i, 12, 16, 16, 127);
|
||||
do_test (i, i, 23, 16, 16, 255);
|
||||
do_test (i, 2 * i, 28, 16, 16, 127);
|
||||
do_test (2 * i, i, 31, 16, 16, 255);
|
||||
do_test (8 - i, 2 * i, 1, 1 << i, 2 << i, 127);
|
||||
do_test (2 * i, 8 - i, 17, 2 << i, 1 << i, 127);
|
||||
do_test (8 - i, 2 * i, 0, 1 << i, 2 << i, 255);
|
||||
do_test (2 * i, 8 - i, i, 2 << i, 1 << i, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, i, 4 << i, 8 << i, 127);
|
||||
do_test (0, 0, i, 16 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, i, 4 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, i, 16 << i, 8 << i, 127);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memchr function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-memchr.c"
|
||||
@@ -0,0 +1,137 @@
|
||||
/* Measure memchr functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "memchr"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (const char *, int, size_t);
|
||||
char *simple_memchr (const char *, int, size_t);
|
||||
|
||||
IMPL (simple_memchr, 0)
|
||||
IMPL (memchr, 1)
|
||||
|
||||
char *
|
||||
simple_memchr (const char *s, int c, size_t n)
|
||||
{
|
||||
while (n--)
|
||||
if (*s++ == (char) c)
|
||||
return (char *) s - 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res)
|
||||
{
|
||||
char *res = CALL (impl, s, c, n);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
res, exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, c, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len, int seek_char)
|
||||
{
|
||||
size_t i;
|
||||
char *result;
|
||||
|
||||
align &= 7;
|
||||
if (align + len >= page_size)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
buf1[align + i] = 1 + 23 * i % 127;
|
||||
if (buf1[align + i] == seek_char)
|
||||
buf1[align + i] = seek_char + 1;
|
||||
}
|
||||
buf1[align + len] = 0;
|
||||
|
||||
if (pos < len)
|
||||
{
|
||||
buf1[align + pos] = seek_char;
|
||||
buf1[align + len] = -seek_char;
|
||||
result = (char *) (buf1 + align + pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = NULL;
|
||||
buf1[align + len] = seek_char;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd:", pos, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (char *) (buf1 + align), seek_char, len, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 23);
|
||||
do_test (i, 64, 256, 23);
|
||||
do_test (0, 16 << i, 2048, 0);
|
||||
do_test (i, 64, 256, 0);
|
||||
}
|
||||
for (i = 1; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 23);
|
||||
do_test (0, i, i + 1, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memcmp function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-memcmp.c"
|
||||
@@ -0,0 +1,183 @@
|
||||
/* Measure memcmp functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#ifdef WIDE
|
||||
# define TEST_NAME "wmemcmp"
|
||||
#else
|
||||
# define TEST_NAME "memcmp"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
#ifdef WIDE
|
||||
# include <inttypes.h>
|
||||
# include <wchar.h>
|
||||
|
||||
# define MEMCMP wmemcmp
|
||||
# define MEMCPY wmemcpy
|
||||
# define SIMPLE_MEMCMP simple_wmemcmp
|
||||
# define CHAR wchar_t
|
||||
# define UCHAR wchar_t
|
||||
# define CHARBYTES 4
|
||||
# define CHAR__MIN WCHAR_MIN
|
||||
# define CHAR__MAX WCHAR_MAX
|
||||
int
|
||||
simple_wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n)
|
||||
{
|
||||
int ret = 0;
|
||||
/* Warning!
|
||||
wmemcmp has to use SIGNED comparison for elements.
|
||||
memcmp has to use UNSIGNED comparison for elemnts.
|
||||
*/
|
||||
while (n-- && (ret = *s1 < *s2 ? -1 : *s1 == *s2 ? 0 : 1) == 0) {s1++; s2++;}
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
# include <limits.h>
|
||||
|
||||
# define MEMCMP memcmp
|
||||
# define MEMCPY memcpy
|
||||
# define SIMPLE_MEMCMP simple_memcmp
|
||||
# define CHAR char
|
||||
# define MAX_CHAR 255
|
||||
# define UCHAR unsigned char
|
||||
# define CHARBYTES 1
|
||||
# define CHAR__MIN CHAR_MIN
|
||||
# define CHAR__MAX CHAR_MAX
|
||||
|
||||
int
|
||||
simple_memcmp (const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (n-- && (ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) == 0);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef int (*proto_t) (const CHAR *, const CHAR *, size_t);
|
||||
|
||||
IMPL (SIMPLE_MEMCMP, 0)
|
||||
IMPL (MEMCMP, 1)
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t len,
|
||||
int exp_result)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2, len);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, int exp_result)
|
||||
{
|
||||
size_t i;
|
||||
CHAR *s1, *s2;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
align1 &= 63;
|
||||
if (align1 + (len + 1) * CHARBYTES >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 63;
|
||||
if (align2 + (len + 1) * CHARBYTES >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (CHAR *) (buf1 + align1);
|
||||
s2 = (CHAR *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % CHAR__MAX;
|
||||
|
||||
s1[len] = align1;
|
||||
s2[len] = align2;
|
||||
s2[len - 1] -= exp_result;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, len, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 16; ++i)
|
||||
{
|
||||
do_test (i * CHARBYTES, i * CHARBYTES, i, 0);
|
||||
do_test (i * CHARBYTES, i * CHARBYTES, i, 1);
|
||||
do_test (i * CHARBYTES, i * CHARBYTES, i, -1);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, 0);
|
||||
do_test (0, 0, i, 1);
|
||||
do_test (0, 0, i, -1);
|
||||
}
|
||||
|
||||
for (i = 1; i < 10; ++i)
|
||||
{
|
||||
do_test (0, 0, 2 << i, 0);
|
||||
do_test (0, 0, 2 << i, 1);
|
||||
do_test (0, 0, 2 << i, -1);
|
||||
do_test (0, 0, 16 << i, 0);
|
||||
do_test ((8 - i) * CHARBYTES, (2 * i) * CHARBYTES, 16 << i, 0);
|
||||
do_test (0, 0, 16 << i, 1);
|
||||
do_test (0, 0, 16 << i, -1);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 0);
|
||||
do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 1);
|
||||
do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, -1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memcpy function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-memcpy.c"
|
||||
@@ -0,0 +1,163 @@
|
||||
/* Measure memcpy functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef MEMCPY_RESULT
|
||||
# define MEMCPY_RESULT(dst, len) dst
|
||||
# define MIN_PAGE_SIZE 131072
|
||||
# define TEST_MAIN
|
||||
# define TEST_NAME "memcpy"
|
||||
# include "bench-string.h"
|
||||
|
||||
char *simple_memcpy (char *, const char *, size_t);
|
||||
char *builtin_memcpy (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_memcpy, 0)
|
||||
IMPL (builtin_memcpy, 0)
|
||||
IMPL (memcpy, 1)
|
||||
|
||||
char *
|
||||
simple_memcpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
char *ret = dst;
|
||||
while (n--)
|
||||
*dst++ = *src++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
builtin_memcpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
return __builtin_memcpy (dst, src, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef char *(*proto_t) (char *, const char *, size_t);
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, const char *src,
|
||||
size_t len)
|
||||
{
|
||||
if (CALL (impl, dst, src, len) != MEMCPY_RESULT (dst, len))
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
CALL (impl, dst, src, len), MEMCPY_RESULT (dst, len));
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp (dst, src, len) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, len);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len)
|
||||
{
|
||||
size_t i, j;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 63;
|
||||
if (align1 + len >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 63;
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0, j = 1; i < len; i++, j += 23)
|
||||
s1[i] = j;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 18; ++i)
|
||||
{
|
||||
do_test (0, 0, 1 << i);
|
||||
do_test (i, 0, 1 << i);
|
||||
do_test (0, i, 1 << i);
|
||||
do_test (i, i, 1 << i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, 0, i);
|
||||
do_test (i, 0, i);
|
||||
do_test (0, i, i);
|
||||
do_test (i, i, i);
|
||||
}
|
||||
|
||||
for (i = 3; i < 32; ++i)
|
||||
{
|
||||
if ((i & (i - 1)) == 0)
|
||||
continue;
|
||||
do_test (0, 0, 16 * i);
|
||||
do_test (i, 0, 16 * i);
|
||||
do_test (0, i, 16 * i);
|
||||
do_test (i, i, 16 * i);
|
||||
}
|
||||
|
||||
do_test (0, 0, getpagesize ());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memmem function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-memmem.c"
|
||||
@@ -0,0 +1,172 @@
|
||||
/* Measure memmem functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "memmem"
|
||||
#define BUF1PAGES 20
|
||||
#define ITERATIONS 500
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (const void *, size_t, const void *, size_t);
|
||||
void *simple_memmem (const void *, size_t, const void *, size_t);
|
||||
|
||||
IMPL (simple_memmem, 0)
|
||||
IMPL (memmem, 1)
|
||||
|
||||
void *
|
||||
simple_memmem (const void *haystack, size_t haystack_len, const void *needle,
|
||||
size_t needle_len)
|
||||
{
|
||||
const char *begin;
|
||||
const char *const last_possible
|
||||
= (const char *) haystack + haystack_len - needle_len;
|
||||
|
||||
if (needle_len == 0)
|
||||
/* The first occurrence of the empty string is deemed to occur at
|
||||
the beginning of the string. */
|
||||
return (void *) haystack;
|
||||
|
||||
/* Sanity check, otherwise the loop might search through the whole
|
||||
memory. */
|
||||
if (__builtin_expect (haystack_len < needle_len, 0))
|
||||
return NULL;
|
||||
|
||||
for (begin = (const char *) haystack; begin <= last_possible; ++begin)
|
||||
if (begin[0] == ((const char *) needle)[0] &&
|
||||
!memcmp ((const void *) &begin[1],
|
||||
(const void *) ((const char *) needle + 1),
|
||||
needle_len - 1))
|
||||
return (void *) begin;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const void *haystack, size_t haystack_len,
|
||||
const void *needle, size_t needle_len, const void *expected)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, haystack, haystack_len, needle, needle_len);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (const char *str, size_t len, size_t idx)
|
||||
{
|
||||
char tmpbuf[len];
|
||||
|
||||
memcpy (tmpbuf, buf1 + idx, len);
|
||||
memcpy (buf1 + idx, str, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("String %s, offset %zd:", str, idx);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx);
|
||||
|
||||
memcpy (buf1 + idx, tmpbuf, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
do_random_tests (void)
|
||||
{
|
||||
for (size_t n = 0; n < ITERATIONS; ++n)
|
||||
{
|
||||
char tmpbuf[32];
|
||||
|
||||
size_t shift = random () % 11;
|
||||
size_t rel = random () % ((2 << (shift + 1)) * 64);
|
||||
size_t idx = MIN ((2 << shift) * 64 + rel, BUF1PAGES * page_size - 2);
|
||||
size_t len = random () % (sizeof (tmpbuf) - 1) + 1;
|
||||
len = MIN (len, BUF1PAGES * page_size - idx - 1);
|
||||
memcpy (tmpbuf, buf1 + idx, len);
|
||||
for (size_t i = random () % len / 2 + 1; i > 0; --i)
|
||||
{
|
||||
size_t off = random () % len;
|
||||
char ch = '0' + random () % 10;
|
||||
|
||||
buf1[idx + off] = ch;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("String %.*s, offset %zd:", (int) len, buf1 + idx, idx);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len,
|
||||
buf1 + idx);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
|
||||
memcpy (buf1 + idx, tmpbuf, len);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *const strs[] =
|
||||
{
|
||||
"00000", "00112233", "0123456789", "0000111100001111",
|
||||
"00000111110000022222", "012345678901234567890",
|
||||
"abc0", "aaaa0", "abcabc0"
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < BUF1PAGES * page_size; ++i)
|
||||
buf1[i] = 60 + random () % 32;
|
||||
|
||||
for (i = 0; i < sizeof (strs) / sizeof (strs[0]); ++i)
|
||||
for (size_t j = 0; j < 120; j += 7)
|
||||
{
|
||||
size_t len = strlen (strs[i]);
|
||||
|
||||
do_test (strs[i], len, j);
|
||||
}
|
||||
|
||||
do_random_tests ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memmove function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-memmove.c"
|
||||
@@ -0,0 +1,188 @@
|
||||
/* Measure memmove functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#ifdef TEST_BCOPY
|
||||
# define TEST_NAME "bcopy"
|
||||
#else
|
||||
# define TEST_NAME "memmove"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_memmove (char *, const char *, size_t);
|
||||
|
||||
#ifdef TEST_BCOPY
|
||||
typedef void (*proto_t) (const char *, char *, size_t);
|
||||
void simple_bcopy (const char *, char *, size_t);
|
||||
|
||||
IMPL (simple_bcopy, 0)
|
||||
IMPL (bcopy, 1)
|
||||
|
||||
void
|
||||
simple_bcopy (const char *src, char *dst, size_t n)
|
||||
{
|
||||
simple_memmove (dst, src, n);
|
||||
}
|
||||
#else
|
||||
typedef char *(*proto_t) (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_memmove, 0)
|
||||
IMPL (memmove, 1)
|
||||
#endif
|
||||
|
||||
char *
|
||||
inhibit_loop_to_libcall
|
||||
simple_memmove (char *dst, const char *src, size_t n)
|
||||
{
|
||||
char *ret = dst;
|
||||
if (src < dst)
|
||||
{
|
||||
dst += n;
|
||||
src += n;
|
||||
while (n--)
|
||||
*--dst = *--src;
|
||||
}
|
||||
else
|
||||
while (n--)
|
||||
*dst++ = *src++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src,
|
||||
size_t len)
|
||||
{
|
||||
memcpy (src, orig_src, len);
|
||||
#ifdef TEST_BCOPY
|
||||
CALL (impl, src, dst, len);
|
||||
#else
|
||||
char *res;
|
||||
|
||||
res = CALL (impl, dst, src, len);
|
||||
if (res != dst)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
res, dst);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (memcmp (dst, orig_src, len) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
#ifdef TEST_BCOPY
|
||||
CALL (impl, src, dst, len);
|
||||
#else
|
||||
CALL (impl, dst, src, len);
|
||||
#endif
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len)
|
||||
{
|
||||
size_t i, j;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 63;
|
||||
if (align1 + len >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 63;
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0, j = 1; i < len; i++, j += 23)
|
||||
s1[i] = j;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, (char *) (buf2 + align1), s1, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 14; ++i)
|
||||
{
|
||||
do_test (0, 32, 1 << i);
|
||||
do_test (32, 0, 1 << i);
|
||||
do_test (0, i, 1 << i);
|
||||
do_test (i, 0, 1 << i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, 32, i);
|
||||
do_test (32, 0, i);
|
||||
do_test (0, i, i);
|
||||
do_test (i, 0, i);
|
||||
}
|
||||
|
||||
for (i = 3; i < 32; ++i)
|
||||
{
|
||||
if ((i & (i - 1)) == 0)
|
||||
continue;
|
||||
do_test (0, 32, 16 * i);
|
||||
do_test (32, 0, 16 * i);
|
||||
do_test (0, i, 16 * i);
|
||||
do_test (i, 0, 16 * i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of mempcpy function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-mempcpy.c"
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Measure mempcpy functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define MEMCPY_RESULT(dst, len) (dst) + (len)
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "mempcpy"
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_mempcpy (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_mempcpy, 0)
|
||||
IMPL (mempcpy, 1)
|
||||
|
||||
char *
|
||||
simple_mempcpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
while (n--)
|
||||
*dst++ = *src++;
|
||||
return dst;
|
||||
}
|
||||
|
||||
#include "bench-memcpy.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of memset function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-memset.c"
|
||||
@@ -0,0 +1,170 @@
|
||||
/* Measure memset functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#ifdef TEST_BZERO
|
||||
# define TEST_NAME "bzero"
|
||||
#else
|
||||
# define TEST_NAME "memset"
|
||||
#endif
|
||||
#define MIN_PAGE_SIZE 131072
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_memset (char *, int, size_t);
|
||||
|
||||
#ifdef TEST_BZERO
|
||||
typedef void (*proto_t) (char *, size_t);
|
||||
void simple_bzero (char *, size_t);
|
||||
void builtin_bzero (char *, size_t);
|
||||
|
||||
IMPL (simple_bzero, 0)
|
||||
IMPL (builtin_bzero, 0)
|
||||
IMPL (bzero, 1)
|
||||
|
||||
void
|
||||
simple_bzero (char *s, size_t n)
|
||||
{
|
||||
simple_memset (s, 0, n);
|
||||
}
|
||||
|
||||
void
|
||||
builtin_bzero (char *s, size_t n)
|
||||
{
|
||||
__builtin_bzero (s, n);
|
||||
}
|
||||
#else
|
||||
typedef char *(*proto_t) (char *, int, size_t);
|
||||
char *builtin_memset (char *, int, size_t);
|
||||
|
||||
IMPL (simple_memset, 0)
|
||||
IMPL (builtin_memset, 0)
|
||||
IMPL (memset, 1)
|
||||
|
||||
char *
|
||||
builtin_memset (char *s, int c, size_t n)
|
||||
{
|
||||
return __builtin_memset (s, c, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
char *
|
||||
inhibit_loop_to_libcall
|
||||
simple_memset (char *s, int c, size_t n)
|
||||
{
|
||||
char *r = s, *end = s + n;
|
||||
while (r < end)
|
||||
*r++ = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *s, int c __attribute ((unused)), size_t n)
|
||||
{
|
||||
char tstbuf[n];
|
||||
#ifdef TEST_BZERO
|
||||
simple_bzero (tstbuf, n);
|
||||
CALL (impl, s, n);
|
||||
if (memcmp (s, tstbuf, n) != 0)
|
||||
#else
|
||||
char *res = CALL (impl, s, c, n);
|
||||
if (res != s
|
||||
|| simple_memset (tstbuf, c, n) != tstbuf
|
||||
|| memcmp (s, tstbuf, n) != 0)
|
||||
#endif
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s", impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
#ifdef TEST_BZERO
|
||||
CALL (impl, s, n);
|
||||
#else
|
||||
CALL (impl, s, c, n);
|
||||
#endif
|
||||
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, int c, size_t len)
|
||||
{
|
||||
align &= 7;
|
||||
if (align + len > page_size)
|
||||
return;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (char *) buf1 + align, c, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
int c = 0;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%24s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
#ifndef TEST_BZERO
|
||||
for (c = -65; c <= 130; c += 65)
|
||||
#endif
|
||||
{
|
||||
for (i = 0; i < 18; ++i)
|
||||
do_test (0, c, 1 << i);
|
||||
for (i = 1; i < 32; ++i)
|
||||
{
|
||||
do_test (i, c, i);
|
||||
if (i & (i - 1))
|
||||
do_test (0, c, i);
|
||||
}
|
||||
do_test (1, c, 14);
|
||||
do_test (3, c, 1024);
|
||||
do_test (4, c, 64);
|
||||
do_test (2, c, 25);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
+10
-5
@@ -17,23 +17,28 @@
|
||||
|
||||
extern double modf (double, double *);
|
||||
|
||||
#define CALL_BENCH_FUNC(j, i) modf ( in[j].arg0, &i);
|
||||
#define CALL_BENCH_FUNC(j, i) modf (in[j].arg0, &i);
|
||||
|
||||
struct args
|
||||
{
|
||||
double arg0;
|
||||
volatile double arg0;
|
||||
} in[] =
|
||||
{
|
||||
{ 42.42 },
|
||||
{ -42.42 }
|
||||
};
|
||||
|
||||
#define NUM_SAMPLES (sizeof (in) / sizeof (struct args))
|
||||
#define NUM_VARIANTS 1
|
||||
#define NUM_SAMPLES(v) (sizeof (in) / sizeof (struct args))
|
||||
|
||||
static volatile double ret = 0.0;
|
||||
#define BENCH_FUNC(j) ({double iptr; ret = CALL_BENCH_FUNC (j, iptr);})
|
||||
#define BENCH_FUNC(v, j) \
|
||||
({ \
|
||||
double iptr; \
|
||||
ret = CALL_BENCH_FUNC (j, iptr); \
|
||||
})
|
||||
|
||||
#define ITER 250000000
|
||||
#define FUNCNAME "modf"
|
||||
#define VARIANT(v) FUNCNAME "()"
|
||||
|
||||
#include "bench-skeleton.c"
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of rawmemchr function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-rawmemchr.c"
|
||||
@@ -0,0 +1,133 @@
|
||||
/* Measure memchr functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "rawmemchr"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (const char *, int);
|
||||
char *simple_rawmemchr (const char *, int);
|
||||
|
||||
IMPL (simple_rawmemchr, 0)
|
||||
IMPL (rawmemchr, 1)
|
||||
|
||||
char *
|
||||
simple_rawmemchr (const char *s, int c)
|
||||
{
|
||||
while (1)
|
||||
if (*s++ == (char) c)
|
||||
return (char *) s - 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, int c, char *exp_res)
|
||||
{
|
||||
char *res = CALL (impl, s, c);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
res, exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, c);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len, int seek_char)
|
||||
{
|
||||
size_t i;
|
||||
char *result;
|
||||
|
||||
align &= 7;
|
||||
if (align + len >= page_size)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
buf1[align + i] = 1 + 23 * i % 127;
|
||||
if (buf1[align + i] == seek_char)
|
||||
buf1[align + i] = seek_char + 1;
|
||||
}
|
||||
buf1[align + len] = 0;
|
||||
|
||||
assert (pos < len);
|
||||
|
||||
buf1[align + pos] = seek_char;
|
||||
buf1[align + len] = -seek_char;
|
||||
result = (char *) (buf1 + align + pos);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd:", pos, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (char *) (buf1 + align), seek_char, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 7; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 23);
|
||||
do_test (i, 64, 256, 23);
|
||||
do_test (0, 16 << i, 2048, 0);
|
||||
do_test (i, 64, 256, 0);
|
||||
}
|
||||
for (i = 1; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 23);
|
||||
do_test (0, i, i + 1, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
+68
-33
@@ -21,55 +21,90 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
#include "bench-timing.h"
|
||||
|
||||
volatile unsigned int dontoptimize = 0;
|
||||
|
||||
void
|
||||
startup (void)
|
||||
{
|
||||
/* This loop should cause CPU to switch to maximal freqency.
|
||||
This makes subsequent measurement more accurate. We need a side effect
|
||||
to prevent the loop being deleted by compiler.
|
||||
This should be enough to cause CPU to speed up and it is simpler than
|
||||
running loop for constant time. This is used when user does not have root
|
||||
access to set a constant freqency. */
|
||||
for (int k = 0; k < 10000000; k++)
|
||||
dontoptimize += 23 * dontoptimize + 2;
|
||||
}
|
||||
|
||||
#define TIMESPEC_AFTER(a, b) \
|
||||
(((a).tv_sec == (b).tv_sec) ? \
|
||||
((a).tv_nsec > (b).tv_nsec) : \
|
||||
((a).tv_sec > (b).tv_sec))
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
unsigned long i, j, k;
|
||||
uint64_t total = 0, max = 0, min = 0x7fffffffffffffff;
|
||||
struct timespec start, end;
|
||||
unsigned long i, k;
|
||||
struct timespec runtime;
|
||||
timing_t start, end;
|
||||
|
||||
memset (&start, 0, sizeof (start));
|
||||
memset (&end, 0, sizeof (end));
|
||||
startup();
|
||||
|
||||
clock_getres (CLOCK_PROCESS_CPUTIME_ID, &start);
|
||||
memset (&runtime, 0, sizeof (runtime));
|
||||
|
||||
/* Measure 1000 times the resolution of the clock. So for a 1ns resolution
|
||||
clock, we measure 1000 iterations of the function call at a time.
|
||||
Measurements close to the minimum clock resolution won't make much sense,
|
||||
but it's better than having nothing at all. */
|
||||
unsigned long iters = 1000 * start.tv_nsec;
|
||||
unsigned long total_iters = ITER / iters;
|
||||
unsigned long iters;
|
||||
|
||||
for (i = 0; i < NUM_SAMPLES; i++)
|
||||
TIMING_INIT (iters);
|
||||
|
||||
for (int v = 0; v < NUM_VARIANTS; v++)
|
||||
{
|
||||
for (j = 0; j < total_iters; j ++)
|
||||
/* Run for approximately DURATION seconds. */
|
||||
clock_gettime (CLOCK_MONOTONIC_RAW, &runtime);
|
||||
runtime.tv_sec += DURATION;
|
||||
|
||||
double d_total_i = 0;
|
||||
timing_t total = 0, max = 0, min = 0x7fffffffffffffff;
|
||||
while (1)
|
||||
{
|
||||
clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &start);
|
||||
for (k = 0; k < iters; k++)
|
||||
BENCH_FUNC(i);
|
||||
clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &end);
|
||||
for (i = 0; i < NUM_SAMPLES (v); i++)
|
||||
{
|
||||
uint64_t cur;
|
||||
TIMING_NOW (start);
|
||||
for (k = 0; k < iters; k++)
|
||||
BENCH_FUNC (v, i);
|
||||
TIMING_NOW (end);
|
||||
|
||||
uint64_t cur = (end.tv_nsec - start.tv_nsec
|
||||
+ ((end.tv_sec - start.tv_sec)
|
||||
* (uint64_t) 1000000000));
|
||||
TIMING_DIFF (cur, start, end);
|
||||
|
||||
if (cur > max)
|
||||
max = cur;
|
||||
if (cur > max)
|
||||
max = cur;
|
||||
|
||||
if (cur < min)
|
||||
min = cur;
|
||||
if (cur < min)
|
||||
min = cur;
|
||||
|
||||
total += cur;
|
||||
TIMING_ACCUM (total, cur);
|
||||
|
||||
d_total_i += iters;
|
||||
}
|
||||
struct timespec curtime;
|
||||
|
||||
memset (&curtime, 0, sizeof (curtime));
|
||||
clock_gettime (CLOCK_MONOTONIC_RAW, &curtime);
|
||||
if (TIMESPEC_AFTER (curtime, runtime))
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
double d_total_s = total * 1e-9;
|
||||
double d_iters = iters;
|
||||
double d_total_i = (double)ITER * NUM_SAMPLES;
|
||||
printf (FUNCNAME ": ITERS:%g: TOTAL:%gs, MAX:%gns, MIN:%gns, %g iter/s\n",
|
||||
d_total_i, d_total_s, max / d_iters, min / d_iters,
|
||||
d_total_i / d_total_s);
|
||||
double d_total_s;
|
||||
double d_iters;
|
||||
|
||||
done:
|
||||
d_total_s = total;
|
||||
d_iters = iters;
|
||||
|
||||
TIMING_PRINT_STATS (VARIANT (v), d_total_s, d_iters, d_total_i, max,
|
||||
min);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of stpcpy function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-stpcpy.c"
|
||||
@@ -0,0 +1,36 @@
|
||||
/* Measure stpcpy functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define STRCPY_RESULT(dst, len) ((dst) + (len))
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "stpcpy"
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_stpcpy (char *, const char *);
|
||||
|
||||
IMPL (simple_stpcpy, 0)
|
||||
IMPL (stpcpy, 1)
|
||||
|
||||
char *
|
||||
simple_stpcpy (char *dst, const char *src)
|
||||
{
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return dst - 1;
|
||||
}
|
||||
|
||||
#include "bench-strcpy.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of stpcpy checking function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-stpcpy_chk.c"
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Measure stpcpy checking functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define STRCPY_RESULT(dst, len) ((dst) + (len))
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "stpcpy_chk"
|
||||
#include "bench-string.h"
|
||||
|
||||
extern void __attribute__ ((noreturn)) __chk_fail (void);
|
||||
char *simple_stpcpy_chk (char *, const char *, size_t);
|
||||
extern char *normal_stpcpy (char *, const char *, size_t)
|
||||
__asm ("stpcpy");
|
||||
extern char *__stpcpy_chk (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_stpcpy_chk, 0)
|
||||
IMPL (normal_stpcpy, 1)
|
||||
IMPL (__stpcpy_chk, 2)
|
||||
|
||||
char *
|
||||
simple_stpcpy_chk (char *dst, const char *src, size_t len)
|
||||
{
|
||||
if (! len)
|
||||
__chk_fail ();
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
if (--len == 0)
|
||||
__chk_fail ();
|
||||
return dst - 1;
|
||||
}
|
||||
|
||||
#include "bench-strcpy_chk.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of stpncpy function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-stpncpy.c"
|
||||
@@ -0,0 +1,59 @@
|
||||
/* Measure stpncpy functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define STRNCPY_RESULT(dst, len, n) ((dst) + ((len) > (n) ? (n) : (len)))
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "stpncpy"
|
||||
#include "bench-string.h"
|
||||
|
||||
char *simple_stpncpy (char *, const char *, size_t);
|
||||
char *stupid_stpncpy (char *, const char *, size_t);
|
||||
|
||||
IMPL (stupid_stpncpy, 0)
|
||||
IMPL (simple_stpncpy, 0)
|
||||
IMPL (stpncpy, 1)
|
||||
|
||||
char *
|
||||
simple_stpncpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
while (n--)
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
dst[i] = '\0';
|
||||
return dst - 1;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *
|
||||
stupid_stpncpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
size_t nc = strnlen (src, n);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nc; ++i)
|
||||
dst[i] = src[i];
|
||||
for (; i < n; ++i)
|
||||
dst[i] = '\0';
|
||||
return dst + nc;
|
||||
}
|
||||
|
||||
#include "bench-strncpy.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcasecmp function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strcasecmp.c"
|
||||
@@ -0,0 +1,183 @@
|
||||
/* Measure strcasecmp functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <ctype.h>
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strcasecmp"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef int (*proto_t) (const char *, const char *);
|
||||
static int simple_strcasecmp (const char *, const char *);
|
||||
static int stupid_strcasecmp (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strcasecmp, 0)
|
||||
IMPL (simple_strcasecmp, 0)
|
||||
IMPL (strcasecmp, 1)
|
||||
|
||||
static int
|
||||
simple_strcasecmp (const char *s1, const char *s2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
while ((ret = ((unsigned char) tolower (*s1)
|
||||
- (unsigned char) tolower (*s2))) == 0
|
||||
&& *s1++)
|
||||
++s2;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
stupid_strcasecmp (const char *s1, const char *s2)
|
||||
{
|
||||
size_t ns1 = strlen (s1) + 1, ns2 = strlen (s2) + 1;
|
||||
size_t n = ns1 < ns2 ? ns1 : ns2;
|
||||
int ret = 0;
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if ((ret = ((unsigned char) tolower (*s1)
|
||||
- (unsigned char) tolower (*s2))) != 0)
|
||||
break;
|
||||
++s1;
|
||||
++s2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result)
|
||||
{
|
||||
int result = CALL (impl, s1, s2);
|
||||
if ((exp_result == 0 && result != 0)
|
||||
|| (exp_result < 0 && result >= 0)
|
||||
|| (exp_result > 0 && result <= 0))
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %d %d", impl->name,
|
||||
result, exp_result);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, int max_char,
|
||||
int exp_result)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len + 1 >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len + 1 >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
s1[i] = toupper (1 + 23 * i % max_char);
|
||||
s2[i] = tolower (s1[i]);
|
||||
}
|
||||
|
||||
s1[len] = s2[len] = 0;
|
||||
s1[len + 1] = 23;
|
||||
s2[len + 1] = 24 + exp_result;
|
||||
if ((s2[len - 1] == 'z' && exp_result == -1)
|
||||
|| (s2[len - 1] == 'a' && exp_result == 1))
|
||||
s1[len - 1] += exp_result;
|
||||
else
|
||||
s2[len - 1] -= exp_result;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 16; ++i)
|
||||
{
|
||||
do_test (i, i, i, 127, 0);
|
||||
do_test (i, i, i, 127, 1);
|
||||
do_test (i, i, i, 127, -1);
|
||||
}
|
||||
|
||||
for (i = 1; i < 10; ++i)
|
||||
{
|
||||
do_test (0, 0, 2 << i, 127, 0);
|
||||
do_test (0, 0, 2 << i, 254, 0);
|
||||
do_test (0, 0, 2 << i, 127, 1);
|
||||
do_test (0, 0, 2 << i, 254, 1);
|
||||
do_test (0, 0, 2 << i, 127, -1);
|
||||
do_test (0, 0, 2 << i, 254, -1);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, 8 << i, 127, 0);
|
||||
do_test (2 * i, i, 8 << i, 254, 0);
|
||||
do_test (i, 2 * i, 8 << i, 127, 1);
|
||||
do_test (2 * i, i, 8 << i, 254, 1);
|
||||
do_test (i, 2 * i, 8 << i, 127, -1);
|
||||
do_test (2 * i, i, 8 << i, 254, -1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcasestr function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strcasestr.c"
|
||||
@@ -0,0 +1,186 @@
|
||||
/* Measure strcasestr functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strcasestr"
|
||||
#include "bench-string.h"
|
||||
|
||||
|
||||
#define STRCASESTR simple_strcasestr
|
||||
#define NO_ALIAS
|
||||
#define __strncasecmp strncasecmp
|
||||
#include "../string/strcasestr.c"
|
||||
|
||||
|
||||
static char *
|
||||
stupid_strcasestr (const char *s1, const char *s2)
|
||||
{
|
||||
ssize_t s1len = strlen (s1);
|
||||
ssize_t s2len = strlen (s2);
|
||||
|
||||
if (s2len > s1len)
|
||||
return NULL;
|
||||
|
||||
for (ssize_t i = 0; i <= s1len - s2len; ++i)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < s2len; ++j)
|
||||
if (tolower (s1[i + j]) != tolower (s2[j]))
|
||||
break;
|
||||
if (j == s2len)
|
||||
return (char *) s1 + i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
typedef char *(*proto_t) (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strcasestr, 0)
|
||||
IMPL (simple_strcasestr, 0)
|
||||
IMPL (strcasestr, 1)
|
||||
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~(hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len1, size_t len2,
|
||||
int fail)
|
||||
{
|
||||
char *s1 = (char *) (buf1 + align1);
|
||||
char *s2 = (char *) (buf2 + align2);
|
||||
|
||||
static const char d[] = "1234567890abcxyz";
|
||||
#define dl (sizeof (d) - 1)
|
||||
char *ss2 = s2;
|
||||
for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
|
||||
{
|
||||
size_t t = l > dl ? dl : l;
|
||||
ss2 = mempcpy (ss2, d, t);
|
||||
}
|
||||
s2[len2] = '\0';
|
||||
|
||||
if (fail)
|
||||
{
|
||||
char *ss1 = s1;
|
||||
for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
|
||||
{
|
||||
size_t t = l > dl ? dl : l;
|
||||
memcpy (ss1, d, t);
|
||||
++ss1[len2 > 7 ? 7 : len2 - 1];
|
||||
ss1 += t;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (s1, '0', len1);
|
||||
for (size_t i = 0; i < len2; ++i)
|
||||
s1[len1 - len2 + i] = toupper (s2[i]);
|
||||
}
|
||||
s1[len1] = '\0';
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:",
|
||||
len1, len2, align1, align2, fail ? "fail" : "found");
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static int
|
||||
test_main (void)
|
||||
{
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (size_t klen = 2; klen < 32; ++klen)
|
||||
for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
|
||||
{
|
||||
do_test (0, 0, hlen, klen, 0);
|
||||
do_test (0, 0, hlen, klen, 1);
|
||||
do_test (0, 3, hlen, klen, 0);
|
||||
do_test (0, 3, hlen, klen, 1);
|
||||
do_test (0, 9, hlen, klen, 0);
|
||||
do_test (0, 9, hlen, klen, 1);
|
||||
do_test (0, 15, hlen, klen, 0);
|
||||
do_test (0, 15, hlen, klen, 1);
|
||||
|
||||
do_test (3, 0, hlen, klen, 0);
|
||||
do_test (3, 0, hlen, klen, 1);
|
||||
do_test (3, 3, hlen, klen, 0);
|
||||
do_test (3, 3, hlen, klen, 1);
|
||||
do_test (3, 9, hlen, klen, 0);
|
||||
do_test (3, 9, hlen, klen, 1);
|
||||
do_test (3, 15, hlen, klen, 0);
|
||||
do_test (3, 15, hlen, klen, 1);
|
||||
|
||||
do_test (9, 0, hlen, klen, 0);
|
||||
do_test (9, 0, hlen, klen, 1);
|
||||
do_test (9, 3, hlen, klen, 0);
|
||||
do_test (9, 3, hlen, klen, 1);
|
||||
do_test (9, 9, hlen, klen, 0);
|
||||
do_test (9, 9, hlen, klen, 1);
|
||||
do_test (9, 15, hlen, klen, 0);
|
||||
do_test (9, 15, hlen, klen, 1);
|
||||
|
||||
do_test (15, 0, hlen, klen, 0);
|
||||
do_test (15, 0, hlen, klen, 1);
|
||||
do_test (15, 3, hlen, klen, 0);
|
||||
do_test (15, 3, hlen, klen, 1);
|
||||
do_test (15, 9, hlen, klen, 0);
|
||||
do_test (15, 9, hlen, klen, 1);
|
||||
do_test (15, 15, hlen, klen, 0);
|
||||
do_test (15, 15, hlen, klen, 1);
|
||||
}
|
||||
|
||||
do_test (0, 0, page_size - 1, 16, 0);
|
||||
do_test (0, 0, page_size - 1, 16, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcat function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strcat.c"
|
||||
@@ -0,0 +1,155 @@
|
||||
/* Measure strcat functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strcat"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (char *, const char *);
|
||||
char *simple_strcat (char *, const char *);
|
||||
|
||||
IMPL (simple_strcat, 0)
|
||||
IMPL (strcat, 1)
|
||||
|
||||
char *
|
||||
simple_strcat (char *dst, const char *src)
|
||||
{
|
||||
char *ret = dst;
|
||||
while (*dst++ != '\0');
|
||||
--dst;
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, const char *src)
|
||||
{
|
||||
size_t k = strlen (dst);
|
||||
if (CALL (impl, dst, src) != dst)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
CALL (impl, dst, src), dst);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp (dst + k, src) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
dst[k] = '\0';
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len1, size_t len2, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len1 >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len1 + len2 >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len1; ++i)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len1] = '\0';
|
||||
|
||||
for (i = 0; i < len2; i++)
|
||||
s2[i] = 32 + 23 * i % (max_char - 32);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len1, len2, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
{
|
||||
s2[len2] = '\0';
|
||||
do_one_test (impl, s2, s1);
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%28s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i, 127);
|
||||
do_test (0, 0, i, i, 255);
|
||||
do_test (0, i, i, i, 127);
|
||||
do_test (i, 0, i, i, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, 8 << i, 8 << i, 127);
|
||||
do_test (0, 0, 8 << i, 2 << i, 127);
|
||||
do_test (8 - i, 2 * i, 8 << i, 2 << i, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, 8 << i, 1, 127);
|
||||
do_test (2 * i, i, 8 << i, 1, 255);
|
||||
do_test (i, i, 8 << i, 10, 127);
|
||||
do_test (i, i, 8 << i, 10, 255);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strchr function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strchr.c"
|
||||
@@ -0,0 +1,206 @@
|
||||
/* Measure STRCHR functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#ifndef WIDE
|
||||
# ifdef USE_FOR_STRCHRNUL
|
||||
# define TEST_NAME "strchrnul"
|
||||
# else
|
||||
# define TEST_NAME "strchr"
|
||||
# endif
|
||||
#else
|
||||
# define TEST_NAME "wcschr"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
|
||||
#ifndef WIDE
|
||||
# ifdef USE_FOR_STRCHRNUL
|
||||
# define STRCHR strchrnul
|
||||
# define stupid_STRCHR stupid_STRCHRNUL
|
||||
# define simple_STRCHR simple_STRCHRNUL
|
||||
# else
|
||||
# define STRCHR strchr
|
||||
# endif
|
||||
# define STRLEN strlen
|
||||
# define CHAR char
|
||||
# define BIG_CHAR CHAR_MAX
|
||||
# define MIDDLE_CHAR 127
|
||||
# define SMALL_CHAR 23
|
||||
# define UCHAR unsigned char
|
||||
#else
|
||||
# include <wchar.h>
|
||||
# define STRCHR wcschr
|
||||
# define STRLEN wcslen
|
||||
# define CHAR wchar_t
|
||||
# define BIG_CHAR WCHAR_MAX
|
||||
# define MIDDLE_CHAR 1121
|
||||
# define SMALL_CHAR 851
|
||||
# define UCHAR wchar_t
|
||||
#endif
|
||||
|
||||
#ifdef USE_FOR_STRCHRNUL
|
||||
# define NULLRET(endptr) endptr
|
||||
#else
|
||||
# define NULLRET(endptr) NULL
|
||||
#endif
|
||||
|
||||
|
||||
typedef CHAR *(*proto_t) (const CHAR *, int);
|
||||
|
||||
CHAR *
|
||||
simple_STRCHR (const CHAR *s, int c)
|
||||
{
|
||||
for (; *s != (CHAR) c; ++s)
|
||||
if (*s == '\0')
|
||||
return NULLRET ((CHAR *) s);
|
||||
return (CHAR *) s;
|
||||
}
|
||||
|
||||
CHAR *
|
||||
stupid_STRCHR (const CHAR *s, int c)
|
||||
{
|
||||
size_t n = STRLEN (s) + 1;
|
||||
|
||||
while (n--)
|
||||
if (*s++ == (CHAR) c)
|
||||
return (CHAR *) s - 1;
|
||||
return NULLRET ((CHAR *) s - 1);
|
||||
}
|
||||
|
||||
IMPL (stupid_STRCHR, 0)
|
||||
IMPL (simple_STRCHR, 0)
|
||||
IMPL (STRCHR, 1)
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, c);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
|
||||
/* For wcschr: align here means align not in bytes,
|
||||
but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
|
||||
len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
|
||||
{
|
||||
size_t i;
|
||||
CHAR *result;
|
||||
CHAR *buf = (CHAR *) buf1;
|
||||
align &= 15;
|
||||
if ((align + len) * sizeof (CHAR) >= page_size)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
buf[align + i] = 32 + 23 * i % max_char;
|
||||
if (buf[align + i] == seek_char)
|
||||
buf[align + i] = seek_char + 1;
|
||||
else if (buf[align + i] == 0)
|
||||
buf[align + i] = 1;
|
||||
}
|
||||
buf[align + len] = 0;
|
||||
|
||||
if (pos < len)
|
||||
{
|
||||
buf[align + pos] = seek_char;
|
||||
result = buf + align + pos;
|
||||
}
|
||||
else if (seek_char == 0)
|
||||
result = buf + align + len;
|
||||
else
|
||||
result = NULLRET (buf + align + len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment in bytes %2zd:",
|
||||
pos, align * sizeof (CHAR));
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, buf + align, seek_char, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
|
||||
do_test (i, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 64, 256, SMALL_CHAR, MIDDLE_CHAR);
|
||||
do_test (i, 64, 256, SMALL_CHAR, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, SMALL_CHAR, MIDDLE_CHAR);
|
||||
do_test (0, i, i + 1, SMALL_CHAR, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 0, MIDDLE_CHAR);
|
||||
do_test (i, 16 << i, 2048, 0, MIDDLE_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 64, 256, 0, MIDDLE_CHAR);
|
||||
do_test (i, 64, 256, 0, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 0, MIDDLE_CHAR);
|
||||
do_test (0, i, i + 1, 0, BIG_CHAR);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strchrnul function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strchrnul.c"
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Define slowpow.
|
||||
/* Measure strchrnul function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@@ -16,4 +16,5 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define slowpow pow
|
||||
#define USE_FOR_STRCHRNUL 1
|
||||
#include "bench-strchr.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcmp function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strcmp.c"
|
||||
@@ -0,0 +1,247 @@
|
||||
/* Measure strcmp and wcscmp functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#ifdef WIDE
|
||||
# define TEST_NAME "wcscmp"
|
||||
#else
|
||||
# define TEST_NAME "strcmp"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
|
||||
#ifdef WIDE
|
||||
# include <wchar.h>
|
||||
|
||||
# define L(str) L##str
|
||||
# define STRCMP wcscmp
|
||||
# define STRCPY wcscpy
|
||||
# define STRLEN wcslen
|
||||
# define MEMCPY wmemcpy
|
||||
# define SIMPLE_STRCMP simple_wcscmp
|
||||
# define STUPID_STRCMP stupid_wcscmp
|
||||
# define CHAR wchar_t
|
||||
# define UCHAR wchar_t
|
||||
# define CHARBYTES 4
|
||||
# define CHARBYTESLOG 2
|
||||
# define CHARALIGN __alignof__ (CHAR)
|
||||
# define MIDCHAR 0x7fffffff
|
||||
# define LARGECHAR 0xfffffffe
|
||||
# define CHAR__MAX WCHAR_MAX
|
||||
# define CHAR__MIN WCHAR_MIN
|
||||
|
||||
/* Wcscmp uses signed semantics for comparison, not unsigned */
|
||||
/* Avoid using substraction since possible overflow */
|
||||
|
||||
int
|
||||
simple_wcscmp (const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
wchar_t c1, c2;
|
||||
do
|
||||
{
|
||||
c1 = *s1++;
|
||||
c2 = *s2++;
|
||||
if (c2 == L'\0')
|
||||
return c1 - c2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
return c1 < c2 ? -1 : 1;
|
||||
}
|
||||
|
||||
int
|
||||
stupid_wcscmp (const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
size_t ns1 = wcslen (s1) + 1;
|
||||
size_t ns2 = wcslen (s2) + 1;
|
||||
size_t n = ns1 < ns2 ? ns1 : ns2;
|
||||
int ret = 0;
|
||||
|
||||
wchar_t c1, c2;
|
||||
|
||||
while (n--) {
|
||||
c1 = *s1++;
|
||||
c2 = *s2++;
|
||||
if ((ret = c1 < c2 ? -1 : c1 == c2 ? 0 : 1) != 0)
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
# include <limits.h>
|
||||
|
||||
# define L(str) str
|
||||
# define STRCMP strcmp
|
||||
# define STRCPY strcpy
|
||||
# define STRLEN strlen
|
||||
# define MEMCPY memcpy
|
||||
# define SIMPLE_STRCMP simple_strcmp
|
||||
# define STUPID_STRCMP stupid_strcmp
|
||||
# define CHAR char
|
||||
# define UCHAR unsigned char
|
||||
# define CHARBYTES 1
|
||||
# define CHARBYTESLOG 0
|
||||
# define CHARALIGN 1
|
||||
# define MIDCHAR 0x7f
|
||||
# define LARGECHAR 0xfe
|
||||
# define CHAR__MAX CHAR_MAX
|
||||
# define CHAR__MIN CHAR_MIN
|
||||
|
||||
/* Strcmp uses unsigned semantics for comparison. */
|
||||
int
|
||||
simple_strcmp (const char *s1, const char *s2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
while ((ret = *(unsigned char *) s1 - *(unsigned char*) s2++) == 0 && *s1++);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
stupid_strcmp (const char *s1, const char *s2)
|
||||
{
|
||||
size_t ns1 = strlen (s1) + 1;
|
||||
size_t ns2 = strlen (s2) + 1;
|
||||
size_t n = ns1 < ns2 ? ns1 : ns2;
|
||||
int ret = 0;
|
||||
|
||||
while (n--)
|
||||
if ((ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) != 0)
|
||||
break;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef int (*proto_t) (const CHAR *, const CHAR *);
|
||||
|
||||
IMPL (STUPID_STRCMP, 1)
|
||||
IMPL (SIMPLE_STRCMP, 1)
|
||||
IMPL (STRCMP, 1)
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl,
|
||||
const CHAR *s1, const CHAR *s2,
|
||||
int exp_result)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, int max_char,
|
||||
int exp_result)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
CHAR *s1, *s2;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
align1 &= 63;
|
||||
if (align1 + (len + 1) * CHARBYTES >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 63;
|
||||
if (align2 + (len + 1) * CHARBYTES >= page_size)
|
||||
return;
|
||||
|
||||
/* Put them close to the end of page. */
|
||||
i = align1 + CHARBYTES * (len + 2);
|
||||
s1 = (CHAR *) (buf1 + ((page_size - i) / 16 * 16) + align1);
|
||||
i = align2 + CHARBYTES * (len + 2);
|
||||
s2 = (CHAR *) (buf2 + ((page_size - i) / 16 * 16) + align2);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char;
|
||||
|
||||
s1[len] = s2[len] = 0;
|
||||
s1[len + 1] = 23;
|
||||
s2[len + 1] = 24 + exp_result;
|
||||
s2[len - 1] -= exp_result;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 32; ++i)
|
||||
{
|
||||
do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 0);
|
||||
do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 1);
|
||||
do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, -1);
|
||||
}
|
||||
|
||||
for (i = 1; i < 10 + CHARBYTESLOG; ++i)
|
||||
{
|
||||
do_test (0, 0, 2 << i, MIDCHAR, 0);
|
||||
do_test (0, 0, 2 << i, LARGECHAR, 0);
|
||||
do_test (0, 0, 2 << i, MIDCHAR, 1);
|
||||
do_test (0, 0, 2 << i, LARGECHAR, 1);
|
||||
do_test (0, 0, 2 << i, MIDCHAR, -1);
|
||||
do_test (0, 0, 2 << i, LARGECHAR, -1);
|
||||
do_test (0, CHARBYTES * i, 2 << i, MIDCHAR, 1);
|
||||
do_test (CHARBYTES * i, CHARBYTES * (i + 1), 2 << i, LARGECHAR, 1);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 0);
|
||||
do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 0);
|
||||
do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 1);
|
||||
do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 1);
|
||||
do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, -1);
|
||||
do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, -1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcpy function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strcpy.c"
|
||||
@@ -0,0 +1,183 @@
|
||||
/* Measure strcpy functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef WIDE
|
||||
# include <wchar.h>
|
||||
# define CHAR wchar_t
|
||||
# define UCHAR wchar_t
|
||||
# define sfmt "ls"
|
||||
# define BIG_CHAR WCHAR_MAX
|
||||
# define SMALL_CHAR 1273
|
||||
# define STRCMP wcscmp
|
||||
# define MEMCMP wmemcmp
|
||||
# define MEMSET wmemset
|
||||
#else
|
||||
# define CHAR char
|
||||
# define UCHAR unsigned char
|
||||
# define sfmt "s"
|
||||
# define BIG_CHAR CHAR_MAX
|
||||
# define SMALL_CHAR 127
|
||||
# define STRCMP strcmp
|
||||
# define MEMCMP memcmp
|
||||
# define MEMSET memset
|
||||
#endif
|
||||
|
||||
#ifndef STRCPY_RESULT
|
||||
# define STRCPY_RESULT(dst, len) dst
|
||||
# define TEST_MAIN
|
||||
# ifndef WIDE
|
||||
# define TEST_NAME "strcpy"
|
||||
# else
|
||||
# define TEST_NAME "wcscpy"
|
||||
# endif
|
||||
# include "bench-string.h"
|
||||
# ifndef WIDE
|
||||
# define SIMPLE_STRCPY simple_strcpy
|
||||
# define STRCPY strcpy
|
||||
# else
|
||||
# define SIMPLE_STRCPY simple_wcscpy
|
||||
# define STRCPY wcscpy
|
||||
# endif
|
||||
|
||||
CHAR *SIMPLE_STRCPY (CHAR *, const CHAR *);
|
||||
|
||||
IMPL (SIMPLE_STRCPY, 0)
|
||||
IMPL (STRCPY, 1)
|
||||
|
||||
CHAR *
|
||||
SIMPLE_STRCPY (CHAR *dst, const CHAR *src)
|
||||
{
|
||||
CHAR *ret = dst;
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef CHAR *(*proto_t) (CHAR *, const CHAR *);
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, CHAR *dst, const CHAR *src,
|
||||
size_t len __attribute__((unused)))
|
||||
{
|
||||
if (CALL (impl, dst, src) != STRCPY_RESULT (dst, len))
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
CALL (impl, dst, src), STRCPY_RESULT (dst, len));
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (STRCMP (dst, src) != 0)
|
||||
{
|
||||
error (0, 0,
|
||||
"Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));;
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
CHAR *s1, *s2;
|
||||
/* For wcscpy: align1 and align2 here mean alignment not in bytes,
|
||||
but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
|
||||
len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
|
||||
align1 &= 7;
|
||||
if ((align1 + len) * sizeof(CHAR) >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if ((align2 + len) * sizeof(CHAR) >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (CHAR *) (buf1) + align1;
|
||||
s2 = (CHAR *) (buf2) + align2;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len] = 0;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignments in bytes %2zd/%2zd:", len, align1 * sizeof(CHAR), align2 * sizeof(CHAR));
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, SMALL_CHAR);
|
||||
do_test (0, 0, i, BIG_CHAR);
|
||||
do_test (0, i, i, SMALL_CHAR);
|
||||
do_test (i, 0, i, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, SMALL_CHAR);
|
||||
do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, 8 << i, SMALL_CHAR);
|
||||
do_test (2 * i, i, 8 << i, BIG_CHAR);
|
||||
do_test (i, i, 8 << i, SMALL_CHAR);
|
||||
do_test (i, i, 8 << i, BIG_CHAR);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcpy checking function.
|
||||
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strcpy_chk.c"
|
||||
@@ -0,0 +1,262 @@
|
||||
/* Measure __strcpy_chk functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef STRCPY_RESULT
|
||||
# define STRCPY_RESULT(dst, len) dst
|
||||
# define TEST_MAIN
|
||||
# define TEST_NAME "strcpy_chk"
|
||||
# include "bench-string.h"
|
||||
|
||||
/* This test case implicitly tests the availability of the __chk_fail
|
||||
symbol, which is part of the public ABI and may be used
|
||||
externally. */
|
||||
extern void __attribute__ ((noreturn)) __chk_fail (void);
|
||||
char *simple_strcpy_chk (char *, const char *, size_t);
|
||||
extern char *normal_strcpy (char *, const char *, size_t)
|
||||
__asm ("strcpy");
|
||||
extern char *__strcpy_chk (char *, const char *, size_t);
|
||||
|
||||
IMPL (simple_strcpy_chk, 0)
|
||||
IMPL (normal_strcpy, 1)
|
||||
IMPL (__strcpy_chk, 2)
|
||||
|
||||
char *
|
||||
simple_strcpy_chk (char *dst, const char *src, size_t len)
|
||||
{
|
||||
char *ret = dst;
|
||||
if (! len)
|
||||
__chk_fail ();
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
if (--len == 0)
|
||||
__chk_fail ();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
volatile int chk_fail_ok;
|
||||
jmp_buf chk_fail_buf;
|
||||
|
||||
static void
|
||||
handler (int sig)
|
||||
{
|
||||
if (chk_fail_ok)
|
||||
{
|
||||
chk_fail_ok = 0;
|
||||
longjmp (chk_fail_buf, 1);
|
||||
}
|
||||
else
|
||||
_exit (127);
|
||||
}
|
||||
|
||||
typedef char *(*proto_t) (char *, const char *, size_t);
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, const char *src,
|
||||
size_t len, size_t dlen)
|
||||
{
|
||||
char *res;
|
||||
if (dlen <= len)
|
||||
{
|
||||
if (impl->test == 1)
|
||||
return;
|
||||
|
||||
chk_fail_ok = 1;
|
||||
if (setjmp (chk_fail_buf) == 0)
|
||||
{
|
||||
res = CALL (impl, dst, src, dlen);
|
||||
printf ("*** Function %s (%zd; %zd) did not __chk_fail\n",
|
||||
impl->name, len, dlen);
|
||||
chk_fail_ok = 0;
|
||||
ret = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
res = CALL (impl, dst, src, dlen);
|
||||
|
||||
if (res != STRCPY_RESULT (dst, len))
|
||||
{
|
||||
printf ("Wrong result in function %s %p %p\n", impl->name,
|
||||
res, STRCPY_RESULT (dst, len));
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp (dst, src) != 0)
|
||||
{
|
||||
printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n",
|
||||
impl->name, dst, src);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));;
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, dlen);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) buf1 + align1;
|
||||
s2 = (char *) buf2 + align2;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len] = 0;
|
||||
|
||||
if (HP_TIMING_AVAIL && dlen > len)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, len, dlen);
|
||||
|
||||
if (HP_TIMING_AVAIL && dlen > len)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = handler;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
|
||||
sigaction (SIGABRT, &sa, NULL);
|
||||
|
||||
/* Avoid all the buffer overflow messages on stderr. */
|
||||
int fd = open (_PATH_DEVNULL, O_WRONLY);
|
||||
if (fd == -1)
|
||||
close (STDERR_FILENO);
|
||||
else
|
||||
{
|
||||
dup2 (fd, STDERR_FILENO);
|
||||
close (fd);
|
||||
}
|
||||
setenv ("LIBC_FATAL_STDERR_", "1", 1);
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i + 1, 127);
|
||||
do_test (0, 0, i, i + 1, 255);
|
||||
do_test (0, i, i, i + 1, 127);
|
||||
do_test (i, 0, i, i + 1, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, (8 << i) + 1, 127);
|
||||
do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127);
|
||||
do_test (2 * i, i, (8 << i), (8 << i) + 1, 255);
|
||||
do_test (i, i, (8 << i), (8 << i) + 1, 127);
|
||||
do_test (i, i, (8 << i), (8 << i) + 1, 255);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i + 256, 127);
|
||||
do_test (0, 0, i, i + 256, 255);
|
||||
do_test (0, i, i, i + 256, 127);
|
||||
do_test (i, 0, i, i + 256, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, (8 << i) + 256, 127);
|
||||
do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127);
|
||||
do_test (2 * i, i, (8 << i), (8 << i) + 256, 255);
|
||||
do_test (i, i, (8 << i), (8 << i) + 256, 127);
|
||||
do_test (i, i, (8 << i), (8 << i) + 256, 255);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, i, i, 127);
|
||||
do_test (0, 0, i, i + 2, 255);
|
||||
do_test (0, i, i, i + 3, 127);
|
||||
do_test (i, 0, i, i + 4, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, (8 << i) - 15, 127);
|
||||
do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i), (8 << i) + i, 127);
|
||||
do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255);
|
||||
do_test (i, i, (8 << i), (8 << i) + i + 2, 127);
|
||||
do_test (i, i, (8 << i), (8 << i) + i + 3, 255);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strcspn function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strcspn.c"
|
||||
@@ -0,0 +1,59 @@
|
||||
/* Measure strcspn functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define STRPBRK_RESULT(s, pos) (pos)
|
||||
#define RES_TYPE size_t
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strcspn"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef size_t (*proto_t) (const char *, const char *);
|
||||
size_t simple_strcspn (const char *, const char *);
|
||||
size_t stupid_strcspn (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strcspn, 0)
|
||||
IMPL (simple_strcspn, 0)
|
||||
IMPL (strcspn, 1)
|
||||
|
||||
size_t
|
||||
simple_strcspn (const char *s, const char *rej)
|
||||
{
|
||||
const char *r, *str = s;
|
||||
char c;
|
||||
|
||||
while ((c = *s++) != '\0')
|
||||
for (r = rej; *r != '\0'; ++r)
|
||||
if (*r == c)
|
||||
return s - str - 1;
|
||||
return s - str - 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
stupid_strcspn (const char *s, const char *rej)
|
||||
{
|
||||
size_t ns = strlen (s), nrej = strlen (rej);
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0; i < ns; ++i)
|
||||
for (j = 0; j < nrej; ++j)
|
||||
if (s[i] == rej[j])
|
||||
return i;
|
||||
return i;
|
||||
}
|
||||
|
||||
#include "bench-strpbrk.c"
|
||||
@@ -0,0 +1,212 @@
|
||||
/* Measure string and memory functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
void (*fn) (void);
|
||||
long test;
|
||||
} impl_t;
|
||||
extern impl_t __start_impls[], __stop_impls[];
|
||||
|
||||
#define IMPL(name, test) \
|
||||
impl_t tst_ ## name \
|
||||
__attribute__ ((section ("impls"), aligned (sizeof (void *)))) \
|
||||
= { __STRING (name), (void (*) (void))name, test };
|
||||
|
||||
#ifdef TEST_MAIN
|
||||
|
||||
# ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
# endif
|
||||
|
||||
# undef __USE_STRING_INLINES
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sys/param.h>
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
# include <error.h>
|
||||
# include <errno.h>
|
||||
# include <time.h>
|
||||
# include <ifunc-impl-list.h>
|
||||
# define GL(x) _##x
|
||||
# define GLRO(x) _##x
|
||||
# include <hp-timing.h>
|
||||
|
||||
|
||||
# define TEST_FUNCTION test_main ()
|
||||
# define TIMEOUT (4 * 60)
|
||||
# define OPT_ITERATIONS 10000
|
||||
# define OPT_RANDOM 10001
|
||||
# define OPT_SEED 10002
|
||||
|
||||
unsigned char *buf1, *buf2;
|
||||
int ret, do_srandom;
|
||||
unsigned int seed;
|
||||
size_t page_size;
|
||||
|
||||
hp_timing_t _dl_hp_timing_overhead;
|
||||
|
||||
# ifndef ITERATIONS
|
||||
size_t iterations = 100000;
|
||||
# define ITERATIONS_OPTIONS \
|
||||
{ "iterations", required_argument, NULL, OPT_ITERATIONS },
|
||||
# define ITERATIONS_PROCESS \
|
||||
case OPT_ITERATIONS: \
|
||||
iterations = strtoul (optarg, NULL, 0); \
|
||||
break;
|
||||
# define ITERATIONS iterations
|
||||
# else
|
||||
# define ITERATIONS_OPTIONS
|
||||
# define ITERATIONS_PROCESS
|
||||
# endif
|
||||
|
||||
# define CMDLINE_OPTIONS ITERATIONS_OPTIONS \
|
||||
{ "random", no_argument, NULL, OPT_RANDOM }, \
|
||||
{ "seed", required_argument, NULL, OPT_SEED },
|
||||
# define CMDLINE_PROCESS ITERATIONS_PROCESS \
|
||||
case OPT_RANDOM: \
|
||||
{ \
|
||||
int fdr = open ("/dev/urandom", O_RDONLY); \
|
||||
\
|
||||
if (fdr < 0 || read (fdr, &seed, sizeof(seed)) != sizeof (seed)) \
|
||||
seed = time (NULL); \
|
||||
if (fdr >= 0) \
|
||||
close (fdr); \
|
||||
do_srandom = 1; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
case OPT_SEED: \
|
||||
seed = strtoul (optarg, NULL, 0); \
|
||||
do_srandom = 1; \
|
||||
break;
|
||||
|
||||
# define CALL(impl, ...) \
|
||||
(* (proto_t) (impl)->fn) (__VA_ARGS__)
|
||||
|
||||
# if defined TEST_IFUNC && defined TEST_NAME
|
||||
/* Increase size of FUNC_LIST if assert is triggered at run-time. */
|
||||
static struct libc_ifunc_impl func_list[32];
|
||||
static int func_count;
|
||||
static int impl_count = -1;
|
||||
static impl_t *impl_array;
|
||||
|
||||
# define FOR_EACH_IMPL(impl, notall) \
|
||||
impl_t *impl; \
|
||||
int count; \
|
||||
if (impl_count == -1) \
|
||||
{ \
|
||||
impl_count = 0; \
|
||||
if (func_count != 0) \
|
||||
{ \
|
||||
int f; \
|
||||
impl_t *skip = NULL, *a; \
|
||||
for (impl = __start_impls; impl < __stop_impls; ++impl) \
|
||||
if (strcmp (impl->name, TEST_NAME) == 0) \
|
||||
skip = impl; \
|
||||
else \
|
||||
impl_count++; \
|
||||
a = impl_array = malloc ((impl_count + func_count) * \
|
||||
sizeof (impl_t)); \
|
||||
for (impl = __start_impls; impl < __stop_impls; ++impl) \
|
||||
if (impl != skip) \
|
||||
*a++ = *impl; \
|
||||
for (f = 0; f < func_count; f++) \
|
||||
if (func_list[f].usable) \
|
||||
{ \
|
||||
a->name = func_list[f].name; \
|
||||
a->fn = func_list[f].fn; \
|
||||
a->test = 1; \
|
||||
a++; \
|
||||
} \
|
||||
impl_count = a - impl_array; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
impl_count = __stop_impls - __start_impls; \
|
||||
impl_array = __start_impls; \
|
||||
} \
|
||||
} \
|
||||
impl = impl_array; \
|
||||
for (count = 0; count < impl_count; ++count, ++impl) \
|
||||
if (!notall || impl->test)
|
||||
# else /* ! (defined TEST_IFUNC && defined TEST_NAME) */
|
||||
# define FOR_EACH_IMPL(impl, notall) \
|
||||
for (impl_t *impl = __start_impls; impl < __stop_impls; ++impl) \
|
||||
if (!notall || impl->test)
|
||||
# endif /* ! (defined TEST_IFUNC && defined TEST_NAME) */
|
||||
|
||||
# define HP_TIMING_BEST(best_time, start, end) \
|
||||
do \
|
||||
{ \
|
||||
hp_timing_t tmptime; \
|
||||
HP_TIMING_DIFF (tmptime, start + _dl_hp_timing_overhead, end); \
|
||||
if (best_time > tmptime) \
|
||||
best_time = tmptime; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
# ifndef BUF1PAGES
|
||||
# define BUF1PAGES 1
|
||||
# endif
|
||||
|
||||
static void
|
||||
test_init (void)
|
||||
{
|
||||
# if defined TEST_IFUNC && defined TEST_NAME
|
||||
func_count = __libc_ifunc_impl_list (TEST_NAME, func_list,
|
||||
(sizeof func_list
|
||||
/ sizeof func_list[0]));
|
||||
# endif
|
||||
|
||||
page_size = 2 * getpagesize ();
|
||||
# ifdef MIN_PAGE_SIZE
|
||||
if (page_size < MIN_PAGE_SIZE)
|
||||
page_size = MIN_PAGE_SIZE;
|
||||
# endif
|
||||
buf1 = mmap (0, (BUF1PAGES + 1) * page_size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
if (buf1 == MAP_FAILED)
|
||||
error (EXIT_FAILURE, errno, "mmap failed");
|
||||
if (mprotect (buf1 + BUF1PAGES * page_size, page_size, PROT_NONE))
|
||||
error (EXIT_FAILURE, errno, "mprotect failed");
|
||||
buf2 = mmap (0, 2 * page_size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
if (buf2 == MAP_FAILED)
|
||||
error (EXIT_FAILURE, errno, "mmap failed");
|
||||
if (mprotect (buf2 + page_size, page_size, PROT_NONE))
|
||||
error (EXIT_FAILURE, errno, "mprotect failed");
|
||||
HP_TIMING_DIFF_INIT ();
|
||||
if (do_srandom)
|
||||
{
|
||||
printf ("Setting seed to 0x%x\n", seed);
|
||||
srandom (seed);
|
||||
}
|
||||
|
||||
memset (buf1, 0xa5, BUF1PAGES * page_size);
|
||||
memset (buf2, 0x5a, page_size);
|
||||
}
|
||||
|
||||
#endif /* TEST_MAIN */
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strlen function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strlen.c"
|
||||
@@ -0,0 +1,149 @@
|
||||
/* Measure STRLEN functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#ifndef WIDE
|
||||
# define TEST_NAME "strlen"
|
||||
#else
|
||||
# define TEST_NAME "wcslen"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
|
||||
#ifndef WIDE
|
||||
# define STRLEN strlen
|
||||
# define CHAR char
|
||||
# define MAX_CHAR CHAR_MAX
|
||||
#else
|
||||
# include <wchar.h>
|
||||
# define STRLEN wcslen
|
||||
# define CHAR wchar_t
|
||||
# define MAX_CHAR WCHAR_MAX
|
||||
#endif
|
||||
|
||||
typedef size_t (*proto_t) (const CHAR *);
|
||||
|
||||
size_t
|
||||
simple_STRLEN (const CHAR *s)
|
||||
{
|
||||
const CHAR *p;
|
||||
|
||||
for (p = s; *p; ++p);
|
||||
return p - s;
|
||||
}
|
||||
|
||||
#ifndef WIDE
|
||||
size_t
|
||||
builtin_strlen (const CHAR *p)
|
||||
{
|
||||
return __builtin_strlen (p);
|
||||
}
|
||||
IMPL (builtin_strlen, 0)
|
||||
#endif
|
||||
|
||||
IMPL (simple_STRLEN, 0)
|
||||
IMPL (STRLEN, 1)
|
||||
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const CHAR *s, size_t exp_len)
|
||||
{
|
||||
size_t len = CALL (impl, s);
|
||||
if (len != exp_len)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %zd %zd", impl->name,
|
||||
len, exp_len);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
align &= 63;
|
||||
if (align + sizeof(CHAR) * len >= page_size)
|
||||
return;
|
||||
|
||||
CHAR *buf = (CHAR *) (buf1);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
buf[align + i] = 1 + 11111 * i % MAX_CHAR;
|
||||
buf[align + len] = 0;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd:", len, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (CHAR *) (buf + align), len);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
/* Checking with only 4 * N alignments for wcslen, other alignments are wrong for wchar_t type arrays*/
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (sizeof(CHAR) * i, i);
|
||||
do_test (0, i);
|
||||
}
|
||||
|
||||
for (i = 2; i <= 12; ++i)
|
||||
{
|
||||
do_test (0, 1 << i);
|
||||
do_test (sizeof(CHAR) * 7, 1 << i);
|
||||
do_test (sizeof(CHAR) * i, 1 << i);
|
||||
do_test (sizeof(CHAR) * i, (size_t)((1 << i) / 1.5));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strncasecmp function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strncasecmp.c"
|
||||
@@ -0,0 +1,213 @@
|
||||
/* Measure strncasecmp functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <ctype.h>
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strncasecmp"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef int (*proto_t) (const char *, const char *, size_t);
|
||||
static int simple_strncasecmp (const char *, const char *, size_t);
|
||||
static int stupid_strncasecmp (const char *, const char *, size_t);
|
||||
|
||||
IMPL (stupid_strncasecmp, 0)
|
||||
IMPL (simple_strncasecmp, 0)
|
||||
IMPL (strncasecmp, 1)
|
||||
|
||||
static int
|
||||
simple_strncasecmp (const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
while ((ret = ((unsigned char) tolower (*s1)
|
||||
- (unsigned char) tolower (*s2))) == 0
|
||||
&& *s1++)
|
||||
{
|
||||
if (--n == 0)
|
||||
return 0;
|
||||
++s2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
stupid_strncasecmp (const char *s1, const char *s2, size_t max)
|
||||
{
|
||||
size_t ns1 = strlen (s1) + 1;
|
||||
size_t ns2 = strlen (s2) + 1;
|
||||
size_t n = ns1 < ns2 ? ns1 : ns2;
|
||||
if (n > max)
|
||||
n = max;
|
||||
int ret = 0;
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if ((ret = ((unsigned char) tolower (*s1)
|
||||
- (unsigned char) tolower (*s2))) != 0)
|
||||
break;
|
||||
++s1;
|
||||
++s2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
|
||||
int exp_result)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char,
|
||||
int exp_result)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len + 1 >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len + 1 >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
s1[i] = toupper (1 + 23 * i % max_char);
|
||||
s2[i] = tolower (s1[i]);
|
||||
}
|
||||
|
||||
s1[len] = s2[len] = 0;
|
||||
s1[len + 1] = 23;
|
||||
s2[len + 1] = 24 + exp_result;
|
||||
if ((s2[len - 1] == 'z' && exp_result == -1)
|
||||
|| (s2[len - 1] == 'a' && exp_result == 1))
|
||||
s1[len - 1] += exp_result;
|
||||
else
|
||||
s2[len - 1] -= exp_result;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, n, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 16; ++i)
|
||||
{
|
||||
do_test (i, i, i - 1, i, 127, 0);
|
||||
|
||||
do_test (i, i, i, i, 127, 0);
|
||||
do_test (i, i, i, i, 127, 1);
|
||||
do_test (i, i, i, i, 127, -1);
|
||||
|
||||
do_test (i, i, i + 1, i, 127, 0);
|
||||
do_test (i, i, i + 1, i, 127, 1);
|
||||
do_test (i, i, i + 1, i, 127, -1);
|
||||
}
|
||||
|
||||
for (i = 1; i < 10; ++i)
|
||||
{
|
||||
do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0);
|
||||
do_test (0, 0, 2 << i, 2 << i, 254, 0);
|
||||
do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0);
|
||||
|
||||
do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0);
|
||||
|
||||
do_test (0, 0, 2 << i, 2 << i, 127, 1);
|
||||
do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1);
|
||||
|
||||
do_test (0, 0, 2 << i, 2 << i, 254, 1);
|
||||
do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1);
|
||||
|
||||
do_test (0, 0, 2 << i, 2 << i, 127, -1);
|
||||
do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1);
|
||||
|
||||
do_test (0, 0, 2 << i, 2 << i, 254, -1);
|
||||
do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0);
|
||||
do_test (i, 2 * i, 8 << i, 8 << i, 127, 0);
|
||||
do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0);
|
||||
|
||||
do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0);
|
||||
do_test (2 * i, i, 8 << i, 8 << i, 254, 0);
|
||||
do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0);
|
||||
|
||||
do_test (i, 2 * i, 8 << i, 8 << i, 127, 1);
|
||||
do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1);
|
||||
|
||||
do_test (2 * i, i, 8 << i, 8 << i, 254, 1);
|
||||
do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1);
|
||||
|
||||
do_test (i, 2 * i, 8 << i, 8 << i, 127, -1);
|
||||
do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1);
|
||||
|
||||
do_test (2 * i, i, 8 << i, 8 << i, 254, -1);
|
||||
do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strncat function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strncat.c"
|
||||
@@ -0,0 +1,168 @@
|
||||
/* Measure strncat functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strncat"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (char *, const char *, size_t);
|
||||
char *stupid_strncat (char *, const char *, size_t);
|
||||
char *simple_strncat (char *, const char *, size_t);
|
||||
|
||||
IMPL (stupid_strncat, 0)
|
||||
IMPL (strncat, 2)
|
||||
|
||||
char *
|
||||
stupid_strncat (char *dst, const char *src, size_t n)
|
||||
{
|
||||
char *ret = dst;
|
||||
while (*dst++ != '\0');
|
||||
--dst;
|
||||
while (n--)
|
||||
if ( (*dst++ = *src++) == '\0')
|
||||
return ret;
|
||||
*dst = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, const char *src, size_t n)
|
||||
{
|
||||
size_t k = strlen (dst);
|
||||
if (CALL (impl, dst, src, n) != dst)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p != %p", impl->name,
|
||||
CALL (impl, dst, src, n), dst);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t len = strlen (src);
|
||||
if (memcmp (dst + k, src, len + 1 > n ? n : len + 1) != 0)
|
||||
{
|
||||
error (0, 0, "Incorrect cancatination in function %s",
|
||||
impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
if (n < len && dst[k + n] != '\0')
|
||||
{
|
||||
error (0, 0, "There is no zero in the end of output string in %s",
|
||||
impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
dst[k] = '\0';
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len1, size_t len2,
|
||||
size_t n, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len1 >= page_size)
|
||||
return;
|
||||
if (align1 + n > page_size)
|
||||
return;
|
||||
align2 &= 7;
|
||||
if (align2 + len1 + len2 >= page_size)
|
||||
return;
|
||||
if (align2 + len1 + n > page_size)
|
||||
return;
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len1; ++i)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len1] = '\0';
|
||||
|
||||
for (i = 0; i < len2; i++)
|
||||
s2[i] = 32 + 23 * i % (max_char - 32);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd, alignment %2zd/%2zd, N %4zd:",
|
||||
len1, len2, align1, align2, n);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
{
|
||||
s2[len2] = '\0';
|
||||
do_one_test (impl, s2, s1, n);
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
size_t i, n;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%28s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (n = 2; n <= 2048; n*=4)
|
||||
{
|
||||
do_test (0, 2, 2, 2, n, 127);
|
||||
do_test (0, 0, 4, 4, n, 127);
|
||||
do_test (4, 0, 4, 4, n, 255);
|
||||
do_test (0, 0, 8, 8, n, 127);
|
||||
do_test (0, 8, 8, 8, n, 127);
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, 8 << i, n, 127);
|
||||
do_test (8 - i, 2 * i, 8 << i, 8 << i, n, 127);
|
||||
do_test (0, 0, 8 << i, 2 << i, n, 127);
|
||||
do_test (8 - i, 2 * i, 8 << i, 2 << i, n, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 2 * i, 8 << i, 1, n, 127);
|
||||
do_test (2 * i, i, 8 << i, 1, n, 255);
|
||||
do_test (i, i, 8 << i, 10, n, 127);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strncmp function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strncmp.c"
|
||||
@@ -0,0 +1,249 @@
|
||||
/* Measure strncmp functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strncmp"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef int (*proto_t) (const char *, const char *, size_t);
|
||||
int simple_strncmp (const char *, const char *, size_t);
|
||||
int stupid_strncmp (const char *, const char *, size_t);
|
||||
|
||||
IMPL (stupid_strncmp, 0)
|
||||
IMPL (simple_strncmp, 0)
|
||||
IMPL (strncmp, 1)
|
||||
|
||||
int
|
||||
simple_strncmp (const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (n-- && (ret = *(unsigned char *) s1 - * (unsigned char *) s2++) == 0
|
||||
&& *s1++);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
stupid_strncmp (const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
size_t ns1 = strnlen (s1, n) + 1, ns2 = strnlen (s2, n) + 1;
|
||||
int ret = 0;
|
||||
|
||||
n = ns1 < n ? ns1 : n;
|
||||
n = ns2 < n ? ns2 : n;
|
||||
while (n-- && (ret = *(unsigned char *) s1++ - * (unsigned char *) s2++) == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
|
||||
int exp_result)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char,
|
||||
int exp_result)
|
||||
{
|
||||
size_t i, align_n;
|
||||
char *s1, *s2;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
s1 = (char*)(buf1 + page_size);
|
||||
s2 = (char*)(buf2 + page_size);
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd:", len, n);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, n, 0);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
align1 &= 15;
|
||||
align2 &= 15;
|
||||
align_n = (page_size - n) & 15;
|
||||
|
||||
s1 = (char*)(buf1 + page_size - n);
|
||||
s2 = (char*)(buf2 + page_size - n);
|
||||
|
||||
if (align1 < align_n)
|
||||
s1 -= (align_n - align1);
|
||||
|
||||
if (align2 < align_n)
|
||||
s2 -= (align_n - align2);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
s1[i] = s2[i] = 1 + 23 * i % max_char;
|
||||
|
||||
if (len < n)
|
||||
{
|
||||
s1[len] = 0;
|
||||
s2[len] = 0;
|
||||
if (exp_result < 0)
|
||||
s2[len] = 32;
|
||||
else if (exp_result > 0)
|
||||
s1[len] = 64;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, n, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char,
|
||||
int exp_result)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + n + 1 >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + n + 1 >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char*)(buf1 + align1);
|
||||
s2 = (char*)(buf2 + align2);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
s1[i] = s2[i] = 1 + 23 * i % max_char;
|
||||
|
||||
s1[n] = 24 + exp_result;
|
||||
s2[n] = 23;
|
||||
s1[len] = 0;
|
||||
s2[len] = 0;
|
||||
if (exp_result < 0)
|
||||
s2[len] = 32;
|
||||
else if (exp_result > 0)
|
||||
s1[len] = 64;
|
||||
if (len >= n)
|
||||
s2[n - 1] -= exp_result;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (char*)s1, (char*)s2, n, exp_result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i =0; i < 16; ++i)
|
||||
{
|
||||
do_test (0, 0, 8, i, 127, 0);
|
||||
do_test (0, 0, 8, i, 127, -1);
|
||||
do_test (0, 0, 8, i, 127, 1);
|
||||
do_test (i, i, 8, i, 127, 0);
|
||||
do_test (i, i, 8, i, 127, 1);
|
||||
do_test (i, i, 8, i, 127, -1);
|
||||
do_test (i, 2 * i, 8, i, 127, 0);
|
||||
do_test (2 * i, i, 8, i, 127, 1);
|
||||
do_test (i, 3 * i, 8, i, 127, -1);
|
||||
do_test (0, 0, 8, i, 255, 0);
|
||||
do_test (0, 0, 8, i, 255, -1);
|
||||
do_test (0, 0, 8, i, 255, 1);
|
||||
do_test (i, i, 8, i, 255, 0);
|
||||
do_test (i, i, 8, i, 255, 1);
|
||||
do_test (i, i, 8, i, 255, -1);
|
||||
do_test (i, 2 * i, 8, i, 255, 0);
|
||||
do_test (2 * i, i, 8, i, 255, 1);
|
||||
do_test (i, 3 * i, 8, i, 255, -1);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 8 << i, 16 << i, 127, 0);
|
||||
do_test (0, 0, 8 << i, 16 << i, 127, 1);
|
||||
do_test (0, 0, 8 << i, 16 << i, 127, -1);
|
||||
do_test (0, 0, 8 << i, 16 << i, 255, 0);
|
||||
do_test (0, 0, 8 << i, 16 << i, 255, 1);
|
||||
do_test (0, 0, 8 << i, 16 << i, 255, -1);
|
||||
do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 0);
|
||||
do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 1);
|
||||
do_test (2 * i, i, 8 << i, 16 << i, 255, 0);
|
||||
do_test (2 * i, i, 8 << i, 16 << i, 255, 1);
|
||||
}
|
||||
|
||||
do_test_limit (0, 0, 0, 0, 127, 0);
|
||||
do_test_limit (4, 0, 21, 20, 127, 0);
|
||||
do_test_limit (0, 4, 21, 20, 127, 0);
|
||||
do_test_limit (8, 0, 25, 24, 127, 0);
|
||||
do_test_limit (0, 8, 25, 24, 127, 0);
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
do_test_limit (0, 0, 17 - i, 16 - i, 127, 0);
|
||||
do_test_limit (0, 0, 17 - i, 16 - i, 255, 0);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 127, 0);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 127, 1);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 127, -1);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 255, 0);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 255, 1);
|
||||
do_test_limit (0, 0, 15 - i, 16 - i, 255, -1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strncpy function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strncpy.c"
|
||||
@@ -0,0 +1,180 @@
|
||||
/* Measure strncpy functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef STRNCPY_RESULT
|
||||
# define STRNCPY_RESULT(dst, len, n) dst
|
||||
# define TEST_MAIN
|
||||
# define TEST_NAME "strncpy"
|
||||
# include "bench-string.h"
|
||||
|
||||
char *simple_strncpy (char *, const char *, size_t);
|
||||
char *stupid_strncpy (char *, const char *, size_t);
|
||||
|
||||
IMPL (stupid_strncpy, 0)
|
||||
IMPL (simple_strncpy, 0)
|
||||
IMPL (strncpy, 1)
|
||||
|
||||
char *
|
||||
simple_strncpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
char *ret = dst;
|
||||
while (n--)
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
{
|
||||
while (n--)
|
||||
*dst++ = '\0';
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
stupid_strncpy (char *dst, const char *src, size_t n)
|
||||
{
|
||||
size_t nc = strnlen (src, n);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nc; ++i)
|
||||
dst[i] = src[i];
|
||||
for (; i < n; ++i)
|
||||
dst[i] = '\0';
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef char *(*proto_t) (char *, const char *, size_t);
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, char *dst, const char *src, size_t len, size_t n)
|
||||
{
|
||||
if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, len, n))
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
CALL (impl, dst, src, n), dst);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp (dst, src, len > n ? n : len) != 0)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s", impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (n > len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = len; i < n; ++i)
|
||||
if (dst [i] != '\0')
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s", impl->name);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute__ ((unused));
|
||||
hp_timing_t stop __attribute__ ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, dst, src, n);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
char *s1, *s2;
|
||||
|
||||
align1 &= 7;
|
||||
if (align1 + len >= page_size)
|
||||
return;
|
||||
|
||||
align2 &= 7;
|
||||
if (align2 + len >= page_size)
|
||||
return;
|
||||
|
||||
s1 = (char *) (buf1 + align1);
|
||||
s2 = (char *) (buf2 + align2);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
s1[i] = 32 + 23 * i % (max_char - 32);
|
||||
s1[len] = 0;
|
||||
for (i = len + 1; i + align1 < page_size && i < len + 64; ++i)
|
||||
s1[i] = 32 + 32 * i % (max_char - 32);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, n %4zd, alignment %2zd/%2zd:", len, n, align1, align2);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s2, s1, len, n);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%28s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, i, 16, 16, 127);
|
||||
do_test (i, i, 16, 16, 255);
|
||||
do_test (i, 2 * i, 16, 16, 127);
|
||||
do_test (2 * i, i, 16, 16, 255);
|
||||
do_test (8 - i, 2 * i, 1 << i, 2 << i, 127);
|
||||
do_test (2 * i, 8 - i, 2 << i, 1 << i, 127);
|
||||
do_test (8 - i, 2 * i, 1 << i, 2 << i, 255);
|
||||
do_test (2 * i, 8 - i, 2 << i, 1 << i, 255);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 0, 4 << i, 8 << i, 127);
|
||||
do_test (0, 0, 16 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, 4 << i, 8 << i, 127);
|
||||
do_test (8 - i, 2 * i, 16 << i, 8 << i, 127);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strnlen function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strnlen.c"
|
||||
@@ -0,0 +1,139 @@
|
||||
/* Measure strlen functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strnlen"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef size_t (*proto_t) (const char *, size_t);
|
||||
size_t simple_strnlen (const char *, size_t);
|
||||
|
||||
IMPL (simple_strnlen, 0)
|
||||
IMPL (strnlen, 1)
|
||||
|
||||
size_t
|
||||
simple_strnlen (const char *s, size_t maxlen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < maxlen && s[i]; ++i);
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, size_t maxlen, size_t exp_len)
|
||||
{
|
||||
size_t len = CALL (impl, s, maxlen);
|
||||
if (len != exp_len)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %zd %zd", impl->name,
|
||||
len, exp_len);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, maxlen);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t len, size_t maxlen, int max_char)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
align &= 7;
|
||||
if (align + len >= page_size)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
buf1[align + i] = 1 + 7 * i % max_char;
|
||||
buf1[align + len] = 0;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd:", len, align);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (char *) (buf1 + align), maxlen, MIN (len, maxlen));
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, i, i - 1, 127);
|
||||
do_test (0, i, i, 127);
|
||||
do_test (0, i, i + 1, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, i, i - 1, 127);
|
||||
do_test (i, i, i, 127);
|
||||
do_test (i, i, i + 1, 127);
|
||||
}
|
||||
|
||||
for (i = 2; i <= 10; ++i)
|
||||
{
|
||||
do_test (0, 1 << i, 5000, 127);
|
||||
do_test (1, 1 << i, 5000, 127);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
do_test (0, i, 5000, 255);
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
do_test (i, i, 5000, 255);
|
||||
|
||||
for (i = 2; i <= 10; ++i)
|
||||
{
|
||||
do_test (0, 1 << i, 5000, 255);
|
||||
do_test (1, 1 << i, 5000, 255);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strpbrk function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strpbrk.c"
|
||||
@@ -0,0 +1,182 @@
|
||||
/* Measure strpbrk functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef STRPBRK_RESULT
|
||||
# define STRPBRK_RESULT(s, pos) ((s)[(pos)] ? (s) + (pos) : NULL)
|
||||
# define RES_TYPE char *
|
||||
# define TEST_MAIN
|
||||
# define TEST_NAME "strpbrk"
|
||||
# include "bench-string.h"
|
||||
|
||||
typedef char *(*proto_t) (const char *, const char *);
|
||||
char *simple_strpbrk (const char *, const char *);
|
||||
char *stupid_strpbrk (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strpbrk, 0)
|
||||
IMPL (simple_strpbrk, 0)
|
||||
IMPL (strpbrk, 1)
|
||||
|
||||
char *
|
||||
simple_strpbrk (const char *s, const char *rej)
|
||||
{
|
||||
const char *r;
|
||||
char c;
|
||||
|
||||
while ((c = *s++) != '\0')
|
||||
for (r = rej; *r != '\0'; ++r)
|
||||
if (*r == c)
|
||||
return (char *) s - 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
stupid_strpbrk (const char *s, const char *rej)
|
||||
{
|
||||
size_t ns = strlen (s), nrej = strlen (rej);
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0; i < ns; ++i)
|
||||
for (j = 0; j < nrej; ++j)
|
||||
if (s[i] == rej[j])
|
||||
return (char *) s + i;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, const char *rej, RES_TYPE exp_res)
|
||||
{
|
||||
RES_TYPE res = CALL (impl, s, rej);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
(void *) res, (void *) exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, rej);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int c;
|
||||
RES_TYPE result;
|
||||
char *rej, *s;
|
||||
|
||||
align &= 7;
|
||||
if (align + pos + 10 >= page_size || len > 240)
|
||||
return;
|
||||
|
||||
rej = (char *) (buf2 + (random () & 255));
|
||||
s = (char *) (buf1 + align);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
rej[i] = random () & 255;
|
||||
if (!rej[i])
|
||||
rej[i] = random () & 255;
|
||||
if (!rej[i])
|
||||
rej[i] = 1 + (random () & 127);
|
||||
}
|
||||
rej[len] = '\0';
|
||||
for (c = 1; c <= 255; ++c)
|
||||
if (strchr (rej, c) == NULL)
|
||||
break;
|
||||
|
||||
for (i = 0; i < pos; ++i)
|
||||
{
|
||||
s[i] = random () & 255;
|
||||
if (strchr (rej, s[i]))
|
||||
{
|
||||
s[i] = random () & 255;
|
||||
if (strchr (rej, s[i]))
|
||||
s[i] = c;
|
||||
}
|
||||
}
|
||||
s[pos] = rej[random () % (len + 1)];
|
||||
if (s[pos])
|
||||
{
|
||||
for (i = pos + 1; i < pos + 10; ++i)
|
||||
s[i] = random () & 255;
|
||||
s[i] = '\0';
|
||||
}
|
||||
result = STRPBRK_RESULT (s, pos);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd, rej len %2zd:", pos, align, len);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s, rej, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%32s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, 512, i);
|
||||
do_test (i, 512, i);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 4);
|
||||
do_test (i, 16 << i, 4);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
do_test (i, 64, 10);
|
||||
|
||||
for (i = 0; i < 64; ++i)
|
||||
do_test (0, i, 6);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strrchr function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strrchr.c"
|
||||
@@ -0,0 +1,190 @@
|
||||
/* Measure STRCHR functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#ifdef WIDE
|
||||
# define TEST_NAME "wcsrchr"
|
||||
#else
|
||||
# define TEST_NAME "strrchr"
|
||||
#endif
|
||||
#include "bench-string.h"
|
||||
|
||||
#ifdef WIDE
|
||||
# include <wchar.h>
|
||||
# define SIMPLE_STRRCHR simple_wcsrchr
|
||||
# define STRRCHR wcsrchr
|
||||
# define CHAR wchar_t
|
||||
# define UCHAR wchar_t
|
||||
# define BIG_CHAR WCHAR_MAX
|
||||
# define SMALL_CHAR 1273
|
||||
#else
|
||||
# define SIMPLE_STRRCHR simple_strrchr
|
||||
# define STRRCHR strrchr
|
||||
# define CHAR char
|
||||
# define UCHAR unsigned char
|
||||
# define BIG_CHAR CHAR_MAX
|
||||
# define SMALL_CHAR 127
|
||||
#endif
|
||||
|
||||
typedef CHAR *(*proto_t) (const CHAR *, int);
|
||||
CHAR *SIMPLE_STRRCHR (const CHAR *, int);
|
||||
|
||||
IMPL (SIMPLE_STRRCHR, 0)
|
||||
IMPL (STRRCHR, 1)
|
||||
|
||||
CHAR *
|
||||
SIMPLE_STRRCHR (const CHAR *s, int c)
|
||||
{
|
||||
const CHAR *ret = NULL;
|
||||
|
||||
for (; *s != '\0'; ++s)
|
||||
if (*s == (CHAR) c)
|
||||
ret = s;
|
||||
|
||||
return (CHAR *) (c == '\0' ? s : ret);
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const CHAR *s, int c, CHAR *exp_res)
|
||||
{
|
||||
CHAR *res = CALL (impl, s, c);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
res, exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, c);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
|
||||
/* For wcsrchr: align here means align not in bytes,
|
||||
but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
|
||||
len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
|
||||
{
|
||||
size_t i;
|
||||
CHAR *result;
|
||||
CHAR *buf = (CHAR *) buf1;
|
||||
|
||||
align &= 7;
|
||||
if ( (align + len) * sizeof(CHAR) >= page_size)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
buf[align + i] = (random () * random ()) & max_char;
|
||||
if (!buf[align + i])
|
||||
buf[align + i] = (random () * random ()) & max_char;
|
||||
if (!buf[align + i])
|
||||
buf[align + i] = 1;
|
||||
if ((i > pos || pos >= len) && buf[align + i] == seek_char)
|
||||
buf[align + i] = seek_char + 10 + (random () & 15);
|
||||
}
|
||||
buf[align + len] = 0;
|
||||
|
||||
if (pos < len)
|
||||
{
|
||||
buf[align + pos] = seek_char;
|
||||
result = (CHAR *) (buf + align + pos);
|
||||
}
|
||||
else if (seek_char == 0)
|
||||
result = (CHAR *) (buf + align + len);
|
||||
else
|
||||
result = NULL;
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment in bytes %2zd:", pos, align * sizeof(CHAR));
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, (CHAR *) (buf + align), seek_char, result);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%20s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 23, SMALL_CHAR);
|
||||
do_test (i, 16 << i, 2048, 23, SMALL_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 64, 256, 23, SMALL_CHAR);
|
||||
do_test (i, 64, 256, 23, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 23, SMALL_CHAR);
|
||||
do_test (0, i, i + 1, 23, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 2048, 0, SMALL_CHAR);
|
||||
do_test (i, 16 << i, 2048, 0, SMALL_CHAR);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (i, 64, 256, 0, SMALL_CHAR);
|
||||
do_test (i, 64, 256, 0, BIG_CHAR);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, i, i + 1, 0, SMALL_CHAR);
|
||||
do_test (0, i, i + 1, 0, BIG_CHAR);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strspn function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strspn.c"
|
||||
@@ -0,0 +1,174 @@
|
||||
/* Measure strspn functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strspn"
|
||||
#include "bench-string.h"
|
||||
|
||||
typedef size_t (*proto_t) (const char *, const char *);
|
||||
size_t simple_strspn (const char *, const char *);
|
||||
size_t stupid_strspn (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strspn, 0)
|
||||
IMPL (simple_strspn, 0)
|
||||
IMPL (strspn, 1)
|
||||
|
||||
size_t
|
||||
simple_strspn (const char *s, const char *acc)
|
||||
{
|
||||
const char *r, *str = s;
|
||||
char c;
|
||||
|
||||
while ((c = *s++) != '\0')
|
||||
{
|
||||
for (r = acc; *r != '\0'; ++r)
|
||||
if (*r == c)
|
||||
break;
|
||||
if (*r == '\0')
|
||||
return s - str - 1;
|
||||
}
|
||||
return s - str - 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
stupid_strspn (const char *s, const char *acc)
|
||||
{
|
||||
size_t ns = strlen (s), nacc = strlen (acc);
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0; i < ns; ++i)
|
||||
{
|
||||
for (j = 0; j < nacc; ++j)
|
||||
if (s[i] == acc[j])
|
||||
break;
|
||||
if (j == nacc)
|
||||
return i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s, const char *acc, size_t exp_res)
|
||||
{
|
||||
size_t res = CALL (impl, s, acc);
|
||||
if (res != exp_res)
|
||||
{
|
||||
error (0, 0, "Wrong result in function %s %p %p", impl->name,
|
||||
(void *) res, (void *) exp_res);
|
||||
ret = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~ (hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s, acc);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_test (size_t align, size_t pos, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
char *acc, *s;
|
||||
|
||||
align &= 7;
|
||||
if (align + pos + 10 >= page_size || len > 240 || ! len)
|
||||
return;
|
||||
|
||||
acc = (char *) (buf2 + (random () & 255));
|
||||
s = (char *) (buf1 + align);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
acc[i] = random () & 255;
|
||||
if (!acc[i])
|
||||
acc[i] = random () & 255;
|
||||
if (!acc[i])
|
||||
acc[i] = 1 + (random () & 127);
|
||||
}
|
||||
acc[len] = '\0';
|
||||
|
||||
for (i = 0; i < pos; ++i)
|
||||
s[i] = acc[random () % len];
|
||||
s[pos] = random () & 255;
|
||||
if (strchr (acc, s[pos]))
|
||||
s[pos] = '\0';
|
||||
else
|
||||
{
|
||||
for (i = pos + 1; i < pos + 10; ++i)
|
||||
s[i] = random () & 255;
|
||||
s[i] = '\0';
|
||||
}
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd, alignment %2zd, acc len %2zd:", pos, align, len);
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s, acc, pos);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
int
|
||||
test_main (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
test_init ();
|
||||
|
||||
printf ("%32s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
do_test (0, 512, i);
|
||||
do_test (i, 512, i);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
{
|
||||
do_test (0, 16 << i, 4);
|
||||
do_test (i, 16 << i, 4);
|
||||
}
|
||||
|
||||
for (i = 1; i < 8; ++i)
|
||||
do_test (i, 64, 10);
|
||||
|
||||
for (i = 0; i < 64; ++i)
|
||||
do_test (0, i, 6);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Measure IFUNC implementations of strstr function.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_IFUNC 1
|
||||
#include "bench-strstr.c"
|
||||
@@ -0,0 +1,183 @@
|
||||
/* Measure strstr functions.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define TEST_MAIN
|
||||
#define TEST_NAME "strstr"
|
||||
#include "bench-string.h"
|
||||
|
||||
|
||||
#define STRSTR simple_strstr
|
||||
#include "../string/strstr.c"
|
||||
|
||||
|
||||
static char *
|
||||
stupid_strstr (const char *s1, const char *s2)
|
||||
{
|
||||
ssize_t s1len = strlen (s1);
|
||||
ssize_t s2len = strlen (s2);
|
||||
|
||||
if (s2len > s1len)
|
||||
return NULL;
|
||||
|
||||
for (ssize_t i = 0; i <= s1len - s2len; ++i)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < s2len; ++j)
|
||||
if (s1[i + j] != s2[j])
|
||||
break;
|
||||
if (j == s2len)
|
||||
return (char *) s1 + i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
typedef char *(*proto_t) (const char *, const char *);
|
||||
|
||||
IMPL (stupid_strstr, 0)
|
||||
IMPL (simple_strstr, 0)
|
||||
IMPL (strstr, 1)
|
||||
|
||||
|
||||
static void
|
||||
do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
|
||||
{
|
||||
if (HP_TIMING_AVAIL)
|
||||
{
|
||||
hp_timing_t start __attribute ((unused));
|
||||
hp_timing_t stop __attribute ((unused));
|
||||
hp_timing_t best_time = ~(hp_timing_t) 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
HP_TIMING_NOW (start);
|
||||
CALL (impl, s1, s2);
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_BEST (best_time, start, stop);
|
||||
}
|
||||
|
||||
printf ("\t%zd", (size_t) best_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_test (size_t align1, size_t align2, size_t len1, size_t len2,
|
||||
int fail)
|
||||
{
|
||||
char *s1 = (char *) (buf1 + align1);
|
||||
char *s2 = (char *) (buf2 + align2);
|
||||
|
||||
static const char d[] = "1234567890abcdef";
|
||||
#define dl (sizeof (d) - 1)
|
||||
char *ss2 = s2;
|
||||
for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
|
||||
{
|
||||
size_t t = l > dl ? dl : l;
|
||||
ss2 = mempcpy (ss2, d, t);
|
||||
}
|
||||
s2[len2] = '\0';
|
||||
|
||||
if (fail)
|
||||
{
|
||||
char *ss1 = s1;
|
||||
for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
|
||||
{
|
||||
size_t t = l > dl ? dl : l;
|
||||
memcpy (ss1, d, t);
|
||||
++ss1[len2 > 7 ? 7 : len2 - 1];
|
||||
ss1 += t;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (s1, '0', len1);
|
||||
memcpy (s1 + len1 - len2, s2, len2);
|
||||
}
|
||||
s1[len1] = '\0';
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:",
|
||||
len1, len2, align1, align2, fail ? "fail" : "found");
|
||||
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2);
|
||||
|
||||
if (HP_TIMING_AVAIL)
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
static int
|
||||
test_main (void)
|
||||
{
|
||||
test_init ();
|
||||
|
||||
printf ("%23s", "");
|
||||
FOR_EACH_IMPL (impl, 0)
|
||||
printf ("\t%s", impl->name);
|
||||
putchar ('\n');
|
||||
|
||||
for (size_t klen = 2; klen < 32; ++klen)
|
||||
for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
|
||||
{
|
||||
do_test (0, 0, hlen, klen, 0);
|
||||
do_test (0, 0, hlen, klen, 1);
|
||||
do_test (0, 3, hlen, klen, 0);
|
||||
do_test (0, 3, hlen, klen, 1);
|
||||
do_test (0, 9, hlen, klen, 0);
|
||||
do_test (0, 9, hlen, klen, 1);
|
||||
do_test (0, 15, hlen, klen, 0);
|
||||
do_test (0, 15, hlen, klen, 1);
|
||||
|
||||
do_test (3, 0, hlen, klen, 0);
|
||||
do_test (3, 0, hlen, klen, 1);
|
||||
do_test (3, 3, hlen, klen, 0);
|
||||
do_test (3, 3, hlen, klen, 1);
|
||||
do_test (3, 9, hlen, klen, 0);
|
||||
do_test (3, 9, hlen, klen, 1);
|
||||
do_test (3, 15, hlen, klen, 0);
|
||||
do_test (3, 15, hlen, klen, 1);
|
||||
|
||||
do_test (9, 0, hlen, klen, 0);
|
||||
do_test (9, 0, hlen, klen, 1);
|
||||
do_test (9, 3, hlen, klen, 0);
|
||||
do_test (9, 3, hlen, klen, 1);
|
||||
do_test (9, 9, hlen, klen, 0);
|
||||
do_test (9, 9, hlen, klen, 1);
|
||||
do_test (9, 15, hlen, klen, 0);
|
||||
do_test (9, 15, hlen, klen, 1);
|
||||
|
||||
do_test (15, 0, hlen, klen, 0);
|
||||
do_test (15, 0, hlen, klen, 1);
|
||||
do_test (15, 3, hlen, klen, 0);
|
||||
do_test (15, 3, hlen, klen, 1);
|
||||
do_test (15, 9, hlen, klen, 0);
|
||||
do_test (15, 9, hlen, klen, 1);
|
||||
do_test (15, 15, hlen, klen, 0);
|
||||
do_test (15, 15, hlen, klen, 1);
|
||||
}
|
||||
|
||||
do_test (0, 0, page_size - 1, 16, 0);
|
||||
do_test (0, 0, page_size - 1, 16, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,72 @@
|
||||
/* Define timing macros.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <hp-timing.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if HP_TIMING_AVAIL && !defined USE_CLOCK_GETTIME
|
||||
# define GL(x) _##x
|
||||
# define GLRO(x) _##x
|
||||
hp_timing_t _dl_hp_timing_overhead;
|
||||
typedef hp_timing_t timing_t;
|
||||
|
||||
# define TIMING_INIT(iters) \
|
||||
({ \
|
||||
HP_TIMING_DIFF_INIT(); \
|
||||
(iters) = 1000; \
|
||||
})
|
||||
|
||||
# define TIMING_NOW(var) HP_TIMING_NOW (var)
|
||||
# define TIMING_DIFF(diff, start, end) HP_TIMING_DIFF ((diff), (start), (end))
|
||||
# define TIMING_ACCUM(sum, diff) HP_TIMING_ACCUM_NT ((sum), (diff))
|
||||
|
||||
# define TIMING_PRINT_STATS(func, d_total_s, d_iters, d_total_i, max, min) \
|
||||
printf ("%s: ITERS:%g: TOTAL:%gMcy, MAX:%gcy, MIN:%gcy, %g calls/Mcy\n", \
|
||||
(func), (d_total_i), (d_total_s) * 1e-6, (max) / (d_iters), \
|
||||
(min) / (d_iters), 1e6 * (d_total_i) / (d_total_s));
|
||||
|
||||
#else
|
||||
typedef uint64_t timing_t;
|
||||
|
||||
/* Measure 1000 times the resolution of the clock. So for a 1ns
|
||||
resolution clock, we measure 1000 iterations of the function call at a
|
||||
time. Measurements close to the minimum clock resolution won't make
|
||||
much sense, but it's better than having nothing at all. */
|
||||
# define TIMING_INIT(iters) \
|
||||
({ \
|
||||
struct timespec start; \
|
||||
clock_getres (CLOCK_PROCESS_CPUTIME_ID, &start); \
|
||||
(iters) = 1000 * start.tv_nsec; \
|
||||
})
|
||||
|
||||
# define TIMING_NOW(var) \
|
||||
({ \
|
||||
struct timespec tv; \
|
||||
clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &tv); \
|
||||
(var) = (uint64_t) (tv.tv_nsec + (uint64_t) 1000000000 * tv.tv_sec); \
|
||||
})
|
||||
|
||||
# define TIMING_DIFF(diff, start, end) (diff) = (end) - (start)
|
||||
# define TIMING_ACCUM(sum, diff) (sum) += (diff)
|
||||
|
||||
# define TIMING_PRINT_STATS(func, d_total_s, d_iters, d_total_i, max, min) \
|
||||
printf ("%s: ITERS:%g: TOTAL:%gs, MAX:%gns, MIN:%gns, %g iter/s\n", \
|
||||
(func), (d_total_i), (d_total_s) * 1e-9, (max) / (d_iters), \
|
||||
(min) / (d_iters), 1e9 * (d_total_i) / (d_total_s))
|
||||
|
||||
#endif
|
||||
@@ -3,3 +3,11 @@
|
||||
0x1.00000162a932ap0
|
||||
0x1.000002d452a11p0
|
||||
0x1.000005bc7d86cp0
|
||||
# cos slow path at 768 bits
|
||||
# Implemented in sysdeps/ieee754/dbl-64/sincos32.c
|
||||
## name: 768bits
|
||||
0x1.000000cf4a2a2p0
|
||||
0x1.0000010b239a9p0
|
||||
0x1.00000162a932bp0
|
||||
0x1.000002d452a10p0
|
||||
0x1.000005bc7d86dp0
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
0.1
|
||||
0.2
|
||||
0.3
|
||||
0.4
|
||||
0.5
|
||||
@@ -1 +1,5 @@
|
||||
42
|
||||
# Slowest path with computation in 768 bit precision.
|
||||
# Implemented in: sysdeps/ieee754/dbl-64/mpexp.c
|
||||
## name: 768bits
|
||||
708.00096423260981737257679924368858
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
42.0
|
||||
@@ -1 +1,5 @@
|
||||
42.0, 42.0
|
||||
# pow slowest path at 768 bits
|
||||
# Implemented in sysdeps/ieee754/dbl-64/slowpow.c
|
||||
## name: 768bits
|
||||
1.0000000000000020, 1.5
|
||||
|
||||
@@ -5,3 +5,13 @@
|
||||
4.0
|
||||
4.7
|
||||
5.9
|
||||
# sin slowest path at 768 bits
|
||||
# Implemented in sysdeps/ieee754/dbl-64/sincos32.c
|
||||
## name: 768bits
|
||||
0.93340582292648832662962377071381
|
||||
2.3328432680770916363144351635128
|
||||
3.7439477503636453548097051680088
|
||||
3.9225160069792437411706487182528
|
||||
4.0711651639931289992091478779912
|
||||
4.7858438478542097982426639646292
|
||||
5.9840767662578002727968851104379
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
0.1
|
||||
0.2
|
||||
0.3
|
||||
0.4
|
||||
0.5
|
||||
@@ -1,3 +0,0 @@
|
||||
0x1.000000c5cba87p0
|
||||
0x1.000001883003bp0
|
||||
0x1.00000dfb2b675p0
|
||||
@@ -1,5 +0,0 @@
|
||||
0x1.000000cf4a2a2p0
|
||||
0x1.0000010b239a9p0
|
||||
0x1.00000162a932bp0
|
||||
0x1.000002d452a10p0
|
||||
0x1.000005bc7d86dp0
|
||||
@@ -1 +0,0 @@
|
||||
708.00096423260981737257679924368858
|
||||
@@ -1 +0,0 @@
|
||||
1.0000000000000020, 1.5
|
||||
@@ -1,7 +0,0 @@
|
||||
0.93340582292648832662962377071381
|
||||
2.3328432680770916363144351635128
|
||||
3.7439477503636453548097051680088
|
||||
3.9225160069792437411706487182528
|
||||
4.0711651639931289992091478779912
|
||||
4.7858438478542097982426639646292
|
||||
5.9840767662578002727968851104379
|
||||
@@ -1,19 +0,0 @@
|
||||
/* Define slowsin.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define slowsin sin
|
||||
@@ -1 +0,0 @@
|
||||
0x1.dffffffffff1fp-22
|
||||
@@ -1,19 +0,0 @@
|
||||
/* Define slowtan.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define slowtan tan
|
||||
@@ -1 +1,5 @@
|
||||
0x1.dffffffffff1ep-22
|
||||
# tan slowest path at 768 bits
|
||||
# Implemented in sysdeps/ieee754/dbl-64/mptan.c
|
||||
## name: 768bits
|
||||
0x1.dffffffffff1fp-22
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user