extzstd 0.1.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
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;