blob: 5b092ccd220930ff2075f6ad0437af26a9c026b7 [file] [log] [blame]
Yann Collet32fb4072017-08-18 16:52:05 -07001/*
Nick Terrell66e811d2021-01-04 17:53:52 -05002 * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
Nick Terrelle777a5b2016-12-29 23:39:44 -08003 * All rights reserved.
4 *
Yann Collet32fb4072017-08-18 16:52:05 -07005 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
Yann Collet3128e032017-09-08 00:09:23 -07008 * You may select, at your option, one of the above-listed licenses.
Nick Terrelle777a5b2016-12-29 23:39:44 -08009 */
10
cyan49732e3b6592017-01-20 14:00:41 -080011
12/* ====== Dependencies ======= */
Nick Terrell80f577b2020-08-06 20:18:05 -070013#include "zstd_deps.h" /* size_t */
Yann Collet6b48eb12018-06-20 14:35:39 -070014#include "debug.h" /* assert */
Nick Terrella686d302020-08-10 12:42:03 -070015#include "zstd_internal.h" /* ZSTD_customMalloc, ZSTD_customFree */
Yann Collet6b48eb12018-06-20 14:35:39 -070016#include "pool.h"
cyan49732e3b6592017-01-20 14:00:41 -080017
18/* ====== Compiler specifics ====== */
19#if defined(_MSC_VER)
20# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
21#endif
22
Nick Terrelle777a5b2016-12-29 23:39:44 -080023
Yann Collet0f984d92017-01-19 14:05:07 -080024#ifdef ZSTD_MULTITHREAD
Nick Terrelle777a5b2016-12-29 23:39:44 -080025
Nick Terrelle628eaf2017-01-26 15:29:10 -080026#include "threading.h" /* pthread adaptation */
Nick Terrelle777a5b2016-12-29 23:39:44 -080027
28/* A job is a function and an opaque argument */
29typedef struct POOL_job_s {
Nick Terrell89dc8562017-08-24 16:48:32 -070030 POOL_function function;
31 void *opaque;
Nick Terrelle777a5b2016-12-29 23:39:44 -080032} POOL_job;
33
34struct POOL_ctx_s {
Nick Terrell26dc0402017-08-24 17:01:41 -070035 ZSTD_customMem customMem;
Nick Terrelle777a5b2016-12-29 23:39:44 -080036 /* Keep track of the threads */
Yann Collet1c714fd2018-06-18 20:46:39 -070037 ZSTD_pthread_t* threads;
38 size_t threadCapacity;
39 size_t threadLimit;
Nick Terrelle777a5b2016-12-29 23:39:44 -080040
41 /* The queue is a circular buffer */
42 POOL_job *queue;
43 size_t queueHead;
44 size_t queueTail;
45 size_t queueSize;
Stella Lau5adceee2017-07-31 10:10:16 -070046
Stella Lau1d76da12017-08-01 12:24:55 -070047 /* The number of threads working on jobs */
48 size_t numThreadsBusy;
49 /* Indicates if the queue is empty */
50 int queueEmpty;
Stella Lau5adceee2017-07-31 10:10:16 -070051
Nick Terrelle777a5b2016-12-29 23:39:44 -080052 /* The mutex protects the queue */
Nick Terrell6c41adf2017-09-27 11:16:24 -070053 ZSTD_pthread_mutex_t queueMutex;
Nick Terrelle777a5b2016-12-29 23:39:44 -080054 /* Condition variable for pushers to wait on when the queue is full */
Nick Terrell6c41adf2017-09-27 11:16:24 -070055 ZSTD_pthread_cond_t queuePushCond;
Nick Terrelle777a5b2016-12-29 23:39:44 -080056 /* Condition variables for poppers to wait on when the queue is empty */
Nick Terrell6c41adf2017-09-27 11:16:24 -070057 ZSTD_pthread_cond_t queuePopCond;
Nick Terrelle777a5b2016-12-29 23:39:44 -080058 /* Indicates if the queue is shutting down */
59 int shutdown;
60};
61
62/* POOL_thread() :
Yann Collet1c714fd2018-06-18 20:46:39 -070063 * Work thread for the thread pool.
64 * Waits for jobs and executes them.
65 * @returns : NULL on failure else non-null.
66 */
Yann Collet3b29dbd2016-12-31 06:04:25 +010067static void* POOL_thread(void* opaque) {
68 POOL_ctx* const ctx = (POOL_ctx*)opaque;
Nick Terrelle777a5b2016-12-29 23:39:44 -080069 if (!ctx) { return NULL; }
70 for (;;) {
71 /* Lock the mutex and wait for a non-empty queue or until shutdown */
Nick Terrell6c41adf2017-09-27 11:16:24 -070072 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
Stella Lau73ba5892017-08-01 20:12:06 -070073
Yann Collet6b48eb12018-06-20 14:35:39 -070074 while ( ctx->queueEmpty
75 || (ctx->numThreadsBusy >= ctx->threadLimit) ) {
Yann Collet818e72b2018-06-21 14:58:59 -070076 if (ctx->shutdown) {
77 /* even if !queueEmpty, (possible if numThreadsBusy >= threadLimit),
78 * a few threads will be shutdown while !queueEmpty,
79 * but enough threads will remain active to finish the queue */
80 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
81 return opaque;
82 }
Nick Terrell6c41adf2017-09-27 11:16:24 -070083 ZSTD_pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex);
Nick Terrelle777a5b2016-12-29 23:39:44 -080084 }
Yann Colletc6a64172016-12-31 03:31:26 +010085 /* Pop a job off the queue */
Yann Collet7db55262017-08-19 15:07:54 -070086 { POOL_job const job = ctx->queue[ctx->queueHead];
Nick Terrelle777a5b2016-12-29 23:39:44 -080087 ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;
Stella Lau5adceee2017-07-31 10:10:16 -070088 ctx->numThreadsBusy++;
Stella Lau1d76da12017-08-01 12:24:55 -070089 ctx->queueEmpty = ctx->queueHead == ctx->queueTail;
Nick Terrelle777a5b2016-12-29 23:39:44 -080090 /* Unlock the mutex, signal a pusher, and run the job */
Nick Terrell6c41adf2017-09-27 11:16:24 -070091 ZSTD_pthread_cond_signal(&ctx->queuePushCond);
Nick Terrella8daa2d2018-11-08 10:45:53 -080092 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
Stella Lau73ba5892017-08-01 20:12:06 -070093
Nick Terrelle777a5b2016-12-29 23:39:44 -080094 job.function(job.opaque);
Stella Lau5adceee2017-07-31 10:10:16 -070095
Stella Lau73ba5892017-08-01 20:12:06 -070096 /* If the intended queue size was 0, signal after finishing job */
Yann Collet6de249c2018-06-20 17:18:57 -070097 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
98 ctx->numThreadsBusy--;
Stella Lau73ba5892017-08-01 20:12:06 -070099 if (ctx->queueSize == 1) {
Nick Terrell6c41adf2017-09-27 11:16:24 -0700100 ZSTD_pthread_cond_signal(&ctx->queuePushCond);
Yann Collet6de249c2018-06-20 17:18:57 -0700101 }
102 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
103 }
Yann Collet7db55262017-08-19 15:07:54 -0700104 } /* for (;;) */
Yann Collet818e72b2018-06-21 14:58:59 -0700105 assert(0); /* Unreachable */
Nick Terrelle777a5b2016-12-29 23:39:44 -0800106}
107
Martin Liskab6849002020-09-25 14:12:14 +0200108POOL_ctx* ZSTD_createThreadPool(size_t numThreads) {
109 return POOL_create (numThreads, 0);
110}
111
Yann Collet86b4fe52017-09-28 18:14:28 -0700112POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
Nick Terrell26dc0402017-08-24 17:01:41 -0700113 return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
114}
115
Yann Collet1c714fd2018-06-18 20:46:39 -0700116POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
117 ZSTD_customMem customMem) {
Yann Collet86b4fe52017-09-28 18:14:28 -0700118 POOL_ctx* ctx;
Yann Collet1c714fd2018-06-18 20:46:39 -0700119 /* Check parameters */
Stella Lau5adceee2017-07-31 10:10:16 -0700120 if (!numThreads) { return NULL; }
Nick Terrelle777a5b2016-12-29 23:39:44 -0800121 /* Allocate the context and zero initialize */
Nick Terrella686d302020-08-10 12:42:03 -0700122 ctx = (POOL_ctx*)ZSTD_customCalloc(sizeof(POOL_ctx), customMem);
Nick Terrelle777a5b2016-12-29 23:39:44 -0800123 if (!ctx) { return NULL; }
124 /* Initialize the job queue.
Yann Collet1c714fd2018-06-18 20:46:39 -0700125 * It needs one extra space since one space is wasted to differentiate
126 * empty and full queues.
Nick Terrelle777a5b2016-12-29 23:39:44 -0800127 */
128 ctx->queueSize = queueSize + 1;
Nick Terrella686d302020-08-10 12:42:03 -0700129 ctx->queue = (POOL_job*)ZSTD_customMalloc(ctx->queueSize * sizeof(POOL_job), customMem);
Nick Terrelle777a5b2016-12-29 23:39:44 -0800130 ctx->queueHead = 0;
131 ctx->queueTail = 0;
Stella Lau5adceee2017-07-31 10:10:16 -0700132 ctx->numThreadsBusy = 0;
Stella Lau1d76da12017-08-01 12:24:55 -0700133 ctx->queueEmpty = 1;
Nick Terrell24382452019-10-18 12:33:45 -0700134 {
135 int error = 0;
136 error |= ZSTD_pthread_mutex_init(&ctx->queueMutex, NULL);
137 error |= ZSTD_pthread_cond_init(&ctx->queuePushCond, NULL);
138 error |= ZSTD_pthread_cond_init(&ctx->queuePopCond, NULL);
139 if (error) { POOL_free(ctx); return NULL; }
140 }
Nick Terrelle777a5b2016-12-29 23:39:44 -0800141 ctx->shutdown = 0;
142 /* Allocate space for the thread handles */
Nick Terrella686d302020-08-10 12:42:03 -0700143 ctx->threads = (ZSTD_pthread_t*)ZSTD_customMalloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
Yann Collet1c714fd2018-06-18 20:46:39 -0700144 ctx->threadCapacity = 0;
Nick Terrell26dc0402017-08-24 17:01:41 -0700145 ctx->customMem = customMem;
Nick Terrelle777a5b2016-12-29 23:39:44 -0800146 /* Check for errors */
Nick Terrellbb133872016-12-31 19:10:47 -0500147 if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
Nick Terrelle777a5b2016-12-29 23:39:44 -0800148 /* Initialize the threads */
149 { size_t i;
150 for (i = 0; i < numThreads; ++i) {
Nick Terrell6c41adf2017-09-27 11:16:24 -0700151 if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
Yann Collet1c714fd2018-06-18 20:46:39 -0700152 ctx->threadCapacity = i;
Nick Terrelle777a5b2016-12-29 23:39:44 -0800153 POOL_free(ctx);
154 return NULL;
Yann Colletc6a64172016-12-31 03:31:26 +0100155 } }
Yann Collet1c714fd2018-06-18 20:46:39 -0700156 ctx->threadCapacity = numThreads;
157 ctx->threadLimit = numThreads;
Nick Terrelle777a5b2016-12-29 23:39:44 -0800158 }
159 return ctx;
160}
161
162/*! POOL_join() :
163 Shutdown the queue, wake any sleeping threads, and join all of the threads.
164*/
Yann Collet86b4fe52017-09-28 18:14:28 -0700165static void POOL_join(POOL_ctx* ctx) {
Nick Terrelle777a5b2016-12-29 23:39:44 -0800166 /* Shut down the queue */
Nick Terrell6c41adf2017-09-27 11:16:24 -0700167 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
Nick Terrelle777a5b2016-12-29 23:39:44 -0800168 ctx->shutdown = 1;
Nick Terrell6c41adf2017-09-27 11:16:24 -0700169 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
Nick Terrelle777a5b2016-12-29 23:39:44 -0800170 /* Wake up sleeping threads */
Nick Terrell6c41adf2017-09-27 11:16:24 -0700171 ZSTD_pthread_cond_broadcast(&ctx->queuePushCond);
172 ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);
Nick Terrelle777a5b2016-12-29 23:39:44 -0800173 /* Join all of the threads */
174 { size_t i;
Yann Collet1c714fd2018-06-18 20:46:39 -0700175 for (i = 0; i < ctx->threadCapacity; ++i) {
176 ZSTD_pthread_join(ctx->threads[i], NULL); /* note : could fail */
Yann Colletc6a64172016-12-31 03:31:26 +0100177 } }
Nick Terrelle777a5b2016-12-29 23:39:44 -0800178}
179
180void POOL_free(POOL_ctx *ctx) {
181 if (!ctx) { return; }
182 POOL_join(ctx);
Nick Terrell6c41adf2017-09-27 11:16:24 -0700183 ZSTD_pthread_mutex_destroy(&ctx->queueMutex);
184 ZSTD_pthread_cond_destroy(&ctx->queuePushCond);
185 ZSTD_pthread_cond_destroy(&ctx->queuePopCond);
Nick Terrella686d302020-08-10 12:42:03 -0700186 ZSTD_customFree(ctx->queue, ctx->customMem);
187 ZSTD_customFree(ctx->threads, ctx->customMem);
188 ZSTD_customFree(ctx, ctx->customMem);
Nick Terrelle777a5b2016-12-29 23:39:44 -0800189}
190
Martin Liskab6849002020-09-25 14:12:14 +0200191void ZSTD_freeThreadPool (ZSTD_threadPool* pool) {
192 POOL_free (pool);
193}
Yann Collet1c714fd2018-06-18 20:46:39 -0700194
Yann Colletc4a5a212017-06-01 17:56:14 -0700195size_t POOL_sizeof(POOL_ctx *ctx) {
196 if (ctx==NULL) return 0; /* supports sizeof NULL */
197 return sizeof(*ctx)
198 + ctx->queueSize * sizeof(POOL_job)
Yann Collet1c714fd2018-06-18 20:46:39 -0700199 + ctx->threadCapacity * sizeof(ZSTD_pthread_t);
200}
201
202
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700203/* @return : 0 on success, 1 on error */
204static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
Yann Collet1c714fd2018-06-18 20:46:39 -0700205{
Yann Collet1c714fd2018-06-18 20:46:39 -0700206 if (numThreads <= ctx->threadCapacity) {
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700207 if (!numThreads) return 1;
Yann Collet1c714fd2018-06-18 20:46:39 -0700208 ctx->threadLimit = numThreads;
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700209 return 0;
Yann Collet1c714fd2018-06-18 20:46:39 -0700210 }
211 /* numThreads > threadCapacity */
Nick Terrella686d302020-08-10 12:42:03 -0700212 { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customMalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700213 if (!threadPool) return 1;
Yann Collet4567c572018-06-19 16:03:12 -0700214 /* replace existing thread pool */
Nick Terrellc465f242020-08-10 12:46:38 -0700215 ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool));
Nick Terrella686d302020-08-10 12:42:03 -0700216 ZSTD_customFree(ctx->threads, ctx->customMem);
Yann Collet4567c572018-06-19 16:03:12 -0700217 ctx->threads = threadPool;
Yann Collet1c714fd2018-06-18 20:46:39 -0700218 /* Initialize additional threads */
219 { size_t threadId;
220 for (threadId = ctx->threadCapacity; threadId < numThreads; ++threadId) {
221 if (ZSTD_pthread_create(&threadPool[threadId], NULL, &POOL_thread, ctx)) {
Yann Collet62469c92018-06-19 20:14:03 -0700222 ctx->threadCapacity = threadId;
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700223 return 1;
Yann Collet1c714fd2018-06-18 20:46:39 -0700224 } }
Yann Collet62469c92018-06-19 20:14:03 -0700225 } }
Yann Collet4567c572018-06-19 16:03:12 -0700226 /* successfully expanded */
Yann Collet1c714fd2018-06-18 20:46:39 -0700227 ctx->threadCapacity = numThreads;
228 ctx->threadLimit = numThreads;
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700229 return 0;
Yann Collet1c714fd2018-06-18 20:46:39 -0700230}
231
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700232/* @return : 0 on success, 1 on error */
233int POOL_resize(POOL_ctx* ctx, size_t numThreads)
Yann Collet1c714fd2018-06-18 20:46:39 -0700234{
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700235 int result;
236 if (ctx==NULL) return 1;
Yann Collet1c714fd2018-06-18 20:46:39 -0700237 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700238 result = POOL_resize_internal(ctx, numThreads);
Yann Collet243cd9d2018-06-21 18:04:58 -0700239 ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);
Yann Collet1c714fd2018-06-18 20:46:39 -0700240 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700241 return result;
Yann Colletc4a5a212017-06-01 17:56:14 -0700242}
243
Stella Lau73ba5892017-08-01 20:12:06 -0700244/**
245 * Returns 1 if the queue is full and 0 otherwise.
246 *
Yann Collet1c714fd2018-06-18 20:46:39 -0700247 * When queueSize is 1 (pool was created with an intended queueSize of 0),
248 * then a queue is empty if there is a thread free _and_ no job is waiting.
Stella Lau73ba5892017-08-01 20:12:06 -0700249 */
250static int isQueueFull(POOL_ctx const* ctx) {
251 if (ctx->queueSize > 1) {
252 return ctx->queueHead == ((ctx->queueTail + 1) % ctx->queueSize);
253 } else {
Yann Collet6b48eb12018-06-20 14:35:39 -0700254 return (ctx->numThreadsBusy == ctx->threadLimit) ||
Stella Lau73ba5892017-08-01 20:12:06 -0700255 !ctx->queueEmpty;
256 }
257}
258
Nick Terrelle777a5b2016-12-29 23:39:44 -0800259
Yann Collet997e4d02018-01-18 14:39:51 -0800260static void POOL_add_internal(POOL_ctx* ctx, POOL_function function, void *opaque)
261{
262 POOL_job const job = {function, opaque};
263 assert(ctx != NULL);
264 if (ctx->shutdown) return;
Stella Lau1d76da12017-08-01 12:24:55 -0700265
Yann Collet997e4d02018-01-18 14:39:51 -0800266 ctx->queueEmpty = 0;
267 ctx->queue[ctx->queueTail] = job;
268 ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize;
Nick Terrell6c41adf2017-09-27 11:16:24 -0700269 ZSTD_pthread_cond_signal(&ctx->queuePopCond);
Nick Terrelle777a5b2016-12-29 23:39:44 -0800270}
271
Yann Collet997e4d02018-01-18 14:39:51 -0800272void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque)
273{
274 assert(ctx != NULL);
275 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
276 /* Wait until there is space in the queue for the new job */
277 while (isQueueFull(ctx) && (!ctx->shutdown)) {
278 ZSTD_pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex);
279 }
280 POOL_add_internal(ctx, function, opaque);
281 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
282}
Nick Terrelle777a5b2016-12-29 23:39:44 -0800283
Yann Collet997e4d02018-01-18 14:39:51 -0800284
285int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque)
286{
287 assert(ctx != NULL);
288 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
289 if (isQueueFull(ctx)) {
290 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
291 return 0;
292 }
293 POOL_add_internal(ctx, function, opaque);
294 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
295 return 1;
296}
297
298
299#else /* ZSTD_MULTITHREAD not defined */
300
301/* ========================== */
302/* No multi-threading support */
303/* ========================== */
304
305
306/* We don't need any data, but if it is empty, malloc() might return NULL. */
Nick Terrell02033be2017-08-28 17:19:01 -0700307struct POOL_ctx_s {
308 int dummy;
309};
yoshihitohc6548ea2020-06-29 10:51:50 +0900310static POOL_ctx g_poolCtx;
Nick Terrelle777a5b2016-12-29 23:39:44 -0800311
Yann Collet16261e62017-07-11 14:14:07 -0700312POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
Nick Terrell26dc0402017-08-24 17:01:41 -0700313 return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
314}
315
316POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) {
Nick Terrell89dc8562017-08-24 16:48:32 -0700317 (void)numThreads;
318 (void)queueSize;
Nick Terrell26dc0402017-08-24 17:01:41 -0700319 (void)customMem;
yoshihitohc6548ea2020-06-29 10:51:50 +0900320 return &g_poolCtx;
Nick Terrelle777a5b2016-12-29 23:39:44 -0800321}
322
Yann Collet16261e62017-07-11 14:14:07 -0700323void POOL_free(POOL_ctx* ctx) {
yoshihitohc6548ea2020-06-29 10:51:50 +0900324 assert(!ctx || ctx == &g_poolCtx);
Nick Terrell26dc0402017-08-24 17:01:41 -0700325 (void)ctx;
Nick Terrelle777a5b2016-12-29 23:39:44 -0800326}
327
Yann Colletfbd5dfc2018-06-22 12:14:59 -0700328int POOL_resize(POOL_ctx* ctx, size_t numThreads) {
329 (void)ctx; (void)numThreads;
330 return 0;
Yann Collet4567c572018-06-19 16:03:12 -0700331}
332
Yann Collet997e4d02018-01-18 14:39:51 -0800333void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque) {
Nick Terrell89dc8562017-08-24 16:48:32 -0700334 (void)ctx;
335 function(opaque);
Nick Terrelle777a5b2016-12-29 23:39:44 -0800336}
337
Yann Collet997e4d02018-01-18 14:39:51 -0800338int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) {
339 (void)ctx;
340 function(opaque);
341 return 1;
342}
343
Yann Collet16261e62017-07-11 14:14:07 -0700344size_t POOL_sizeof(POOL_ctx* ctx) {
Yann Collet6056e4c2017-06-02 11:36:47 -0700345 if (ctx==NULL) return 0; /* supports sizeof NULL */
yoshihitohc6548ea2020-06-29 10:51:50 +0900346 assert(ctx == &g_poolCtx);
Yann Collet6056e4c2017-06-02 11:36:47 -0700347 return sizeof(*ctx);
348}
349
Yann Collet0f984d92017-01-19 14:05:07 -0800350#endif /* ZSTD_MULTITHREAD */