extzstd 0.1.1 → 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/HISTORY.ja.md +18 -0
- data/README.md +15 -50
- data/contrib/zstd/CONTRIBUTING.md +1 -1
- data/contrib/zstd/COPYING +339 -0
- data/contrib/zstd/Makefile +82 -51
- data/contrib/zstd/NEWS +92 -5
- data/contrib/zstd/README.md +50 -41
- data/contrib/zstd/appveyor.yml +164 -102
- data/contrib/zstd/circle.yml +10 -22
- data/contrib/zstd/lib/BUCK +31 -10
- data/contrib/zstd/lib/Makefile +57 -31
- data/contrib/zstd/lib/README.md +68 -37
- data/contrib/zstd/lib/common/bitstream.h +130 -76
- data/contrib/zstd/lib/common/compiler.h +86 -0
- data/contrib/zstd/lib/common/error_private.c +15 -11
- data/contrib/zstd/lib/common/error_private.h +8 -8
- data/contrib/zstd/lib/common/fse.h +19 -9
- data/contrib/zstd/lib/common/fse_decompress.c +3 -22
- data/contrib/zstd/lib/common/huf.h +68 -26
- data/contrib/zstd/lib/common/mem.h +23 -35
- data/contrib/zstd/lib/common/pool.c +123 -63
- data/contrib/zstd/lib/common/pool.h +19 -10
- data/contrib/zstd/lib/common/threading.c +11 -16
- data/contrib/zstd/lib/common/threading.h +52 -33
- data/contrib/zstd/lib/common/xxhash.c +28 -22
- data/contrib/zstd/lib/common/zstd_common.c +40 -27
- data/contrib/zstd/lib/common/zstd_errors.h +43 -34
- data/contrib/zstd/lib/common/zstd_internal.h +131 -123
- data/contrib/zstd/lib/compress/fse_compress.c +17 -33
- data/contrib/zstd/lib/compress/huf_compress.c +15 -9
- data/contrib/zstd/lib/compress/zstd_compress.c +2096 -2363
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +462 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.c +309 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.h +29 -0
- data/contrib/zstd/lib/compress/zstd_fast.c +243 -0
- data/contrib/zstd/lib/compress/zstd_fast.h +31 -0
- data/contrib/zstd/lib/compress/zstd_lazy.c +765 -0
- data/contrib/zstd/lib/compress/zstd_lazy.h +39 -0
- data/contrib/zstd/lib/compress/zstd_ldm.c +707 -0
- data/contrib/zstd/lib/compress/zstd_ldm.h +68 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +785 -0
- data/contrib/zstd/lib/compress/zstd_opt.h +19 -908
- data/contrib/zstd/lib/compress/zstdmt_compress.c +737 -327
- data/contrib/zstd/lib/compress/zstdmt_compress.h +88 -26
- data/contrib/zstd/lib/decompress/huf_decompress.c +158 -50
- data/contrib/zstd/lib/decompress/zstd_decompress.c +884 -699
- data/contrib/zstd/lib/deprecated/zbuff.h +5 -4
- data/contrib/zstd/lib/deprecated/zbuff_common.c +5 -5
- data/contrib/zstd/lib/deprecated/zbuff_compress.c +6 -4
- data/contrib/zstd/lib/deprecated/zbuff_decompress.c +5 -4
- data/contrib/zstd/lib/dictBuilder/cover.c +93 -77
- data/contrib/zstd/lib/dictBuilder/zdict.c +107 -92
- data/contrib/zstd/lib/dictBuilder/zdict.h +112 -102
- data/contrib/zstd/lib/legacy/zstd_legacy.h +9 -4
- data/contrib/zstd/lib/legacy/zstd_v01.c +7 -6
- data/contrib/zstd/lib/legacy/zstd_v01.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v02.c +27 -99
- data/contrib/zstd/lib/legacy/zstd_v02.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v03.c +26 -98
- data/contrib/zstd/lib/legacy/zstd_v03.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v04.c +22 -91
- data/contrib/zstd/lib/legacy/zstd_v04.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v05.c +23 -99
- data/contrib/zstd/lib/legacy/zstd_v05.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v06.c +22 -96
- data/contrib/zstd/lib/legacy/zstd_v06.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v07.c +19 -95
- data/contrib/zstd/lib/legacy/zstd_v07.h +5 -4
- data/contrib/zstd/lib/zstd.h +895 -271
- data/ext/extconf.rb +11 -2
- data/ext/extzstd.c +45 -128
- data/ext/extzstd.h +74 -31
- data/ext/extzstd_stream.c +401 -142
- data/ext/zstd_common.c +5 -0
- data/ext/zstd_compress.c +8 -0
- data/ext/zstd_decompress.c +1 -0
- data/ext/zstd_dictbuilder.c +2 -0
- data/lib/extzstd/version.rb +1 -1
- data/lib/extzstd.rb +48 -1
- data/test/test_basic.rb +9 -1
- metadata +17 -7
- data/HISTORY.ja +0 -10
- data/contrib/zstd/LICENSE-examples +0 -11
- data/contrib/zstd/PATENTS +0 -33
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
* Copyright (c) 2016-present, Facebook, Inc.
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
|
-
* This source code is licensed under the BSD-style license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree
|
|
7
|
-
*
|
|
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.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
/* ====== Dependencies ======= */
|
|
12
13
|
#include <stddef.h> /* size_t */
|
|
13
|
-
#include <stdlib.h> /* malloc, calloc, free */
|
|
14
14
|
#include "pool.h"
|
|
15
15
|
|
|
16
16
|
/* ====== Compiler specifics ====== */
|
|
@@ -25,13 +25,14 @@
|
|
|
25
25
|
|
|
26
26
|
/* A job is a function and an opaque argument */
|
|
27
27
|
typedef struct POOL_job_s {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
POOL_function function;
|
|
29
|
+
void *opaque;
|
|
30
30
|
} POOL_job;
|
|
31
31
|
|
|
32
32
|
struct POOL_ctx_s {
|
|
33
|
+
ZSTD_customMem customMem;
|
|
33
34
|
/* Keep track of the threads */
|
|
34
|
-
|
|
35
|
+
ZSTD_pthread_t *threads;
|
|
35
36
|
size_t numThreads;
|
|
36
37
|
|
|
37
38
|
/* The queue is a circular buffer */
|
|
@@ -39,12 +40,18 @@ struct POOL_ctx_s {
|
|
|
39
40
|
size_t queueHead;
|
|
40
41
|
size_t queueTail;
|
|
41
42
|
size_t queueSize;
|
|
43
|
+
|
|
44
|
+
/* The number of threads working on jobs */
|
|
45
|
+
size_t numThreadsBusy;
|
|
46
|
+
/* Indicates if the queue is empty */
|
|
47
|
+
int queueEmpty;
|
|
48
|
+
|
|
42
49
|
/* The mutex protects the queue */
|
|
43
|
-
|
|
50
|
+
ZSTD_pthread_mutex_t queueMutex;
|
|
44
51
|
/* Condition variable for pushers to wait on when the queue is full */
|
|
45
|
-
|
|
52
|
+
ZSTD_pthread_cond_t queuePushCond;
|
|
46
53
|
/* Condition variables for poppers to wait on when the queue is empty */
|
|
47
|
-
|
|
54
|
+
ZSTD_pthread_cond_t queuePopCond;
|
|
48
55
|
/* Indicates if the queue is shutting down */
|
|
49
56
|
int shutdown;
|
|
50
57
|
};
|
|
@@ -59,55 +66,73 @@ static void* POOL_thread(void* opaque) {
|
|
|
59
66
|
if (!ctx) { return NULL; }
|
|
60
67
|
for (;;) {
|
|
61
68
|
/* Lock the mutex and wait for a non-empty queue or until shutdown */
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
70
|
+
|
|
71
|
+
while (ctx->queueEmpty && !ctx->shutdown) {
|
|
72
|
+
ZSTD_pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex);
|
|
65
73
|
}
|
|
66
74
|
/* empty => shutting down: so stop */
|
|
67
|
-
if (ctx->
|
|
68
|
-
|
|
75
|
+
if (ctx->queueEmpty) {
|
|
76
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
69
77
|
return opaque;
|
|
70
78
|
}
|
|
71
79
|
/* Pop a job off the queue */
|
|
72
80
|
{ POOL_job const job = ctx->queue[ctx->queueHead];
|
|
73
81
|
ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;
|
|
82
|
+
ctx->numThreadsBusy++;
|
|
83
|
+
ctx->queueEmpty = ctx->queueHead == ctx->queueTail;
|
|
74
84
|
/* Unlock the mutex, signal a pusher, and run the job */
|
|
75
|
-
|
|
76
|
-
|
|
85
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
86
|
+
ZSTD_pthread_cond_signal(&ctx->queuePushCond);
|
|
87
|
+
|
|
77
88
|
job.function(job.opaque);
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
|
|
90
|
+
/* If the intended queue size was 0, signal after finishing job */
|
|
91
|
+
if (ctx->queueSize == 1) {
|
|
92
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
93
|
+
ctx->numThreadsBusy--;
|
|
94
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
95
|
+
ZSTD_pthread_cond_signal(&ctx->queuePushCond);
|
|
96
|
+
} }
|
|
97
|
+
} /* for (;;) */
|
|
80
98
|
/* Unreachable */
|
|
81
99
|
}
|
|
82
100
|
|
|
83
|
-
POOL_ctx
|
|
84
|
-
|
|
101
|
+
POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
|
|
102
|
+
return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) {
|
|
106
|
+
POOL_ctx* ctx;
|
|
85
107
|
/* Check the parameters */
|
|
86
|
-
if (!numThreads
|
|
108
|
+
if (!numThreads) { return NULL; }
|
|
87
109
|
/* Allocate the context and zero initialize */
|
|
88
|
-
ctx = (POOL_ctx
|
|
110
|
+
ctx = (POOL_ctx*)ZSTD_calloc(sizeof(POOL_ctx), customMem);
|
|
89
111
|
if (!ctx) { return NULL; }
|
|
90
112
|
/* Initialize the job queue.
|
|
91
113
|
* It needs one extra space since one space is wasted to differentiate empty
|
|
92
114
|
* and full queues.
|
|
93
115
|
*/
|
|
94
116
|
ctx->queueSize = queueSize + 1;
|
|
95
|
-
ctx->queue = (POOL_job
|
|
117
|
+
ctx->queue = (POOL_job*)ZSTD_malloc(ctx->queueSize * sizeof(POOL_job), customMem);
|
|
96
118
|
ctx->queueHead = 0;
|
|
97
119
|
ctx->queueTail = 0;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
120
|
+
ctx->numThreadsBusy = 0;
|
|
121
|
+
ctx->queueEmpty = 1;
|
|
122
|
+
(void)ZSTD_pthread_mutex_init(&ctx->queueMutex, NULL);
|
|
123
|
+
(void)ZSTD_pthread_cond_init(&ctx->queuePushCond, NULL);
|
|
124
|
+
(void)ZSTD_pthread_cond_init(&ctx->queuePopCond, NULL);
|
|
101
125
|
ctx->shutdown = 0;
|
|
102
126
|
/* Allocate space for the thread handles */
|
|
103
|
-
ctx->threads = (
|
|
127
|
+
ctx->threads = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
|
|
104
128
|
ctx->numThreads = 0;
|
|
129
|
+
ctx->customMem = customMem;
|
|
105
130
|
/* Check for errors */
|
|
106
131
|
if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
|
|
107
132
|
/* Initialize the threads */
|
|
108
133
|
{ size_t i;
|
|
109
134
|
for (i = 0; i < numThreads; ++i) {
|
|
110
|
-
if (
|
|
135
|
+
if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
|
|
111
136
|
ctx->numThreads = i;
|
|
112
137
|
POOL_free(ctx);
|
|
113
138
|
return NULL;
|
|
@@ -120,52 +145,74 @@ POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) {
|
|
|
120
145
|
/*! POOL_join() :
|
|
121
146
|
Shutdown the queue, wake any sleeping threads, and join all of the threads.
|
|
122
147
|
*/
|
|
123
|
-
static void POOL_join(POOL_ctx
|
|
148
|
+
static void POOL_join(POOL_ctx* ctx) {
|
|
124
149
|
/* Shut down the queue */
|
|
125
|
-
|
|
150
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
126
151
|
ctx->shutdown = 1;
|
|
127
|
-
|
|
152
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
128
153
|
/* Wake up sleeping threads */
|
|
129
|
-
|
|
130
|
-
|
|
154
|
+
ZSTD_pthread_cond_broadcast(&ctx->queuePushCond);
|
|
155
|
+
ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);
|
|
131
156
|
/* Join all of the threads */
|
|
132
157
|
{ size_t i;
|
|
133
158
|
for (i = 0; i < ctx->numThreads; ++i) {
|
|
134
|
-
|
|
159
|
+
ZSTD_pthread_join(ctx->threads[i], NULL);
|
|
135
160
|
} }
|
|
136
161
|
}
|
|
137
162
|
|
|
138
163
|
void POOL_free(POOL_ctx *ctx) {
|
|
139
164
|
if (!ctx) { return; }
|
|
140
165
|
POOL_join(ctx);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
166
|
+
ZSTD_pthread_mutex_destroy(&ctx->queueMutex);
|
|
167
|
+
ZSTD_pthread_cond_destroy(&ctx->queuePushCond);
|
|
168
|
+
ZSTD_pthread_cond_destroy(&ctx->queuePopCond);
|
|
169
|
+
ZSTD_free(ctx->queue, ctx->customMem);
|
|
170
|
+
ZSTD_free(ctx->threads, ctx->customMem);
|
|
171
|
+
ZSTD_free(ctx, ctx->customMem);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
size_t POOL_sizeof(POOL_ctx *ctx) {
|
|
175
|
+
if (ctx==NULL) return 0; /* supports sizeof NULL */
|
|
176
|
+
return sizeof(*ctx)
|
|
177
|
+
+ ctx->queueSize * sizeof(POOL_job)
|
|
178
|
+
+ ctx->numThreads * sizeof(ZSTD_pthread_t);
|
|
147
179
|
}
|
|
148
180
|
|
|
149
|
-
|
|
150
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Returns 1 if the queue is full and 0 otherwise.
|
|
183
|
+
*
|
|
184
|
+
* If the queueSize is 1 (the pool was created with an intended queueSize of 0),
|
|
185
|
+
* then a queue is empty if there is a thread free and no job is waiting.
|
|
186
|
+
*/
|
|
187
|
+
static int isQueueFull(POOL_ctx const* ctx) {
|
|
188
|
+
if (ctx->queueSize > 1) {
|
|
189
|
+
return ctx->queueHead == ((ctx->queueTail + 1) % ctx->queueSize);
|
|
190
|
+
} else {
|
|
191
|
+
return ctx->numThreadsBusy == ctx->numThreads ||
|
|
192
|
+
!ctx->queueEmpty;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
void POOL_add(void* ctxVoid, POOL_function function, void *opaque) {
|
|
197
|
+
POOL_ctx* const ctx = (POOL_ctx*)ctxVoid;
|
|
151
198
|
if (!ctx) { return; }
|
|
152
199
|
|
|
153
|
-
|
|
200
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
154
201
|
{ POOL_job const job = {function, opaque};
|
|
202
|
+
|
|
155
203
|
/* Wait until there is space in the queue for the new job */
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex);
|
|
159
|
-
newTail = (ctx->queueTail + 1) % ctx->queueSize;
|
|
204
|
+
while (isQueueFull(ctx) && !ctx->shutdown) {
|
|
205
|
+
ZSTD_pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex);
|
|
160
206
|
}
|
|
161
207
|
/* The queue is still going => there is space */
|
|
162
208
|
if (!ctx->shutdown) {
|
|
209
|
+
ctx->queueEmpty = 0;
|
|
163
210
|
ctx->queue[ctx->queueTail] = job;
|
|
164
|
-
ctx->queueTail =
|
|
211
|
+
ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize;
|
|
165
212
|
}
|
|
166
213
|
}
|
|
167
|
-
|
|
168
|
-
|
|
214
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
215
|
+
ZSTD_pthread_cond_signal(&ctx->queuePopCond);
|
|
169
216
|
}
|
|
170
217
|
|
|
171
218
|
#else /* ZSTD_MULTITHREAD not defined */
|
|
@@ -173,22 +220,35 @@ void POOL_add(void *ctxVoid, POOL_function function, void *opaque) {
|
|
|
173
220
|
|
|
174
221
|
/* We don't need any data, but if it is empty malloc() might return NULL. */
|
|
175
222
|
struct POOL_ctx_s {
|
|
176
|
-
|
|
223
|
+
int dummy;
|
|
177
224
|
};
|
|
225
|
+
static POOL_ctx g_ctx;
|
|
178
226
|
|
|
179
|
-
POOL_ctx
|
|
180
|
-
|
|
181
|
-
(void)queueSize;
|
|
182
|
-
return (POOL_ctx *)malloc(sizeof(POOL_ctx));
|
|
227
|
+
POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
|
|
228
|
+
return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
|
|
183
229
|
}
|
|
184
230
|
|
|
185
|
-
|
|
186
|
-
|
|
231
|
+
POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) {
|
|
232
|
+
(void)numThreads;
|
|
233
|
+
(void)queueSize;
|
|
234
|
+
(void)customMem;
|
|
235
|
+
return &g_ctx;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
void POOL_free(POOL_ctx* ctx) {
|
|
239
|
+
assert(!ctx || ctx == &g_ctx);
|
|
240
|
+
(void)ctx;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
void POOL_add(void* ctx, POOL_function function, void* opaque) {
|
|
244
|
+
(void)ctx;
|
|
245
|
+
function(opaque);
|
|
187
246
|
}
|
|
188
247
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
248
|
+
size_t POOL_sizeof(POOL_ctx* ctx) {
|
|
249
|
+
if (ctx==NULL) return 0; /* supports sizeof NULL */
|
|
250
|
+
assert(ctx == &g_ctx);
|
|
251
|
+
return sizeof(*ctx);
|
|
192
252
|
}
|
|
193
253
|
|
|
194
254
|
#endif /* ZSTD_MULTITHREAD */
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
* Copyright (c) 2016-present, Facebook, Inc.
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
|
-
* This source code is licensed under the BSD-style license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree
|
|
7
|
-
*
|
|
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.
|
|
8
9
|
*/
|
|
10
|
+
|
|
9
11
|
#ifndef POOL_H
|
|
10
12
|
#define POOL_H
|
|
11
13
|
|
|
@@ -15,23 +17,30 @@ extern "C" {
|
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
#include <stddef.h> /* size_t */
|
|
20
|
+
#include "zstd_internal.h" /* ZSTD_customMem */
|
|
18
21
|
|
|
19
22
|
typedef struct POOL_ctx_s POOL_ctx;
|
|
20
23
|
|
|
21
24
|
/*! POOL_create() :
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@return : The POOL_ctx pointer on success else NULL.
|
|
25
|
+
* Create a thread pool with at most `numThreads` threads.
|
|
26
|
+
* `numThreads` must be at least 1.
|
|
27
|
+
* The maximum number of queued jobs before blocking is `queueSize`.
|
|
28
|
+
* @return : POOL_ctx pointer on success, else NULL.
|
|
27
29
|
*/
|
|
28
30
|
POOL_ctx *POOL_create(size_t numThreads, size_t queueSize);
|
|
29
31
|
|
|
32
|
+
POOL_ctx *POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem);
|
|
33
|
+
|
|
30
34
|
/*! POOL_free() :
|
|
31
35
|
Free a thread pool returned by POOL_create().
|
|
32
36
|
*/
|
|
33
37
|
void POOL_free(POOL_ctx *ctx);
|
|
34
38
|
|
|
39
|
+
/*! POOL_sizeof() :
|
|
40
|
+
return memory usage of pool returned by POOL_create().
|
|
41
|
+
*/
|
|
42
|
+
size_t POOL_sizeof(POOL_ctx *ctx);
|
|
43
|
+
|
|
35
44
|
/*! POOL_function :
|
|
36
45
|
The function type that can be added to a thread pool.
|
|
37
46
|
*/
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
1
|
/**
|
|
3
2
|
* Copyright (c) 2016 Tino Reichardt
|
|
4
3
|
* All rights reserved.
|
|
5
4
|
*
|
|
6
|
-
* This source code is licensed under the BSD-style license found in the
|
|
7
|
-
* LICENSE file in the root directory of this source tree
|
|
8
|
-
*
|
|
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).
|
|
9
8
|
*
|
|
10
9
|
* You can contact the author at:
|
|
11
10
|
* - zstdmt source repository: https://github.com/mcmilk/zstdmt
|
|
@@ -15,12 +14,8 @@
|
|
|
15
14
|
* This file will hold wrapper for systems, which do not support pthreads
|
|
16
15
|
*/
|
|
17
16
|
|
|
18
|
-
/*
|
|
19
|
-
|
|
20
|
-
* (Visual C++: C4206 / GCC: -Wpedantic / Clang: -Wempty-translation-unit)
|
|
21
|
-
*/
|
|
22
|
-
#include <stddef.h>
|
|
23
|
-
|
|
17
|
+
/* create fake symbol to avoid empty trnaslation unit warning */
|
|
18
|
+
int g_ZSTD_threading_useles_symbol;
|
|
24
19
|
|
|
25
20
|
#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
|
|
26
21
|
|
|
@@ -40,12 +35,12 @@
|
|
|
40
35
|
|
|
41
36
|
static unsigned __stdcall worker(void *arg)
|
|
42
37
|
{
|
|
43
|
-
|
|
38
|
+
ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
|
|
44
39
|
thread->arg = thread->start_routine(thread->arg);
|
|
45
40
|
return 0;
|
|
46
41
|
}
|
|
47
42
|
|
|
48
|
-
int
|
|
43
|
+
int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
|
|
49
44
|
void* (*start_routine) (void*), void* arg)
|
|
50
45
|
{
|
|
51
46
|
(void)unused;
|
|
@@ -59,16 +54,16 @@ int pthread_create(pthread_t* thread, const void* unused,
|
|
|
59
54
|
return 0;
|
|
60
55
|
}
|
|
61
56
|
|
|
62
|
-
int
|
|
57
|
+
int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
|
|
63
58
|
{
|
|
64
59
|
DWORD result;
|
|
65
60
|
|
|
66
|
-
if (!thread
|
|
61
|
+
if (!thread.handle) return 0;
|
|
67
62
|
|
|
68
|
-
result = WaitForSingleObject(thread
|
|
63
|
+
result = WaitForSingleObject(thread.handle, INFINITE);
|
|
69
64
|
switch (result) {
|
|
70
65
|
case WAIT_OBJECT_0:
|
|
71
|
-
if (value_ptr) *value_ptr = thread
|
|
66
|
+
if (value_ptr) *value_ptr = thread.arg;
|
|
72
67
|
return 0;
|
|
73
68
|
case WAIT_ABANDONED:
|
|
74
69
|
return EINVAL;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
1
|
/**
|
|
3
2
|
* Copyright (c) 2016 Tino Reichardt
|
|
4
3
|
* All rights reserved.
|
|
5
4
|
*
|
|
6
|
-
* This source code is licensed under the BSD-style license found in the
|
|
7
|
-
* LICENSE file in the root directory of this source tree
|
|
8
|
-
*
|
|
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).
|
|
9
8
|
*
|
|
10
9
|
* You can contact the author at:
|
|
11
10
|
* - zstdmt source repository: https://github.com/mcmilk/zstdmt
|
|
@@ -38,35 +37,38 @@ extern "C" {
|
|
|
38
37
|
# define WIN32_LEAN_AND_MEAN
|
|
39
38
|
#endif
|
|
40
39
|
|
|
40
|
+
#undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
|
|
41
41
|
#include <windows.h>
|
|
42
|
+
#undef ERROR
|
|
43
|
+
#define ERROR(name) ZSTD_ERROR(name)
|
|
44
|
+
|
|
42
45
|
|
|
43
46
|
/* mutex */
|
|
44
|
-
#define
|
|
45
|
-
#define
|
|
46
|
-
#define
|
|
47
|
-
#define
|
|
48
|
-
#define
|
|
47
|
+
#define ZSTD_pthread_mutex_t CRITICAL_SECTION
|
|
48
|
+
#define ZSTD_pthread_mutex_init(a, 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))
|
|
49
52
|
|
|
50
53
|
/* condition variable */
|
|
51
|
-
#define
|
|
52
|
-
#define
|
|
53
|
-
#define
|
|
54
|
-
#define
|
|
55
|
-
#define
|
|
56
|
-
#define
|
|
57
|
-
|
|
58
|
-
/*
|
|
54
|
+
#define ZSTD_pthread_cond_t CONDITION_VARIABLE
|
|
55
|
+
#define ZSTD_pthread_cond_init(a, b) (InitializeConditionVariable((a)), 0)
|
|
56
|
+
#define ZSTD_pthread_cond_destroy(a) /* No delete */
|
|
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() */
|
|
59
62
|
typedef struct {
|
|
60
63
|
HANDLE handle;
|
|
61
64
|
void* (*start_routine)(void*);
|
|
62
65
|
void* arg;
|
|
63
|
-
}
|
|
66
|
+
} ZSTD_pthread_t;
|
|
64
67
|
|
|
65
|
-
int
|
|
68
|
+
int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
|
|
66
69
|
void* (*start_routine) (void*), void* arg);
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
int _pthread_join(pthread_t* thread, void** value_ptr);
|
|
71
|
+
int ZSTD_pthread_join(ZSTD_pthread_t thread, void** value_ptr);
|
|
70
72
|
|
|
71
73
|
/**
|
|
72
74
|
* add here more wrappers as required
|
|
@@ -77,23 +79,40 @@ int _pthread_join(pthread_t* thread, void** value_ptr);
|
|
|
77
79
|
/* === POSIX Systems === */
|
|
78
80
|
# include <pthread.h>
|
|
79
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
|
+
|
|
80
99
|
#else /* ZSTD_MULTITHREAD not defined */
|
|
81
100
|
/* No multithreading support */
|
|
82
101
|
|
|
83
|
-
|
|
84
|
-
#define
|
|
85
|
-
#define
|
|
86
|
-
#define
|
|
87
|
-
#define
|
|
102
|
+
typedef int ZSTD_pthread_mutex_t;
|
|
103
|
+
#define ZSTD_pthread_mutex_init(a, b) ((void)a, 0)
|
|
104
|
+
#define ZSTD_pthread_mutex_destroy(a)
|
|
105
|
+
#define ZSTD_pthread_mutex_lock(a)
|
|
106
|
+
#define ZSTD_pthread_mutex_unlock(a)
|
|
88
107
|
|
|
89
|
-
|
|
90
|
-
#define
|
|
91
|
-
#define
|
|
92
|
-
#define
|
|
93
|
-
#define
|
|
94
|
-
#define
|
|
108
|
+
typedef int ZSTD_pthread_cond_t;
|
|
109
|
+
#define ZSTD_pthread_cond_init(a, b) ((void)a, 0)
|
|
110
|
+
#define ZSTD_pthread_cond_destroy(a)
|
|
111
|
+
#define ZSTD_pthread_cond_wait(a, b)
|
|
112
|
+
#define ZSTD_pthread_cond_signal(a)
|
|
113
|
+
#define ZSTD_pthread_cond_broadcast(a)
|
|
95
114
|
|
|
96
|
-
/* do not use
|
|
115
|
+
/* do not use ZSTD_pthread_t */
|
|
97
116
|
|
|
98
117
|
#endif /* ZSTD_MULTITHREAD */
|
|
99
118
|
|
|
@@ -113,19 +113,25 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp
|
|
|
113
113
|
/* *************************************
|
|
114
114
|
* Compiler Specific Options
|
|
115
115
|
***************************************/
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
# define FORCE_INLINE static __forceinline
|
|
116
|
+
#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
|
117
|
+
# define INLINE_KEYWORD inline
|
|
119
118
|
#else
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
|
|
123
|
-
#
|
|
124
|
-
#
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
#
|
|
128
|
-
#
|
|
119
|
+
# define INLINE_KEYWORD
|
|
120
|
+
#endif
|
|
121
|
+
|
|
122
|
+
#if defined(__GNUC__)
|
|
123
|
+
# define FORCE_INLINE_ATTR __attribute__((always_inline))
|
|
124
|
+
#elif defined(_MSC_VER)
|
|
125
|
+
# define FORCE_INLINE_ATTR __forceinline
|
|
126
|
+
#else
|
|
127
|
+
# define FORCE_INLINE_ATTR
|
|
128
|
+
#endif
|
|
129
|
+
|
|
130
|
+
#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
#ifdef _MSC_VER
|
|
134
|
+
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
|
129
135
|
#endif
|
|
130
136
|
|
|
131
137
|
|
|
@@ -248,7 +254,7 @@ typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
|
|
|
248
254
|
*****************************/
|
|
249
255
|
typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
|
|
250
256
|
|
|
251
|
-
|
|
257
|
+
FORCE_INLINE_TEMPLATE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
|
|
252
258
|
{
|
|
253
259
|
if (align==XXH_unaligned)
|
|
254
260
|
return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
|
|
@@ -256,7 +262,7 @@ FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_a
|
|
|
256
262
|
return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
|
|
257
263
|
}
|
|
258
264
|
|
|
259
|
-
|
|
265
|
+
FORCE_INLINE_TEMPLATE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
|
|
260
266
|
{
|
|
261
267
|
return XXH_readLE32_align(ptr, endian, XXH_unaligned);
|
|
262
268
|
}
|
|
@@ -266,7 +272,7 @@ static U32 XXH_readBE32(const void* ptr)
|
|
|
266
272
|
return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
|
|
267
273
|
}
|
|
268
274
|
|
|
269
|
-
|
|
275
|
+
FORCE_INLINE_TEMPLATE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
|
|
270
276
|
{
|
|
271
277
|
if (align==XXH_unaligned)
|
|
272
278
|
return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
|
|
@@ -274,7 +280,7 @@ FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_a
|
|
|
274
280
|
return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
|
|
275
281
|
}
|
|
276
282
|
|
|
277
|
-
|
|
283
|
+
FORCE_INLINE_TEMPLATE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
|
|
278
284
|
{
|
|
279
285
|
return XXH_readLE64_align(ptr, endian, XXH_unaligned);
|
|
280
286
|
}
|
|
@@ -335,7 +341,7 @@ static U32 XXH32_round(U32 seed, U32 input)
|
|
|
335
341
|
return seed;
|
|
336
342
|
}
|
|
337
343
|
|
|
338
|
-
|
|
344
|
+
FORCE_INLINE_TEMPLATE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
|
|
339
345
|
{
|
|
340
346
|
const BYTE* p = (const BYTE*)input;
|
|
341
347
|
const BYTE* bEnd = p + len;
|
|
@@ -435,7 +441,7 @@ static U64 XXH64_mergeRound(U64 acc, U64 val)
|
|
|
435
441
|
return acc;
|
|
436
442
|
}
|
|
437
443
|
|
|
438
|
-
|
|
444
|
+
FORCE_INLINE_TEMPLATE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
|
|
439
445
|
{
|
|
440
446
|
const BYTE* p = (const BYTE*)input;
|
|
441
447
|
const BYTE* const bEnd = p + len;
|
|
@@ -584,7 +590,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long
|
|
|
584
590
|
}
|
|
585
591
|
|
|
586
592
|
|
|
587
|
-
|
|
593
|
+
FORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
|
|
588
594
|
{
|
|
589
595
|
const BYTE* p = (const BYTE*)input;
|
|
590
596
|
const BYTE* const bEnd = p + len;
|
|
@@ -654,7 +660,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void*
|
|
|
654
660
|
|
|
655
661
|
|
|
656
662
|
|
|
657
|
-
|
|
663
|
+
FORCE_INLINE_TEMPLATE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
|
|
658
664
|
{
|
|
659
665
|
const BYTE * p = (const BYTE*)state->mem32;
|
|
660
666
|
const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize;
|
|
@@ -704,7 +710,7 @@ XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
|
|
|
704
710
|
|
|
705
711
|
/* **** XXH64 **** */
|
|
706
712
|
|
|
707
|
-
|
|
713
|
+
FORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
|
|
708
714
|
{
|
|
709
715
|
const BYTE* p = (const BYTE*)input;
|
|
710
716
|
const BYTE* const bEnd = p + len;
|
|
@@ -771,7 +777,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void*
|
|
|
771
777
|
|
|
772
778
|
|
|
773
779
|
|
|
774
|
-
|
|
780
|
+
FORCE_INLINE_TEMPLATE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
|
|
775
781
|
{
|
|
776
782
|
const BYTE * p = (const BYTE*)state->mem64;
|
|
777
783
|
const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize;
|