From: Hans Kristian Rosbach Date: Sat, 27 Sep 2025 14:54:59 +0000 (+0200) Subject: Add WITH_C_FALLBACK X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7199fa251a600ccdf8c27e98bf292fef5911814b;p=thirdparty%2Fzlib-ng.git Add WITH_C_FALLBACK --- diff --git a/CMakeLists.txt b/CMakeLists.txt index d1633646..5f43a230 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,10 @@ option(WITH_CODE_COVERAGE "Enable code coverage reporting" OFF) option(WITH_INFLATE_STRICT "Build with strict inflate distance checking" OFF) option(WITH_INFLATE_ALLOW_INVALID_DIST "Build with zero fill for inflate invalid distances" OFF) +option(WITH_C_FALLBACK "Build with C fallback functions. +Causes abort() on init if optimized functions are missing! +Currently known safe on X86-64 if WITH_OPTIM and WITH_SSE2 is on." ON) + set(ZLIB_SYMBOL_PREFIX "" CACHE STRING "Give this prefix to all publicly exported symbols. Useful when embedding into a larger library. Default is no prefix (empty prefix).") @@ -153,6 +157,7 @@ option(INSTALL_UTILS "Copy minigzip and minideflate during install" OFF) mark_as_advanced(FORCE ZLIB_SYMBOL_PREFIX WITH_REDUCED_MEM + WITH_C_FALLBACK WITH_CRC32_CHORBA WITH_ARMV8 WITH_NEON WITH_ARMV6 @@ -195,6 +200,14 @@ if(NOT WITH_CRC32_CHORBA) add_definitions(-DWITHOUT_CHORBA) endif() +if(${ARCH} MATCHES "x86_64") + +endif() + +if(NOT WITH_C_FALLBACK) + add_definitions(-DNO_C_FALLBACK=1) +endif() + if(CMAKE_C_COMPILER_ID MATCHES "^Intel") if(CMAKE_HOST_UNIX) set(WARNFLAGS -Wall) @@ -1277,15 +1290,19 @@ set(ZLIB_PRIVATE_HDRS zutil.h zutil_p.h ) -set(ZLIB_SRCS +set(ZLIB_C_FALLBACK_SRCS arch/generic/adler32_c.c arch/generic/adler32_fold_c.c arch/generic/chunkset_c.c arch/generic/compare256_c.c - arch/generic/crc32_braid_c.c arch/generic/crc32_c.c + arch/generic/crc32_braid_c.c arch/generic/crc32_fold_c.c arch/generic/slide_hash_c.c +) + + +set(ZLIB_SRCS adler32.c compress.c crc32.c @@ -1311,6 +1328,9 @@ set(ZLIB_SRCS if(WITH_CRC32_CHORBA) list(APPEND ZLIB_SRCS arch/generic/crc32_chorba_c.c) + if(NOT WITH_C_FALLBACK) + list(APPEND ZLIB_SRCS arch/generic/crc32_braid_c.c) + endif() endif() if(WITH_RUNTIME_CPU_DETECTION) @@ -1332,6 +1352,10 @@ if(WITH_GZFILEOP) list(APPEND ZLIB_ALL_SRCS ${ZLIB_GZFILE_PRIVATE_HDRS} ${ZLIB_GZFILE_SRCS}) endif() +if(WITH_C_FALLBACK) + list(APPEND ZLIB_ALL_SRCS ${ZLIB_C_FALLBACK_SRCS}) +endif() + if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) set(ZLIB_DLL_SRCS win32/zlib${SUFFIX}1.rc) endif() @@ -1553,6 +1577,7 @@ add_feature_info(WITH_GTEST WITH_GTEST "Build gtest_zlib") add_feature_info(WITH_FUZZERS WITH_FUZZERS "Build test/fuzz") add_feature_info(WITH_BENCHMARKS WITH_BENCHMARKS "Build test/benchmarks") add_feature_info(WITH_BENCHMARK_APPS WITH_BENCHMARK_APPS "Build application benchmarks") +add_feature_info(WITH_C_FALLBACK WITH_C_FALLBACK "Build with C fallbacks") add_feature_info(WITH_OPTIM WITH_OPTIM "Build with optimisation") add_feature_info(WITH_NEW_STRATEGIES WITH_NEW_STRATEGIES "Use new strategies") add_feature_info(WITH_CRC32_CHORBA WITH_CRC32_CHORBA "Use optimized CRC32 algorithm Chorba") diff --git a/arch/generic/crc32_braid_c.c b/arch/generic/crc32_braid_c.c index 40c56105..efa3b1b6 100644 --- a/arch/generic/crc32_braid_c.c +++ b/arch/generic/crc32_braid_c.c @@ -212,6 +212,7 @@ Z_INTERNAL uint32_t crc32_braid_internal(uint32_t c, const uint8_t *buf, size_t return c; } +#ifndef NO_C_FALLBACK Z_INTERNAL uint32_t crc32_braid(uint32_t c, const uint8_t *buf, size_t len) { c = (~c) & 0xffffffff; @@ -220,3 +221,4 @@ Z_INTERNAL uint32_t crc32_braid(uint32_t c, const uint8_t *buf, size_t len) { /* Return the CRC, post-conditioned. */ return c ^ 0xffffffff; } +#endif diff --git a/functable.c b/functable.c index dd6400df..78104b23 100644 --- a/functable.c +++ b/functable.c @@ -13,6 +13,7 @@ #include "functable.h" #include "cpu_features.h" #include "arch_functions.h" +#include /* Platform has pointer size atomic store */ #if defined(__GNUC__) || defined(__clang__) @@ -38,6 +39,15 @@ # define FUNCTABLE_BARRIER() do { /* Empty */ } while (0) #endif +// Verify all pointers are valid before assigning, abort on failure +#define FUNCTABLE_VERIFY_ASSIGN(VAR, FUNC_NAME) \ + if (!VAR.FUNC_NAME) { \ + fprintf(stderr, "Functable entry not set!\n"); \ + abort(); \ + } \ + FUNCTABLE_ASSIGN(VAR, FUNC_NAME); + + static void force_init_empty(void) { // empty } @@ -48,8 +58,10 @@ static void init_functable(void) { cpu_check_features(&cf); - // Generic code ft.force_init = &force_init_empty; + +#ifndef NO_C_FALLBACK + // Generic code ft.adler32 = &adler32_c; ft.adler32_fold_copy = &adler32_fold_copy_c; ft.chunkmemset_safe = &chunkmemset_safe_c; @@ -64,6 +76,7 @@ static void init_functable(void) { ft.longest_match = &longest_match_c; ft.longest_match_slow = &longest_match_slow_c; ft.compare256 = &compare256_c; +#endif // Select arch-optimized functions @@ -309,21 +322,21 @@ static void init_functable(void) { #endif // Assign function pointers individually for atomic operation - FUNCTABLE_ASSIGN(ft, force_init); - FUNCTABLE_ASSIGN(ft, adler32); - FUNCTABLE_ASSIGN(ft, adler32_fold_copy); - FUNCTABLE_ASSIGN(ft, chunkmemset_safe); - FUNCTABLE_ASSIGN(ft, chunksize); - FUNCTABLE_ASSIGN(ft, compare256); - FUNCTABLE_ASSIGN(ft, crc32); - FUNCTABLE_ASSIGN(ft, crc32_fold); - FUNCTABLE_ASSIGN(ft, crc32_fold_copy); - FUNCTABLE_ASSIGN(ft, crc32_fold_final); - FUNCTABLE_ASSIGN(ft, crc32_fold_reset); - FUNCTABLE_ASSIGN(ft, inflate_fast); - FUNCTABLE_ASSIGN(ft, longest_match); - FUNCTABLE_ASSIGN(ft, longest_match_slow); - FUNCTABLE_ASSIGN(ft, slide_hash); + FUNCTABLE_VERIFY_ASSIGN(ft, force_init); + FUNCTABLE_VERIFY_ASSIGN(ft, adler32); + FUNCTABLE_VERIFY_ASSIGN(ft, adler32_fold_copy); + FUNCTABLE_VERIFY_ASSIGN(ft, chunkmemset_safe); + FUNCTABLE_VERIFY_ASSIGN(ft, chunksize); + FUNCTABLE_VERIFY_ASSIGN(ft, compare256); + FUNCTABLE_VERIFY_ASSIGN(ft, crc32); + FUNCTABLE_VERIFY_ASSIGN(ft, crc32_fold); + FUNCTABLE_VERIFY_ASSIGN(ft, crc32_fold_copy); + FUNCTABLE_VERIFY_ASSIGN(ft, crc32_fold_final); + FUNCTABLE_VERIFY_ASSIGN(ft, crc32_fold_reset); + FUNCTABLE_VERIFY_ASSIGN(ft, inflate_fast); + FUNCTABLE_VERIFY_ASSIGN(ft, longest_match); + FUNCTABLE_VERIFY_ASSIGN(ft, longest_match_slow); + FUNCTABLE_VERIFY_ASSIGN(ft, slide_hash); // Memory barrier for weak memory order CPUs FUNCTABLE_BARRIER(); diff --git a/test/benchmarks/benchmark_adler32_copy.cc b/test/benchmarks/benchmark_adler32_copy.cc index 2027904a..610c1c55 100644 --- a/test/benchmarks/benchmark_adler32_copy.cc +++ b/test/benchmarks/benchmark_adler32_copy.cc @@ -84,7 +84,9 @@ public: } \ BENCHMARK_REGISTER_F(adler32_copy, name)->Range(8192, MAX_RANDOM_INTS_SIZE); +#ifndef NO_C_FALLBACK BENCHMARK_ADLER32_BASELINE_COPY(c, adler32_c, 1); +#endif #ifdef DISABLE_RUNTIME_CPU_DETECTION BENCHMARK_ADLER32_BASELINE_COPY(native, native_adler32, 1); diff --git a/test/benchmarks/benchmark_crc32.cc b/test/benchmarks/benchmark_crc32.cc index 1e95b277..d308ce2d 100644 --- a/test/benchmarks/benchmark_crc32.cc +++ b/test/benchmarks/benchmark_crc32.cc @@ -56,13 +56,15 @@ public: } \ BENCHMARK_REGISTER_F(crc32, name)->Arg(1)->Arg(8)->Arg(12)->Arg(16)->Arg(32)->Arg(64)->Arg(512)->Arg(4<<10)->Arg(32<<10)->Arg(256<<10)->Arg(4096<<10); -#ifndef WITHOUT_CHORBA -BENCHMARK_CRC32(generic_chorba, crc32_c, 1); -#else -BENCHMARK_CRC32(generic, crc32_c, 1); -#endif +#ifndef NO_C_FALLBACK +# ifndef WITHOUT_CHORBA + BENCHMARK_CRC32(generic_chorba, crc32_c, 1); +# else + BENCHMARK_CRC32(generic, crc32_c, 1); +# endif -BENCHMARK_CRC32(braid, crc32_braid, 1); + BENCHMARK_CRC32(braid, crc32_braid, 1); +#endif #ifdef DISABLE_RUNTIME_CPU_DETECTION BENCHMARK_CRC32(native, native_crc32, 1); diff --git a/test/benchmarks/benchmark_slidehash.cc b/test/benchmarks/benchmark_slidehash.cc index 53e95168..7348e4d1 100644 --- a/test/benchmarks/benchmark_slidehash.cc +++ b/test/benchmarks/benchmark_slidehash.cc @@ -68,7 +68,9 @@ public: } \ BENCHMARK_REGISTER_F(slide_hash, name)->RangeMultiplier(2)->Range(512, MAX_RANDOM_INTS); +#ifndef NO_C_FALLBACK BENCHMARK_SLIDEHASH(c, slide_hash_c, 1); +#endif #ifdef DISABLE_RUNTIME_CPU_DETECTION BENCHMARK_SLIDEHASH(native, native_slide_hash, 1); diff --git a/test/test_adler32.cc b/test/test_adler32.cc index c52122c4..5a5912b3 100644 --- a/test/test_adler32.cc +++ b/test/test_adler32.cc @@ -363,7 +363,9 @@ INSTANTIATE_TEST_SUITE_P(adler32, adler32_variant, testing::ValuesIn(tests)); hash(GetParam(), func); \ } +#ifndef NO_C_FALLBACK TEST_ADLER32(c, adler32_c, 1) +#endif #ifdef DISABLE_RUNTIME_CPU_DETECTION TEST_ADLER32(native, native_adler32, 1) diff --git a/test/test_crc32.cc b/test/test_crc32.cc index d44d079e..1b728e7c 100644 --- a/test/test_crc32.cc +++ b/test/test_crc32.cc @@ -269,13 +269,15 @@ INSTANTIATE_TEST_SUITE_P(crc32, crc32_variant, testing::ValuesIn(tests)); hash(func); \ } -#ifndef WITHOUT_CHORBA -TEST_CRC32(generic_chorba, crc32_c, 1) -#else -TEST_CRC32(generic, crc32_c, 1) -#endif +#ifndef NO_C_FALLBACK +# ifndef WITHOUT_CHORBA + TEST_CRC32(generic_chorba, crc32_c, 1) +# else + TEST_CRC32(generic, crc32_c, 1) +# endif -TEST_CRC32(braid, crc32_braid, 1) + TEST_CRC32(braid, crc32_braid, 1) +#endif #ifdef DISABLE_RUNTIME_CPU_DETECTION TEST_CRC32(native, native_crc32, 1)