zstdlib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES.md +9 -0
  3. data/Gemfile +3 -0
  4. data/README.md +96 -0
  5. data/Rakefile +29 -0
  6. data/ext/zstdlib/extconf.rb +53 -0
  7. data/ext/zstdlib/ruby/zlib-2.2/zlib.c +4659 -0
  8. data/ext/zstdlib/ruby/zlib-2.3/zlib.c +4686 -0
  9. data/ext/zstdlib/ruby/zlib-2.4/zlib.c +4843 -0
  10. data/ext/zstdlib/ruby/zlib-2.5/zlib.c +4848 -0
  11. data/ext/zstdlib/ruby/zlib-2.6/zlib.c +4890 -0
  12. data/ext/zstdlib/zlib-1.2.11/adler32.c +186 -0
  13. data/ext/zstdlib/zlib-1.2.11/compress.c +86 -0
  14. data/ext/zstdlib/zlib-1.2.11/crc32.c +442 -0
  15. data/ext/zstdlib/zlib-1.2.11/crc32.h +441 -0
  16. data/ext/zstdlib/zlib-1.2.11/deflate.c +2163 -0
  17. data/ext/zstdlib/zlib-1.2.11/deflate.h +349 -0
  18. data/ext/zstdlib/zlib-1.2.11/gzclose.c +25 -0
  19. data/ext/zstdlib/zlib-1.2.11/gzguts.h +218 -0
  20. data/ext/zstdlib/zlib-1.2.11/gzlib.c +637 -0
  21. data/ext/zstdlib/zlib-1.2.11/gzread.c +654 -0
  22. data/ext/zstdlib/zlib-1.2.11/gzwrite.c +665 -0
  23. data/ext/zstdlib/zlib-1.2.11/infback.c +640 -0
  24. data/ext/zstdlib/zlib-1.2.11/inffast.c +323 -0
  25. data/ext/zstdlib/zlib-1.2.11/inffast.h +11 -0
  26. data/ext/zstdlib/zlib-1.2.11/inffixed.h +94 -0
  27. data/ext/zstdlib/zlib-1.2.11/inflate.c +1561 -0
  28. data/ext/zstdlib/zlib-1.2.11/inflate.h +125 -0
  29. data/ext/zstdlib/zlib-1.2.11/inftrees.c +304 -0
  30. data/ext/zstdlib/zlib-1.2.11/inftrees.h +62 -0
  31. data/ext/zstdlib/zlib-1.2.11/trees.c +1203 -0
  32. data/ext/zstdlib/zlib-1.2.11/trees.h +128 -0
  33. data/ext/zstdlib/zlib-1.2.11/uncompr.c +93 -0
  34. data/ext/zstdlib/zlib-1.2.11/zconf.h +534 -0
  35. data/ext/zstdlib/zlib-1.2.11/zlib.h +1912 -0
  36. data/ext/zstdlib/zlib-1.2.11/zutil.c +325 -0
  37. data/ext/zstdlib/zlib-1.2.11/zutil.h +271 -0
  38. data/ext/zstdlib/zlib.mk +14 -0
  39. data/ext/zstdlib/zlibwrapper/zlibwrapper.c +14 -0
  40. data/ext/zstdlib/zlibwrapper.mk +14 -0
  41. data/ext/zstdlib/zstd-1.3.8/lib/common/bitstream.h +455 -0
  42. data/ext/zstdlib/zstd-1.3.8/lib/common/compiler.h +140 -0
  43. data/ext/zstdlib/zstd-1.3.8/lib/common/cpu.h +215 -0
  44. data/ext/zstdlib/zstd-1.3.8/lib/common/debug.c +44 -0
  45. data/ext/zstdlib/zstd-1.3.8/lib/common/debug.h +134 -0
  46. data/ext/zstdlib/zstd-1.3.8/lib/common/entropy_common.c +236 -0
  47. data/ext/zstdlib/zstd-1.3.8/lib/common/error_private.c +54 -0
  48. data/ext/zstdlib/zstd-1.3.8/lib/common/error_private.h +76 -0
  49. data/ext/zstdlib/zstd-1.3.8/lib/common/fse.h +708 -0
  50. data/ext/zstdlib/zstd-1.3.8/lib/common/fse_decompress.c +309 -0
  51. data/ext/zstdlib/zstd-1.3.8/lib/common/huf.h +358 -0
  52. data/ext/zstdlib/zstd-1.3.8/lib/common/mem.h +380 -0
  53. data/ext/zstdlib/zstd-1.3.8/lib/common/pool.c +340 -0
  54. data/ext/zstdlib/zstd-1.3.8/lib/common/pool.h +84 -0
  55. data/ext/zstdlib/zstd-1.3.8/lib/common/threading.c +75 -0
  56. data/ext/zstdlib/zstd-1.3.8/lib/common/threading.h +123 -0
  57. data/ext/zstdlib/zstd-1.3.8/lib/common/xxhash.c +876 -0
  58. data/ext/zstdlib/zstd-1.3.8/lib/common/xxhash.h +305 -0
  59. data/ext/zstdlib/zstd-1.3.8/lib/common/zstd_common.c +83 -0
  60. data/ext/zstdlib/zstd-1.3.8/lib/common/zstd_errors.h +93 -0
  61. data/ext/zstdlib/zstd-1.3.8/lib/common/zstd_internal.h +266 -0
  62. data/ext/zstdlib/zstd-1.3.8/lib/compress/fse_compress.c +721 -0
  63. data/ext/zstdlib/zstd-1.3.8/lib/compress/hist.c +203 -0
  64. data/ext/zstdlib/zstd-1.3.8/lib/compress/hist.h +95 -0
  65. data/ext/zstdlib/zstd-1.3.8/lib/compress/huf_compress.c +798 -0
  66. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_compress.c +4290 -0
  67. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_compress_internal.h +860 -0
  68. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_double_fast.c +499 -0
  69. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_double_fast.h +38 -0
  70. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_fast.c +391 -0
  71. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_fast.h +37 -0
  72. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_lazy.c +1106 -0
  73. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_lazy.h +67 -0
  74. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_ldm.c +597 -0
  75. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_ldm.h +105 -0
  76. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_opt.c +1217 -0
  77. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstd_opt.h +56 -0
  78. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstdmt_compress.c +2107 -0
  79. data/ext/zstdlib/zstd-1.3.8/lib/compress/zstdmt_compress.h +174 -0
  80. data/ext/zstdlib/zstd-1.3.8/lib/decompress/huf_decompress.c +1232 -0
  81. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_ddict.c +240 -0
  82. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_ddict.h +44 -0
  83. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_decompress.c +1672 -0
  84. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_decompress_block.c +1307 -0
  85. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_decompress_block.h +59 -0
  86. data/ext/zstdlib/zstd-1.3.8/lib/decompress/zstd_decompress_internal.h +168 -0
  87. data/ext/zstdlib/zstd-1.3.8/lib/zstd.h +1766 -0
  88. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzclose.c +28 -0
  89. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzcompatibility.h +68 -0
  90. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzguts.h +227 -0
  91. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzlib.c +640 -0
  92. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzread.c +670 -0
  93. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/gzwrite.c +671 -0
  94. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/zstd_zlibwrapper.c +1105 -0
  95. data/ext/zstdlib/zstd-1.3.8/zlibWrapper/zstd_zlibwrapper.h +88 -0
  96. data/ext/zstdlib/zstd.mk +14 -0
  97. data/lib/zstdlib.rb +6 -0
  98. data/test/zstdlib_test.rb +21 -0
  99. metadata +198 -0
@@ -0,0 +1,340 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * 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).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+
12
+ /* ====== Dependencies ======= */
13
+ #include <stddef.h> /* size_t */
14
+ #include "debug.h" /* assert */
15
+ #include "zstd_internal.h" /* ZSTD_malloc, ZSTD_free */
16
+ #include "pool.h"
17
+
18
+ /* ====== Compiler specifics ====== */
19
+ #if defined(_MSC_VER)
20
+ # pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
21
+ #endif
22
+
23
+
24
+ #ifdef ZSTD_MULTITHREAD
25
+
26
+ #include "threading.h" /* pthread adaptation */
27
+
28
+ /* A job is a function and an opaque argument */
29
+ typedef struct POOL_job_s {
30
+ POOL_function function;
31
+ void *opaque;
32
+ } POOL_job;
33
+
34
+ struct POOL_ctx_s {
35
+ ZSTD_customMem customMem;
36
+ /* Keep track of the threads */
37
+ ZSTD_pthread_t* threads;
38
+ size_t threadCapacity;
39
+ size_t threadLimit;
40
+
41
+ /* The queue is a circular buffer */
42
+ POOL_job *queue;
43
+ size_t queueHead;
44
+ size_t queueTail;
45
+ size_t queueSize;
46
+
47
+ /* The number of threads working on jobs */
48
+ size_t numThreadsBusy;
49
+ /* Indicates if the queue is empty */
50
+ int queueEmpty;
51
+
52
+ /* The mutex protects the queue */
53
+ ZSTD_pthread_mutex_t queueMutex;
54
+ /* Condition variable for pushers to wait on when the queue is full */
55
+ ZSTD_pthread_cond_t queuePushCond;
56
+ /* Condition variables for poppers to wait on when the queue is empty */
57
+ ZSTD_pthread_cond_t queuePopCond;
58
+ /* Indicates if the queue is shutting down */
59
+ int shutdown;
60
+ };
61
+
62
+ /* POOL_thread() :
63
+ * Work thread for the thread pool.
64
+ * Waits for jobs and executes them.
65
+ * @returns : NULL on failure else non-null.
66
+ */
67
+ static void* POOL_thread(void* opaque) {
68
+ POOL_ctx* const ctx = (POOL_ctx*)opaque;
69
+ if (!ctx) { return NULL; }
70
+ for (;;) {
71
+ /* Lock the mutex and wait for a non-empty queue or until shutdown */
72
+ ZSTD_pthread_mutex_lock(&ctx->queueMutex);
73
+
74
+ while ( ctx->queueEmpty
75
+ || (ctx->numThreadsBusy >= ctx->threadLimit) ) {
76
+ 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
+ }
83
+ ZSTD_pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex);
84
+ }
85
+ /* Pop a job off the queue */
86
+ { POOL_job const job = ctx->queue[ctx->queueHead];
87
+ ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;
88
+ ctx->numThreadsBusy++;
89
+ ctx->queueEmpty = ctx->queueHead == ctx->queueTail;
90
+ /* Unlock the mutex, signal a pusher, and run the job */
91
+ ZSTD_pthread_cond_signal(&ctx->queuePushCond);
92
+ ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
93
+
94
+ job.function(job.opaque);
95
+
96
+ /* If the intended queue size was 0, signal after finishing job */
97
+ ZSTD_pthread_mutex_lock(&ctx->queueMutex);
98
+ ctx->numThreadsBusy--;
99
+ if (ctx->queueSize == 1) {
100
+ ZSTD_pthread_cond_signal(&ctx->queuePushCond);
101
+ }
102
+ ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
103
+ }
104
+ } /* for (;;) */
105
+ assert(0); /* Unreachable */
106
+ }
107
+
108
+ POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
109
+ return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
110
+ }
111
+
112
+ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
113
+ ZSTD_customMem customMem) {
114
+ POOL_ctx* ctx;
115
+ /* Check parameters */
116
+ if (!numThreads) { return NULL; }
117
+ /* Allocate the context and zero initialize */
118
+ ctx = (POOL_ctx*)ZSTD_calloc(sizeof(POOL_ctx), customMem);
119
+ if (!ctx) { return NULL; }
120
+ /* Initialize the job queue.
121
+ * It needs one extra space since one space is wasted to differentiate
122
+ * empty and full queues.
123
+ */
124
+ ctx->queueSize = queueSize + 1;
125
+ ctx->queue = (POOL_job*)ZSTD_malloc(ctx->queueSize * sizeof(POOL_job), customMem);
126
+ ctx->queueHead = 0;
127
+ ctx->queueTail = 0;
128
+ ctx->numThreadsBusy = 0;
129
+ ctx->queueEmpty = 1;
130
+ (void)ZSTD_pthread_mutex_init(&ctx->queueMutex, NULL);
131
+ (void)ZSTD_pthread_cond_init(&ctx->queuePushCond, NULL);
132
+ (void)ZSTD_pthread_cond_init(&ctx->queuePopCond, NULL);
133
+ ctx->shutdown = 0;
134
+ /* Allocate space for the thread handles */
135
+ ctx->threads = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
136
+ ctx->threadCapacity = 0;
137
+ ctx->customMem = customMem;
138
+ /* Check for errors */
139
+ if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
140
+ /* Initialize the threads */
141
+ { size_t i;
142
+ for (i = 0; i < numThreads; ++i) {
143
+ if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
144
+ ctx->threadCapacity = i;
145
+ POOL_free(ctx);
146
+ return NULL;
147
+ } }
148
+ ctx->threadCapacity = numThreads;
149
+ ctx->threadLimit = numThreads;
150
+ }
151
+ return ctx;
152
+ }
153
+
154
+ /*! POOL_join() :
155
+ Shutdown the queue, wake any sleeping threads, and join all of the threads.
156
+ */
157
+ static void POOL_join(POOL_ctx* ctx) {
158
+ /* Shut down the queue */
159
+ ZSTD_pthread_mutex_lock(&ctx->queueMutex);
160
+ ctx->shutdown = 1;
161
+ ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
162
+ /* Wake up sleeping threads */
163
+ ZSTD_pthread_cond_broadcast(&ctx->queuePushCond);
164
+ ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);
165
+ /* Join all of the threads */
166
+ { size_t i;
167
+ for (i = 0; i < ctx->threadCapacity; ++i) {
168
+ ZSTD_pthread_join(ctx->threads[i], NULL); /* note : could fail */
169
+ } }
170
+ }
171
+
172
+ void POOL_free(POOL_ctx *ctx) {
173
+ if (!ctx) { return; }
174
+ POOL_join(ctx);
175
+ ZSTD_pthread_mutex_destroy(&ctx->queueMutex);
176
+ ZSTD_pthread_cond_destroy(&ctx->queuePushCond);
177
+ ZSTD_pthread_cond_destroy(&ctx->queuePopCond);
178
+ ZSTD_free(ctx->queue, ctx->customMem);
179
+ ZSTD_free(ctx->threads, ctx->customMem);
180
+ ZSTD_free(ctx, ctx->customMem);
181
+ }
182
+
183
+
184
+
185
+ size_t POOL_sizeof(POOL_ctx *ctx) {
186
+ if (ctx==NULL) return 0; /* supports sizeof NULL */
187
+ return sizeof(*ctx)
188
+ + ctx->queueSize * sizeof(POOL_job)
189
+ + ctx->threadCapacity * sizeof(ZSTD_pthread_t);
190
+ }
191
+
192
+
193
+ /* @return : 0 on success, 1 on error */
194
+ static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
195
+ {
196
+ if (numThreads <= ctx->threadCapacity) {
197
+ if (!numThreads) return 1;
198
+ ctx->threadLimit = numThreads;
199
+ return 0;
200
+ }
201
+ /* numThreads > threadCapacity */
202
+ { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
203
+ if (!threadPool) return 1;
204
+ /* replace existing thread pool */
205
+ memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool));
206
+ ZSTD_free(ctx->threads, ctx->customMem);
207
+ ctx->threads = threadPool;
208
+ /* Initialize additional threads */
209
+ { size_t threadId;
210
+ for (threadId = ctx->threadCapacity; threadId < numThreads; ++threadId) {
211
+ if (ZSTD_pthread_create(&threadPool[threadId], NULL, &POOL_thread, ctx)) {
212
+ ctx->threadCapacity = threadId;
213
+ return 1;
214
+ } }
215
+ } }
216
+ /* successfully expanded */
217
+ ctx->threadCapacity = numThreads;
218
+ ctx->threadLimit = numThreads;
219
+ return 0;
220
+ }
221
+
222
+ /* @return : 0 on success, 1 on error */
223
+ int POOL_resize(POOL_ctx* ctx, size_t numThreads)
224
+ {
225
+ int result;
226
+ if (ctx==NULL) return 1;
227
+ ZSTD_pthread_mutex_lock(&ctx->queueMutex);
228
+ result = POOL_resize_internal(ctx, numThreads);
229
+ ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);
230
+ ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
231
+ return result;
232
+ }
233
+
234
+ /**
235
+ * Returns 1 if the queue is full and 0 otherwise.
236
+ *
237
+ * When queueSize is 1 (pool was created with an intended queueSize of 0),
238
+ * then a queue is empty if there is a thread free _and_ no job is waiting.
239
+ */
240
+ static int isQueueFull(POOL_ctx const* ctx) {
241
+ if (ctx->queueSize > 1) {
242
+ return ctx->queueHead == ((ctx->queueTail + 1) % ctx->queueSize);
243
+ } else {
244
+ return (ctx->numThreadsBusy == ctx->threadLimit) ||
245
+ !ctx->queueEmpty;
246
+ }
247
+ }
248
+
249
+
250
+ static void POOL_add_internal(POOL_ctx* ctx, POOL_function function, void *opaque)
251
+ {
252
+ POOL_job const job = {function, opaque};
253
+ assert(ctx != NULL);
254
+ if (ctx->shutdown) return;
255
+
256
+ ctx->queueEmpty = 0;
257
+ ctx->queue[ctx->queueTail] = job;
258
+ ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize;
259
+ ZSTD_pthread_cond_signal(&ctx->queuePopCond);
260
+ }
261
+
262
+ void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque)
263
+ {
264
+ assert(ctx != NULL);
265
+ ZSTD_pthread_mutex_lock(&ctx->queueMutex);
266
+ /* Wait until there is space in the queue for the new job */
267
+ while (isQueueFull(ctx) && (!ctx->shutdown)) {
268
+ ZSTD_pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex);
269
+ }
270
+ POOL_add_internal(ctx, function, opaque);
271
+ ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
272
+ }
273
+
274
+
275
+ int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque)
276
+ {
277
+ assert(ctx != NULL);
278
+ ZSTD_pthread_mutex_lock(&ctx->queueMutex);
279
+ if (isQueueFull(ctx)) {
280
+ ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
281
+ return 0;
282
+ }
283
+ POOL_add_internal(ctx, function, opaque);
284
+ ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
285
+ return 1;
286
+ }
287
+
288
+
289
+ #else /* ZSTD_MULTITHREAD not defined */
290
+
291
+ /* ========================== */
292
+ /* No multi-threading support */
293
+ /* ========================== */
294
+
295
+
296
+ /* We don't need any data, but if it is empty, malloc() might return NULL. */
297
+ struct POOL_ctx_s {
298
+ int dummy;
299
+ };
300
+ static POOL_ctx g_ctx;
301
+
302
+ POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
303
+ return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
304
+ }
305
+
306
+ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) {
307
+ (void)numThreads;
308
+ (void)queueSize;
309
+ (void)customMem;
310
+ return &g_ctx;
311
+ }
312
+
313
+ void POOL_free(POOL_ctx* ctx) {
314
+ assert(!ctx || ctx == &g_ctx);
315
+ (void)ctx;
316
+ }
317
+
318
+ int POOL_resize(POOL_ctx* ctx, size_t numThreads) {
319
+ (void)ctx; (void)numThreads;
320
+ return 0;
321
+ }
322
+
323
+ void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque) {
324
+ (void)ctx;
325
+ function(opaque);
326
+ }
327
+
328
+ int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) {
329
+ (void)ctx;
330
+ function(opaque);
331
+ return 1;
332
+ }
333
+
334
+ size_t POOL_sizeof(POOL_ctx* ctx) {
335
+ if (ctx==NULL) return 0; /* supports sizeof NULL */
336
+ assert(ctx == &g_ctx);
337
+ return sizeof(*ctx);
338
+ }
339
+
340
+ #endif /* ZSTD_MULTITHREAD */
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * 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).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #ifndef POOL_H
12
+ #define POOL_H
13
+
14
+ #if defined (__cplusplus)
15
+ extern "C" {
16
+ #endif
17
+
18
+
19
+ #include <stddef.h> /* size_t */
20
+ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_customMem */
21
+ #include "zstd.h"
22
+
23
+ typedef struct POOL_ctx_s POOL_ctx;
24
+
25
+ /*! POOL_create() :
26
+ * Create a thread pool with at most `numThreads` threads.
27
+ * `numThreads` must be at least 1.
28
+ * The maximum number of queued jobs before blocking is `queueSize`.
29
+ * @return : POOL_ctx pointer on success, else NULL.
30
+ */
31
+ POOL_ctx* POOL_create(size_t numThreads, size_t queueSize);
32
+
33
+ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
34
+ ZSTD_customMem customMem);
35
+
36
+ /*! POOL_free() :
37
+ * Free a thread pool returned by POOL_create().
38
+ */
39
+ void POOL_free(POOL_ctx* ctx);
40
+
41
+ /*! POOL_resize() :
42
+ * Expands or shrinks pool's number of threads.
43
+ * This is more efficient than releasing + creating a new context,
44
+ * since it tries to preserve and re-use existing threads.
45
+ * `numThreads` must be at least 1.
46
+ * @return : 0 when resize was successful,
47
+ * !0 (typically 1) if there is an error.
48
+ * note : only numThreads can be resized, queueSize remains unchanged.
49
+ */
50
+ int POOL_resize(POOL_ctx* ctx, size_t numThreads);
51
+
52
+ /*! POOL_sizeof() :
53
+ * @return threadpool memory usage
54
+ * note : compatible with NULL (returns 0 in this case)
55
+ */
56
+ size_t POOL_sizeof(POOL_ctx* ctx);
57
+
58
+ /*! POOL_function :
59
+ * The function type that can be added to a thread pool.
60
+ */
61
+ typedef void (*POOL_function)(void*);
62
+
63
+ /*! POOL_add() :
64
+ * Add the job `function(opaque)` to the thread pool. `ctx` must be valid.
65
+ * Possibly blocks until there is room in the queue.
66
+ * Note : The function may be executed asynchronously,
67
+ * therefore, `opaque` must live until function has been completed.
68
+ */
69
+ void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque);
70
+
71
+
72
+ /*! POOL_tryAdd() :
73
+ * Add the job `function(opaque)` to thread pool _if_ a worker is available.
74
+ * Returns immediately even if not (does not block).
75
+ * @return : 1 if successful, 0 if not.
76
+ */
77
+ int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque);
78
+
79
+
80
+ #if defined (__cplusplus)
81
+ }
82
+ #endif
83
+
84
+ #endif
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Copyright (c) 2016 Tino Reichardt
3
+ * All rights reserved.
4
+ *
5
+ * 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).
8
+ *
9
+ * You can contact the author at:
10
+ * - zstdmt source repository: https://github.com/mcmilk/zstdmt
11
+ */
12
+
13
+ /**
14
+ * This file will hold wrapper for systems, which do not support pthreads
15
+ */
16
+
17
+ /* create fake symbol to avoid empty trnaslation unit warning */
18
+ int g_ZSTD_threading_useles_symbol;
19
+
20
+ #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
21
+
22
+ /**
23
+ * Windows minimalist Pthread Wrapper, based on :
24
+ * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
25
+ */
26
+
27
+
28
+ /* === Dependencies === */
29
+ #include <process.h>
30
+ #include <errno.h>
31
+ #include "threading.h"
32
+
33
+
34
+ /* === Implementation === */
35
+
36
+ static unsigned __stdcall worker(void *arg)
37
+ {
38
+ ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
39
+ thread->arg = thread->start_routine(thread->arg);
40
+ return 0;
41
+ }
42
+
43
+ int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
44
+ void* (*start_routine) (void*), void* arg)
45
+ {
46
+ (void)unused;
47
+ thread->arg = arg;
48
+ thread->start_routine = start_routine;
49
+ thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
50
+
51
+ if (!thread->handle)
52
+ return errno;
53
+ else
54
+ return 0;
55
+ }
56
+
57
+ int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
58
+ {
59
+ DWORD result;
60
+
61
+ if (!thread.handle) return 0;
62
+
63
+ result = WaitForSingleObject(thread.handle, INFINITE);
64
+ switch (result) {
65
+ case WAIT_OBJECT_0:
66
+ if (value_ptr) *value_ptr = thread.arg;
67
+ return 0;
68
+ case WAIT_ABANDONED:
69
+ return EINVAL;
70
+ default:
71
+ return GetLastError();
72
+ }
73
+ }
74
+
75
+ #endif /* ZSTD_MULTITHREAD */
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Copyright (c) 2016 Tino Reichardt
3
+ * All rights reserved.
4
+ *
5
+ * 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).
8
+ *
9
+ * You can contact the author at:
10
+ * - zstdmt source repository: https://github.com/mcmilk/zstdmt
11
+ */
12
+
13
+ #ifndef THREADING_H_938743
14
+ #define THREADING_H_938743
15
+
16
+ #if defined (__cplusplus)
17
+ extern "C" {
18
+ #endif
19
+
20
+ #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
21
+
22
+ /**
23
+ * Windows minimalist Pthread Wrapper, based on :
24
+ * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
25
+ */
26
+ #ifdef WINVER
27
+ # undef WINVER
28
+ #endif
29
+ #define WINVER 0x0600
30
+
31
+ #ifdef _WIN32_WINNT
32
+ # undef _WIN32_WINNT
33
+ #endif
34
+ #define _WIN32_WINNT 0x0600
35
+
36
+ #ifndef WIN32_LEAN_AND_MEAN
37
+ # define WIN32_LEAN_AND_MEAN
38
+ #endif
39
+
40
+ #undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
41
+ #include <windows.h>
42
+ #undef ERROR
43
+ #define ERROR(name) ZSTD_ERROR(name)
44
+
45
+
46
+ /* mutex */
47
+ #define ZSTD_pthread_mutex_t CRITICAL_SECTION
48
+ #define ZSTD_pthread_mutex_init(a, b) ((void)(b), InitializeCriticalSection((a)), 0)
49
+ #define ZSTD_pthread_mutex_destroy(a) DeleteCriticalSection((a))
50
+ #define ZSTD_pthread_mutex_lock(a) EnterCriticalSection((a))
51
+ #define ZSTD_pthread_mutex_unlock(a) LeaveCriticalSection((a))
52
+
53
+ /* condition variable */
54
+ #define ZSTD_pthread_cond_t CONDITION_VARIABLE
55
+ #define ZSTD_pthread_cond_init(a, b) ((void)(b), InitializeConditionVariable((a)), 0)
56
+ #define ZSTD_pthread_cond_destroy(a) ((void)(a))
57
+ #define ZSTD_pthread_cond_wait(a, b) SleepConditionVariableCS((a), (b), INFINITE)
58
+ #define ZSTD_pthread_cond_signal(a) WakeConditionVariable((a))
59
+ #define ZSTD_pthread_cond_broadcast(a) WakeAllConditionVariable((a))
60
+
61
+ /* ZSTD_pthread_create() and ZSTD_pthread_join() */
62
+ typedef struct {
63
+ HANDLE handle;
64
+ void* (*start_routine)(void*);
65
+ void* arg;
66
+ } ZSTD_pthread_t;
67
+
68
+ int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
69
+ void* (*start_routine) (void*), void* arg);
70
+
71
+ int ZSTD_pthread_join(ZSTD_pthread_t thread, void** value_ptr);
72
+
73
+ /**
74
+ * add here more wrappers as required
75
+ */
76
+
77
+
78
+ #elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */
79
+ /* === POSIX Systems === */
80
+ # include <pthread.h>
81
+
82
+ #define ZSTD_pthread_mutex_t pthread_mutex_t
83
+ #define ZSTD_pthread_mutex_init(a, b) pthread_mutex_init((a), (b))
84
+ #define ZSTD_pthread_mutex_destroy(a) pthread_mutex_destroy((a))
85
+ #define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock((a))
86
+ #define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock((a))
87
+
88
+ #define ZSTD_pthread_cond_t pthread_cond_t
89
+ #define ZSTD_pthread_cond_init(a, b) pthread_cond_init((a), (b))
90
+ #define ZSTD_pthread_cond_destroy(a) pthread_cond_destroy((a))
91
+ #define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait((a), (b))
92
+ #define ZSTD_pthread_cond_signal(a) pthread_cond_signal((a))
93
+ #define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast((a))
94
+
95
+ #define ZSTD_pthread_t pthread_t
96
+ #define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))
97
+ #define ZSTD_pthread_join(a, b) pthread_join((a),(b))
98
+
99
+ #else /* ZSTD_MULTITHREAD not defined */
100
+ /* No multithreading support */
101
+
102
+ typedef int ZSTD_pthread_mutex_t;
103
+ #define ZSTD_pthread_mutex_init(a, b) ((void)(a), (void)(b), 0)
104
+ #define ZSTD_pthread_mutex_destroy(a) ((void)(a))
105
+ #define ZSTD_pthread_mutex_lock(a) ((void)(a))
106
+ #define ZSTD_pthread_mutex_unlock(a) ((void)(a))
107
+
108
+ typedef int ZSTD_pthread_cond_t;
109
+ #define ZSTD_pthread_cond_init(a, b) ((void)(a), (void)(b), 0)
110
+ #define ZSTD_pthread_cond_destroy(a) ((void)(a))
111
+ #define ZSTD_pthread_cond_wait(a, b) ((void)(a), (void)(b))
112
+ #define ZSTD_pthread_cond_signal(a) ((void)(a))
113
+ #define ZSTD_pthread_cond_broadcast(a) ((void)(a))
114
+
115
+ /* do not use ZSTD_pthread_t */
116
+
117
+ #endif /* ZSTD_MULTITHREAD */
118
+
119
+ #if defined (__cplusplus)
120
+ }
121
+ #endif
122
+
123
+ #endif /* THREADING_H_938743 */