Blob Blame History Raw
--- rpmio/rpmio.c.orig	2023-09-19 10:10:10.000000000 +0000
+++ rpmio/rpmio.c	2023-10-10 12:09:28.171040124 +0000
@@ -8,6 +8,7 @@
 #include <ctype.h>
 #include <dirent.h>
 #include <fcntl.h>
+#include <pthread.h>
 #include <sys/resource.h>
 
 #include <rpm/rpmlog.h>
@@ -997,6 +998,7 @@ static const FDIO_t lzdio = &lzdio_s;
 /* Support for ZSTD library.  */
 #ifdef HAVE_ZSTD
 
+#define ZSTD_STATIC_LINKING_ONLY
 #include <zstd.h>
 
 typedef struct rpmzstd_s {
@@ -1011,6 +1013,29 @@ typedef struct rpmzstd_s {
     ZSTD_outBuffer zob;         /*!< ZSTD_outBuffer */
 } * rpmzstd;
 
+#if ZSTD_VERSION_NUMBER >= 10407
+
+static pthread_once_t zstdThreadPoolCreated = PTHREAD_ONCE_INIT;
+static ZSTD_threadPool *zstdThreadPool;
+static int zstdThreadPoolThreads;
+
+static void zstdCreateThreadPool(void)
+{
+    int numthreads = rpmExpandNumeric("%{?_zstd_pool_threads}%{?!_zstd_pool_threads:-1}");
+    if (numthreads == 0)
+	numthreads = rpmExpandNumeric("%{getncpus:thread}");
+    if (numthreads > 0) {
+        zstdThreadPoolThreads = numthreads;
+        zstdThreadPool = ZSTD_createThreadPool(numthreads);
+        if (!zstdThreadPool)
+            rpmlog(RPMLOG_WARNING, "Could not create zstd thread pool for %d threads\n", numthreads);
+        else
+            rpmlog(RPMLOG_DEBUG, "Created zstd thread pool for %d threads\n", numthreads);
+    }
+}
+
+#endif
+
 static rpmzstd rpmzstdNew(int fdno, const char *fmode)
 {
     int flags = 0;
@@ -1116,8 +1141,18 @@ static rpmzstd rpmzstdNew(int fdno, cons
 	}
 
 	if (threads > 0) {
-	    if (ZSTD_isError (ZSTD_CCtx_setParameter(_stream, ZSTD_c_nbWorkers, threads)))
+	    if (ZSTD_isError (ZSTD_CCtx_setParameter(_stream, ZSTD_c_nbWorkers, threads))) {
 		rpmlog(RPMLOG_DEBUG, "zstd library does not support multi-threading\n");
+	    } else {
+#if ZSTD_VERSION_NUMBER >= 10407
+		pthread_once(&zstdThreadPoolCreated, zstdCreateThreadPool);
+		if (zstdThreadPool) {
+		    if (threads > zstdThreadPoolThreads)
+			ZSTD_CCtx_setParameter(_stream, ZSTD_c_nbWorkers, zstdThreadPoolThreads);
+		    ZSTD_CCtx_refThreadPool(_stream, zstdThreadPool);
+		}
+#endif
+	    }
 	}
 
 	nb = ZSTD_CStreamOutSize();