From 3efcadf8865efa2e0c5d44606efda87bfd4835fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 4 Mar 2024 11:37:14 +0100 Subject: [PATCH] zstd: Implement core detection (#2083) The bsdtar manual page claims that setting zstd:threads to 0 tells zstd to use as many threads as there are cores in the system, but it actually disables multi-threading. Replace 0 with the number of configured processors. While here, add a previously missing overflow check. Co-authored-by: Martin Matuska --- CMakeLists.txt | 1 + build/cmake/config.h.in | 3 +++ configure.ac | 1 + libarchive/archive_write_add_filter_zstd.c | 14 +++++++++++++- tar/bsdtar.1 | 15 +++++++-------- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a953bcea1d..822056b910 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1497,6 +1497,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(strncpy_s HAVE_STRNCPY_S) CHECK_FUNCTION_EXISTS_GLIBC(strnlen HAVE_STRNLEN) CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR) CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK) +CHECK_FUNCTION_EXISTS_GLIBC(sysconf HAVE_SYSCONF) CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM) CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET) CHECK_FUNCTION_EXISTS_GLIBC(unlinkat HAVE_UNLINKAT) diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index 045a6b4165..d47694c0c1 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -1094,6 +1094,9 @@ typedef uint64_t uintmax_t; /* Define to 1 if you have the `symlink' function. */ #cmakedefine HAVE_SYMLINK 1 +/* Define to 1 if you have the `sysconf' function. */ +#cmakedefine HAVE_SYSCONF 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_ACL_H 1 diff --git a/configure.ac b/configure.ac index 3cf5f50e78..c778c043f0 100644 --- a/configure.ac +++ b/configure.ac @@ -804,6 +804,7 @@ AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawnp readlink readlinkat]) AC_CHECK_FUNCS([readpassphrase]) AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs]) AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strnlen strrchr symlink]) +AC_CHECK_FUNCS([sysconf]) AC_CHECK_FUNCS([timegm tzset unlinkat unsetenv utime utimensat utimes vfork]) AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy wmemmove]) AC_CHECK_FUNCS([_fseeki64 _get_timezone]) diff --git a/libarchive/archive_write_add_filter_zstd.c b/libarchive/archive_write_add_filter_zstd.c index df539d326e..b49f453102 100644 --- a/libarchive/archive_write_add_filter_zstd.c +++ b/libarchive/archive_write_add_filter_zstd.c @@ -29,6 +29,9 @@ #ifdef HAVE_ERRNO_H #include #endif +#ifdef HAVE_LIMITS_H +#include +#endif #ifdef HAVE_STDINT_H #include #endif @@ -38,6 +41,9 @@ #ifdef HAVE_STRING_H #include #endif +#ifdef HAVE_UNISTD_H +#include +#endif #ifdef HAVE_ZSTD_H #include #endif @@ -266,7 +272,13 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key, if (string_to_number(value, &threads) != ARCHIVE_OK) { return (ARCHIVE_WARN); } - if (threads < 0) { + +#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) + if (threads == 0) { + threads = sysconf(_SC_NPROCESSORS_ONLN); + } +#endif + if (threads < 0 || threads > INT_MAX) { return (ARCHIVE_WARN); } data->threads = (int)threads; diff --git a/tar/bsdtar.1 b/tar/bsdtar.1 index e570d2a48a..fe9ec95046 100644 --- a/tar/bsdtar.1 +++ b/tar/bsdtar.1 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd March 1, 2024 +.Dd April 23, 2024 .Dt TAR 1 .Os .Sh NAME @@ -644,14 +644,13 @@ A decimal integer from 4 to 7 specifying the lz4 compression block size .It Cm lz4:block-dependence Use the previous block of the block being compressed for a compression dictionary to improve compression ratio. -.It Cm zstd:compression-level -A decimal integer specifying the zstd compression level. Supported values depend +.It Cm zstd:compression-level Ns = Ns Ar N +A decimal integer specifying the zstd compression level. +Supported values depend on the library version, common values are from 1 to 22. -.It Cm zstd:threads -Specify the number of worker threads to use. -Setting threads to a special value 0 makes -.Xr zstd 1 -use as many threads as there are CPU cores on the system. +.It Cm zstd:threads Ns = Ns Ar N +Specify the number of worker threads to use, or 0 to use as many +threads as there are CPU cores in the system. .It Cm zstd:frame-per-file Start a new compression frame at the beginning of each file in the archive.