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.
Files changed (85) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.ja.md +18 -0
  3. data/README.md +15 -50
  4. data/contrib/zstd/CONTRIBUTING.md +1 -1
  5. data/contrib/zstd/COPYING +339 -0
  6. data/contrib/zstd/Makefile +82 -51
  7. data/contrib/zstd/NEWS +92 -5
  8. data/contrib/zstd/README.md +50 -41
  9. data/contrib/zstd/appveyor.yml +164 -102
  10. data/contrib/zstd/circle.yml +10 -22
  11. data/contrib/zstd/lib/BUCK +31 -10
  12. data/contrib/zstd/lib/Makefile +57 -31
  13. data/contrib/zstd/lib/README.md +68 -37
  14. data/contrib/zstd/lib/common/bitstream.h +130 -76
  15. data/contrib/zstd/lib/common/compiler.h +86 -0
  16. data/contrib/zstd/lib/common/error_private.c +15 -11
  17. data/contrib/zstd/lib/common/error_private.h +8 -8
  18. data/contrib/zstd/lib/common/fse.h +19 -9
  19. data/contrib/zstd/lib/common/fse_decompress.c +3 -22
  20. data/contrib/zstd/lib/common/huf.h +68 -26
  21. data/contrib/zstd/lib/common/mem.h +23 -35
  22. data/contrib/zstd/lib/common/pool.c +123 -63
  23. data/contrib/zstd/lib/common/pool.h +19 -10
  24. data/contrib/zstd/lib/common/threading.c +11 -16
  25. data/contrib/zstd/lib/common/threading.h +52 -33
  26. data/contrib/zstd/lib/common/xxhash.c +28 -22
  27. data/contrib/zstd/lib/common/zstd_common.c +40 -27
  28. data/contrib/zstd/lib/common/zstd_errors.h +43 -34
  29. data/contrib/zstd/lib/common/zstd_internal.h +131 -123
  30. data/contrib/zstd/lib/compress/fse_compress.c +17 -33
  31. data/contrib/zstd/lib/compress/huf_compress.c +15 -9
  32. data/contrib/zstd/lib/compress/zstd_compress.c +2096 -2363
  33. data/contrib/zstd/lib/compress/zstd_compress_internal.h +462 -0
  34. data/contrib/zstd/lib/compress/zstd_double_fast.c +309 -0
  35. data/contrib/zstd/lib/compress/zstd_double_fast.h +29 -0
  36. data/contrib/zstd/lib/compress/zstd_fast.c +243 -0
  37. data/contrib/zstd/lib/compress/zstd_fast.h +31 -0
  38. data/contrib/zstd/lib/compress/zstd_lazy.c +765 -0
  39. data/contrib/zstd/lib/compress/zstd_lazy.h +39 -0
  40. data/contrib/zstd/lib/compress/zstd_ldm.c +707 -0
  41. data/contrib/zstd/lib/compress/zstd_ldm.h +68 -0
  42. data/contrib/zstd/lib/compress/zstd_opt.c +785 -0
  43. data/contrib/zstd/lib/compress/zstd_opt.h +19 -908
  44. data/contrib/zstd/lib/compress/zstdmt_compress.c +737 -327
  45. data/contrib/zstd/lib/compress/zstdmt_compress.h +88 -26
  46. data/contrib/zstd/lib/decompress/huf_decompress.c +158 -50
  47. data/contrib/zstd/lib/decompress/zstd_decompress.c +884 -699
  48. data/contrib/zstd/lib/deprecated/zbuff.h +5 -4
  49. data/contrib/zstd/lib/deprecated/zbuff_common.c +5 -5
  50. data/contrib/zstd/lib/deprecated/zbuff_compress.c +6 -4
  51. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +5 -4
  52. data/contrib/zstd/lib/dictBuilder/cover.c +93 -77
  53. data/contrib/zstd/lib/dictBuilder/zdict.c +107 -92
  54. data/contrib/zstd/lib/dictBuilder/zdict.h +112 -102
  55. data/contrib/zstd/lib/legacy/zstd_legacy.h +9 -4
  56. data/contrib/zstd/lib/legacy/zstd_v01.c +7 -6
  57. data/contrib/zstd/lib/legacy/zstd_v01.h +5 -4
  58. data/contrib/zstd/lib/legacy/zstd_v02.c +27 -99
  59. data/contrib/zstd/lib/legacy/zstd_v02.h +5 -4
  60. data/contrib/zstd/lib/legacy/zstd_v03.c +26 -98
  61. data/contrib/zstd/lib/legacy/zstd_v03.h +5 -4
  62. data/contrib/zstd/lib/legacy/zstd_v04.c +22 -91
  63. data/contrib/zstd/lib/legacy/zstd_v04.h +5 -4
  64. data/contrib/zstd/lib/legacy/zstd_v05.c +23 -99
  65. data/contrib/zstd/lib/legacy/zstd_v05.h +5 -4
  66. data/contrib/zstd/lib/legacy/zstd_v06.c +22 -96
  67. data/contrib/zstd/lib/legacy/zstd_v06.h +5 -4
  68. data/contrib/zstd/lib/legacy/zstd_v07.c +19 -95
  69. data/contrib/zstd/lib/legacy/zstd_v07.h +5 -4
  70. data/contrib/zstd/lib/zstd.h +895 -271
  71. data/ext/extconf.rb +11 -2
  72. data/ext/extzstd.c +45 -128
  73. data/ext/extzstd.h +74 -31
  74. data/ext/extzstd_stream.c +401 -142
  75. data/ext/zstd_common.c +5 -0
  76. data/ext/zstd_compress.c +8 -0
  77. data/ext/zstd_decompress.c +1 -0
  78. data/ext/zstd_dictbuilder.c +2 -0
  79. data/lib/extzstd/version.rb +1 -1
  80. data/lib/extzstd.rb +48 -1
  81. data/test/test_basic.rb +9 -1
  82. metadata +17 -7
  83. data/HISTORY.ja +0 -10
  84. data/contrib/zstd/LICENSE-examples +0 -11
  85. 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. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
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
- POOL_function function;
29
- void *opaque;
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
- pthread_t *threads;
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
- pthread_mutex_t queueMutex;
50
+ ZSTD_pthread_mutex_t queueMutex;
44
51
  /* Condition variable for pushers to wait on when the queue is full */
45
- pthread_cond_t queuePushCond;
52
+ ZSTD_pthread_cond_t queuePushCond;
46
53
  /* Condition variables for poppers to wait on when the queue is empty */
47
- pthread_cond_t queuePopCond;
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
- pthread_mutex_lock(&ctx->queueMutex);
63
- while (ctx->queueHead == ctx->queueTail && !ctx->shutdown) {
64
- pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex);
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->queueHead == ctx->queueTail) {
68
- pthread_mutex_unlock(&ctx->queueMutex);
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
- pthread_mutex_unlock(&ctx->queueMutex);
76
- pthread_cond_signal(&ctx->queuePushCond);
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 *POOL_create(size_t numThreads, size_t queueSize) {
84
- POOL_ctx *ctx;
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 || !queueSize) { return NULL; }
108
+ if (!numThreads) { return NULL; }
87
109
  /* Allocate the context and zero initialize */
88
- ctx = (POOL_ctx *)calloc(1, sizeof(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 *)malloc(ctx->queueSize * sizeof(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
- pthread_mutex_init(&ctx->queueMutex, NULL);
99
- pthread_cond_init(&ctx->queuePushCond, NULL);
100
- pthread_cond_init(&ctx->queuePopCond, NULL);
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 = (pthread_t *)malloc(numThreads * sizeof(pthread_t));
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 (pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
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 *ctx) {
148
+ static void POOL_join(POOL_ctx* ctx) {
124
149
  /* Shut down the queue */
125
- pthread_mutex_lock(&ctx->queueMutex);
150
+ ZSTD_pthread_mutex_lock(&ctx->queueMutex);
126
151
  ctx->shutdown = 1;
127
- pthread_mutex_unlock(&ctx->queueMutex);
152
+ ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
128
153
  /* Wake up sleeping threads */
129
- pthread_cond_broadcast(&ctx->queuePushCond);
130
- pthread_cond_broadcast(&ctx->queuePopCond);
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
- pthread_join(ctx->threads[i], NULL);
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
- pthread_mutex_destroy(&ctx->queueMutex);
142
- pthread_cond_destroy(&ctx->queuePushCond);
143
- pthread_cond_destroy(&ctx->queuePopCond);
144
- if (ctx->queue) free(ctx->queue);
145
- if (ctx->threads) free(ctx->threads);
146
- free(ctx);
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
- void POOL_add(void *ctxVoid, POOL_function function, void *opaque) {
150
- POOL_ctx *ctx = (POOL_ctx *)ctxVoid;
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
- pthread_mutex_lock(&ctx->queueMutex);
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
- size_t newTail = (ctx->queueTail + 1) % ctx->queueSize;
157
- while (ctx->queueHead == newTail && !ctx->shutdown) {
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 = newTail;
211
+ ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize;
165
212
  }
166
213
  }
167
- pthread_mutex_unlock(&ctx->queueMutex);
168
- pthread_cond_signal(&ctx->queuePopCond);
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
- int data;
223
+ int dummy;
177
224
  };
225
+ static POOL_ctx g_ctx;
178
226
 
179
- POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) {
180
- (void)numThreads;
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
- void POOL_free(POOL_ctx *ctx) {
186
- if (ctx) free(ctx);
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
- void POOL_add(void *ctx, POOL_function function, void *opaque) {
190
- (void)ctx;
191
- function(opaque);
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. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
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
- Create a thread pool with at most `numThreads` threads.
23
- `numThreads` must be at least 1.
24
- The maximum number of queued jobs before blocking is `queueSize`.
25
- `queueSize` must be at least 1.
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. An additional grant
8
- * of patent rights can be found in the PATENTS file in the same directory.
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
- /* When ZSTD_MULTITHREAD is not defined, this file would become an empty translation unit.
19
- * Include some ISO C header code to prevent this and portably avoid related warnings.
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
- pthread_t* const thread = (pthread_t*) arg;
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 pthread_create(pthread_t* thread, const void* unused,
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 _pthread_join(pthread_t * thread, void **value_ptr)
57
+ int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
63
58
  {
64
59
  DWORD result;
65
60
 
66
- if (!thread->handle) return 0;
61
+ if (!thread.handle) return 0;
67
62
 
68
- result = WaitForSingleObject(thread->handle, INFINITE);
63
+ result = WaitForSingleObject(thread.handle, INFINITE);
69
64
  switch (result) {
70
65
  case WAIT_OBJECT_0:
71
- if (value_ptr) *value_ptr = thread->arg;
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. An additional grant
8
- * of patent rights can be found in the PATENTS file in the same directory.
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 pthread_mutex_t CRITICAL_SECTION
45
- #define pthread_mutex_init(a,b) InitializeCriticalSection((a))
46
- #define pthread_mutex_destroy(a) DeleteCriticalSection((a))
47
- #define pthread_mutex_lock(a) EnterCriticalSection((a))
48
- #define pthread_mutex_unlock(a) LeaveCriticalSection((a))
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 pthread_cond_t CONDITION_VARIABLE
52
- #define pthread_cond_init(a, b) InitializeConditionVariable((a))
53
- #define pthread_cond_destroy(a) /* No delete */
54
- #define pthread_cond_wait(a, b) SleepConditionVariableCS((a), (b), INFINITE)
55
- #define pthread_cond_signal(a) WakeConditionVariable((a))
56
- #define pthread_cond_broadcast(a) WakeAllConditionVariable((a))
57
-
58
- /* pthread_create() and pthread_join() */
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
- } pthread_t;
66
+ } ZSTD_pthread_t;
64
67
 
65
- int pthread_create(pthread_t* thread, const void* unused,
68
+ int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
66
69
  void* (*start_routine) (void*), void* arg);
67
70
 
68
- #define pthread_join(a, b) _pthread_join(&(a), (b))
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
- #define pthread_mutex_t int /* #define rather than typedef, as sometimes pthread support is implicit, resulting in duplicated symbols */
84
- #define pthread_mutex_init(a,b)
85
- #define pthread_mutex_destroy(a)
86
- #define pthread_mutex_lock(a)
87
- #define pthread_mutex_unlock(a)
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
- #define pthread_cond_t int
90
- #define pthread_cond_init(a,b)
91
- #define pthread_cond_destroy(a)
92
- #define pthread_cond_wait(a,b)
93
- #define pthread_cond_signal(a)
94
- #define pthread_cond_broadcast(a)
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 pthread_t */
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
- #ifdef _MSC_VER /* Visual Studio */
117
- # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
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
- # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
121
- # ifdef __GNUC__
122
- # define FORCE_INLINE static inline __attribute__((always_inline))
123
- # else
124
- # define FORCE_INLINE static inline
125
- # endif
126
- # else
127
- # define FORCE_INLINE static
128
- # endif /* __STDC_VERSION__ */
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
- FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
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
- FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
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
- FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
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
- FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
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
- FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
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
- FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
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
- FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
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
- FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
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
- FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
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
- FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
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;