strutil: replace SSE4 specialization with libc call

SkipUntil had been partially specialized to use SSE4.2 instructions if
selected at compile time. The Makefile.ckati sets the compile flags to
the rather incompatible -march=native to enable the SSE4.2 instruction
set. The minimum (Intel) architecture required for SSE4.2 is Nehalem, so
-march=nehalem would do and that would probably make things a bit more
compatible when distributing the binary across machines.

It turns out, the relevant part of SkipUntil can actually be replaced by
a checked `strpbrk` call. Recent libc implementations do specialize
strpbrk for SSE4.2 as well. E.g. glibc runtime-selects `__strpbrk_sse42`
if the host provides the instruction set.

The ckati benchmark `strutil_bench` is neutral to this change. On my
machine the benchmark consistently produces around
   *kati*: WordScanner: 0.156697
with or without the change applied. This is when using the Make based
building process that also sets -march=native.

Other build systems and processes might not want to use -march=native to
be able to produce compatible builds. They might also not want to use
any limiting -march=* at all. That is the case for the Android build
where ckati is built and mainly used. When building in that environment,
the strutil_bench consistently runs
   *kati*: WordScanner: 0.396514
and when applying this patch
   *kati*: WordScanner: 0.255683

The difference between the best Android build and the Make based build
must be related to other build settings done in the Android/Soong based
build, such as FORTIFY_SOURCE, stack protector, etc.

Another side effect of this patch is, that we can run the kati test
suite successfully with --fsanitize=address now. Otherwise the SSE4.2
specific implementation would cause an address violation due to an
out-of-bounds read.

Signed-off-by: Matthias Maennich <[email protected]>
1 file changed
tree: 4baaf608a40c275137564eac30e54524f715f172
  1. .github/
  2. golang/
  3. src/
  4. testcase/
  5. .clang-format
  6. .dockerignore
  7. .gitignore
  8. AUTHORS
  9. clang-format-check
  10. CODEOWNERS
  11. CONTRIBUTING.md
  12. CONTRIBUTORS
  13. Dockerfile
  14. go.mod
  15. go.sum
  16. INTERNALS.md
  17. LICENSE
  18. Makefile
  19. Makefile.ckati
  20. Makefile.kati
  21. README.md
  22. run_test.go
README.md

kati

Build and Test

kati is an experimental GNU make clone. The main goal of this tool is to speed-up incremental build of Android.

Currently, kati does not offer a faster build by itself. It instead converts your Makefile to a ninja file.

Development

Building:

$ make ckati

The above command produces a ckati binary in the project root.

Testing (best ran in a Ubuntu 18.04 environment):

$ make test
$ go test --ckati
$ go test --ckati --ninja
$ go test --ckati --ninja --all

The above commands run all cKati and Ninja tests in the testcases/ directory.

Alternatively, you can also run the tests in a Docker container in a prepared test enviroment:

$ docker build -t kati-test . && docker run kati-test

How to use for Android

For Android-N+, ckati and ninja is used automatically. There is a prebuilt checked in under prebuilts/build-tools that is used.

All Android's build commands (m, mmm, mmma, etc.) should just work.