extzstd 0.0.3.CONCEPT → 0.3.1
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 +39 -0
- data/LICENSE +6 -6
- data/README.md +26 -45
- data/contrib/zstd/CHANGELOG +555 -0
- data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
- data/contrib/zstd/CONTRIBUTING.md +392 -0
- data/contrib/zstd/COPYING +339 -0
- data/contrib/zstd/LICENSE +13 -9
- data/contrib/zstd/Makefile +414 -0
- data/contrib/zstd/README.md +170 -45
- data/contrib/zstd/TESTING.md +44 -0
- data/contrib/zstd/appveyor.yml +289 -0
- data/contrib/zstd/lib/BUCK +234 -0
- data/contrib/zstd/lib/Makefile +354 -0
- data/contrib/zstd/lib/README.md +179 -0
- data/contrib/zstd/{common → lib/common}/bitstream.h +170 -130
- data/contrib/zstd/lib/common/compiler.h +175 -0
- data/contrib/zstd/lib/common/cpu.h +215 -0
- data/contrib/zstd/lib/common/debug.c +24 -0
- data/contrib/zstd/lib/common/debug.h +114 -0
- data/contrib/zstd/{common → lib/common}/entropy_common.c +79 -94
- data/contrib/zstd/lib/common/error_private.c +55 -0
- data/contrib/zstd/lib/common/error_private.h +80 -0
- data/contrib/zstd/{common → lib/common}/fse.h +153 -93
- data/contrib/zstd/{common → lib/common}/fse_decompress.c +37 -82
- data/contrib/zstd/lib/common/huf.h +340 -0
- data/contrib/zstd/{common → lib/common}/mem.h +154 -78
- data/contrib/zstd/lib/common/pool.c +344 -0
- data/contrib/zstd/lib/common/pool.h +84 -0
- data/contrib/zstd/lib/common/threading.c +121 -0
- data/contrib/zstd/lib/common/threading.h +155 -0
- data/contrib/zstd/{common → lib/common}/xxhash.c +85 -75
- data/contrib/zstd/{common → lib/common}/xxhash.h +85 -73
- data/contrib/zstd/lib/common/zstd_common.c +83 -0
- data/contrib/zstd/lib/common/zstd_errors.h +94 -0
- data/contrib/zstd/lib/common/zstd_internal.h +447 -0
- data/contrib/zstd/{compress → lib/compress}/fse_compress.c +194 -303
- data/contrib/zstd/lib/compress/hist.c +183 -0
- data/contrib/zstd/lib/compress/hist.h +75 -0
- data/contrib/zstd/lib/compress/huf_compress.c +798 -0
- data/contrib/zstd/lib/compress/zstd_compress.c +4278 -0
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +1125 -0
- data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
- data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
- data/contrib/zstd/lib/compress/zstd_compress_sequences.c +419 -0
- data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +845 -0
- data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
- data/contrib/zstd/lib/compress/zstd_cwksp.h +525 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
- data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
- data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
- data/contrib/zstd/lib/compress/zstd_lazy.c +1138 -0
- data/contrib/zstd/lib/compress/zstd_lazy.h +67 -0
- data/contrib/zstd/lib/compress/zstd_ldm.c +619 -0
- data/contrib/zstd/lib/compress/zstd_ldm.h +110 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +1200 -0
- data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
- data/contrib/zstd/lib/compress/zstdmt_compress.c +2143 -0
- data/contrib/zstd/lib/compress/zstdmt_compress.h +192 -0
- data/contrib/zstd/lib/decompress/huf_decompress.c +1248 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
- data/contrib/zstd/lib/decompress/zstd_decompress.c +1885 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1432 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +59 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +189 -0
- data/contrib/zstd/{common → lib/deprecated}/zbuff.h +86 -69
- data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
- data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
- data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
- data/contrib/zstd/lib/dictBuilder/cover.c +1236 -0
- data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +5 -5
- data/contrib/zstd/lib/dictBuilder/fastcover.c +757 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +437 -347
- data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
- data/contrib/zstd/lib/legacy/zstd_legacy.h +415 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +272 -292
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +26 -32
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +162 -392
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +26 -32
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +162 -391
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +27 -33
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +195 -604
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +26 -32
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +300 -575
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +22 -31
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +165 -592
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +54 -67
- data/contrib/zstd/lib/legacy/zstd_v07.c +4541 -0
- data/contrib/zstd/lib/legacy/zstd_v07.h +187 -0
- data/contrib/zstd/lib/libzstd.pc.in +15 -0
- data/contrib/zstd/lib/zstd.h +2090 -0
- data/ext/depend +2 -0
- data/ext/extconf.rb +18 -5
- data/ext/extzstd.c +296 -214
- data/ext/extzstd.h +81 -36
- data/ext/extzstd_nogvls.h +0 -117
- data/ext/extzstd_stream.c +622 -0
- data/ext/libzstd_conf.h +8 -0
- data/ext/zstd_common.c +11 -0
- data/ext/zstd_compress.c +15 -0
- data/ext/zstd_decompress.c +6 -0
- data/ext/zstd_dictbuilder.c +10 -0
- data/ext/zstd_dictbuilder_fastcover.c +3 -0
- data/ext/zstd_legacy_v01.c +3 -1
- data/ext/zstd_legacy_v02.c +3 -1
- data/ext/zstd_legacy_v03.c +3 -1
- data/ext/zstd_legacy_v04.c +3 -1
- data/ext/zstd_legacy_v05.c +3 -1
- data/ext/zstd_legacy_v06.c +3 -1
- data/ext/zstd_legacy_v07.c +3 -0
- data/gemstub.rb +27 -21
- data/lib/extzstd.rb +82 -161
- data/lib/extzstd/version.rb +1 -1
- data/test/test_basic.rb +19 -6
- metadata +127 -59
- data/contrib/zstd/common/error_private.h +0 -125
- data/contrib/zstd/common/error_public.h +0 -77
- data/contrib/zstd/common/huf.h +0 -228
- data/contrib/zstd/common/zstd.h +0 -475
- data/contrib/zstd/common/zstd_common.c +0 -91
- data/contrib/zstd/common/zstd_internal.h +0 -238
- data/contrib/zstd/compress/huf_compress.c +0 -577
- data/contrib/zstd/compress/zbuff_compress.c +0 -327
- data/contrib/zstd/compress/zstd_compress.c +0 -3074
- data/contrib/zstd/compress/zstd_opt.h +0 -1046
- data/contrib/zstd/decompress/huf_decompress.c +0 -894
- data/contrib/zstd/decompress/zbuff_decompress.c +0 -294
- data/contrib/zstd/decompress/zstd_decompress.c +0 -1362
- data/contrib/zstd/dictBuilder/zdict.h +0 -113
- data/contrib/zstd/legacy/zstd_legacy.h +0 -140
- data/ext/extzstd_buffered.c +0 -265
- data/ext/zstd_amalgam.c +0 -18
|
@@ -1,37 +1,13 @@
|
|
|
1
|
-
/*
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* Redistributions of source code must retain the above copyright
|
|
13
|
-
notice, this list of conditions and the following disclaimer.
|
|
14
|
-
* Redistributions in binary form must reproduce the above
|
|
15
|
-
copyright notice, this list of conditions and the following disclaimer
|
|
16
|
-
in the documentation and/or other materials provided with the
|
|
17
|
-
distribution.
|
|
18
|
-
|
|
19
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
20
|
-
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
21
|
-
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
22
|
-
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
23
|
-
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
24
|
-
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
25
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
26
|
-
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
27
|
-
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
28
|
-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
-
|
|
31
|
-
You can contact the author at :
|
|
32
|
-
- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
|
33
|
-
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
34
|
-
****************************************************************** */
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under both the BSD-style license (found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
7
|
+
* in the COPYING file in the root directory of this source tree).
|
|
8
|
+
* You may select, at your option, one of the above-listed licenses.
|
|
9
|
+
*/
|
|
10
|
+
|
|
35
11
|
#ifndef MEM_H_MODULE
|
|
36
12
|
#define MEM_H_MODULE
|
|
37
13
|
|
|
@@ -44,19 +20,17 @@ extern "C" {
|
|
|
44
20
|
******************************************/
|
|
45
21
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
|
46
22
|
#include <string.h> /* memcpy */
|
|
47
|
-
#if defined(_MSC_VER) /* Visual Studio */
|
|
48
|
-
# include <stdlib.h> /* _byteswap_ulong */
|
|
49
|
-
#endif
|
|
50
23
|
|
|
51
24
|
|
|
52
25
|
/*-****************************************
|
|
53
26
|
* Compiler specifics
|
|
54
27
|
******************************************/
|
|
55
|
-
#if defined(_MSC_VER)
|
|
56
|
-
# include <
|
|
28
|
+
#if defined(_MSC_VER) /* Visual Studio */
|
|
29
|
+
# include <stdlib.h> /* _byteswap_ulong */
|
|
30
|
+
# include <intrin.h> /* _byteswap_* */
|
|
57
31
|
#endif
|
|
58
32
|
#if defined(__GNUC__)
|
|
59
|
-
# define MEM_STATIC static __attribute__((unused))
|
|
33
|
+
# define MEM_STATIC static __inline __attribute__((unused))
|
|
60
34
|
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
|
61
35
|
# define MEM_STATIC static inline
|
|
62
36
|
#elif defined(_MSC_VER)
|
|
@@ -65,25 +39,118 @@ extern "C" {
|
|
|
65
39
|
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
|
66
40
|
#endif
|
|
67
41
|
|
|
42
|
+
#ifndef __has_builtin
|
|
43
|
+
# define __has_builtin(x) 0 /* compat. with non-clang compilers */
|
|
44
|
+
#endif
|
|
45
|
+
|
|
46
|
+
/* code only tested on 32 and 64 bits systems */
|
|
47
|
+
#define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; }
|
|
48
|
+
MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
|
|
49
|
+
|
|
50
|
+
/* detects whether we are being compiled under msan */
|
|
51
|
+
#if defined (__has_feature)
|
|
52
|
+
# if __has_feature(memory_sanitizer)
|
|
53
|
+
# define MEMORY_SANITIZER 1
|
|
54
|
+
# endif
|
|
55
|
+
#endif
|
|
56
|
+
|
|
57
|
+
#if defined (MEMORY_SANITIZER)
|
|
58
|
+
/* Not all platforms that support msan provide sanitizers/msan_interface.h.
|
|
59
|
+
* We therefore declare the functions we need ourselves, rather than trying to
|
|
60
|
+
* include the header file... */
|
|
61
|
+
|
|
62
|
+
#include <stdint.h> /* intptr_t */
|
|
63
|
+
|
|
64
|
+
/* Make memory region fully initialized (without changing its contents). */
|
|
65
|
+
void __msan_unpoison(const volatile void *a, size_t size);
|
|
66
|
+
|
|
67
|
+
/* Make memory region fully uninitialized (without changing its contents).
|
|
68
|
+
This is a legacy interface that does not update origin information. Use
|
|
69
|
+
__msan_allocated_memory() instead. */
|
|
70
|
+
void __msan_poison(const volatile void *a, size_t size);
|
|
71
|
+
|
|
72
|
+
/* Returns the offset of the first (at least partially) poisoned byte in the
|
|
73
|
+
memory range, or -1 if the whole range is good. */
|
|
74
|
+
intptr_t __msan_test_shadow(const volatile void *x, size_t size);
|
|
75
|
+
#endif
|
|
76
|
+
|
|
77
|
+
/* detects whether we are being compiled under asan */
|
|
78
|
+
#if defined (__has_feature)
|
|
79
|
+
# if __has_feature(address_sanitizer)
|
|
80
|
+
# define ADDRESS_SANITIZER 1
|
|
81
|
+
# endif
|
|
82
|
+
#elif defined(__SANITIZE_ADDRESS__)
|
|
83
|
+
# define ADDRESS_SANITIZER 1
|
|
84
|
+
#endif
|
|
85
|
+
|
|
86
|
+
#if defined (ADDRESS_SANITIZER)
|
|
87
|
+
/* Not all platforms that support asan provide sanitizers/asan_interface.h.
|
|
88
|
+
* We therefore declare the functions we need ourselves, rather than trying to
|
|
89
|
+
* include the header file... */
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable.
|
|
93
|
+
*
|
|
94
|
+
* This memory must be previously allocated by your program. Instrumented
|
|
95
|
+
* code is forbidden from accessing addresses in this region until it is
|
|
96
|
+
* unpoisoned. This function is not guaranteed to poison the entire region -
|
|
97
|
+
* it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan
|
|
98
|
+
* alignment restrictions.
|
|
99
|
+
*
|
|
100
|
+
* \note This function is not thread-safe because no two threads can poison or
|
|
101
|
+
* unpoison memory in the same memory region simultaneously.
|
|
102
|
+
*
|
|
103
|
+
* \param addr Start of memory region.
|
|
104
|
+
* \param size Size of memory region. */
|
|
105
|
+
void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Marks a memory region (<c>[addr, addr+size)</c>) as addressable.
|
|
109
|
+
*
|
|
110
|
+
* This memory must be previously allocated by your program. Accessing
|
|
111
|
+
* addresses in this region is allowed until this region is poisoned again.
|
|
112
|
+
* This function could unpoison a super-region of <c>[addr, addr+size)</c> due
|
|
113
|
+
* to ASan alignment restrictions.
|
|
114
|
+
*
|
|
115
|
+
* \note This function is not thread-safe because no two threads can
|
|
116
|
+
* poison or unpoison memory in the same memory region simultaneously.
|
|
117
|
+
*
|
|
118
|
+
* \param addr Start of memory region.
|
|
119
|
+
* \param size Size of memory region. */
|
|
120
|
+
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
|
121
|
+
#endif
|
|
122
|
+
|
|
68
123
|
|
|
69
124
|
/*-**************************************************************
|
|
70
125
|
* Basic Types
|
|
71
126
|
*****************************************************************/
|
|
72
127
|
#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
|
|
73
128
|
# include <stdint.h>
|
|
74
|
-
typedef
|
|
75
|
-
typedef
|
|
76
|
-
typedef
|
|
77
|
-
typedef
|
|
78
|
-
typedef
|
|
79
|
-
typedef
|
|
80
|
-
typedef
|
|
129
|
+
typedef uint8_t BYTE;
|
|
130
|
+
typedef uint16_t U16;
|
|
131
|
+
typedef int16_t S16;
|
|
132
|
+
typedef uint32_t U32;
|
|
133
|
+
typedef int32_t S32;
|
|
134
|
+
typedef uint64_t U64;
|
|
135
|
+
typedef int64_t S64;
|
|
81
136
|
#else
|
|
82
|
-
|
|
137
|
+
# include <limits.h>
|
|
138
|
+
#if CHAR_BIT != 8
|
|
139
|
+
# error "this implementation requires char to be exactly 8-bit type"
|
|
140
|
+
#endif
|
|
141
|
+
typedef unsigned char BYTE;
|
|
142
|
+
#if USHRT_MAX != 65535
|
|
143
|
+
# error "this implementation requires short to be exactly 16-bit type"
|
|
144
|
+
#endif
|
|
83
145
|
typedef unsigned short U16;
|
|
84
146
|
typedef signed short S16;
|
|
147
|
+
#if UINT_MAX != 4294967295
|
|
148
|
+
# error "this implementation requires int to be exactly 32-bit type"
|
|
149
|
+
#endif
|
|
85
150
|
typedef unsigned int U32;
|
|
86
151
|
typedef signed int S32;
|
|
152
|
+
/* note : there are no limits defined for long long type in C90.
|
|
153
|
+
* limits exist in C99, however, in such case, <stdint.h> is preferred */
|
|
87
154
|
typedef unsigned long long U64;
|
|
88
155
|
typedef signed long long S64;
|
|
89
156
|
#endif
|
|
@@ -97,19 +164,18 @@ extern "C" {
|
|
|
97
164
|
* Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
|
|
98
165
|
* The below switch allow to select different access method for improved performance.
|
|
99
166
|
* Method 0 (default) : use `memcpy()`. Safe and portable.
|
|
100
|
-
* Method 1 : `__packed` statement. It depends on compiler extension (
|
|
167
|
+
* Method 1 : `__packed` statement. It depends on compiler extension (i.e., not portable).
|
|
101
168
|
* This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
|
|
102
169
|
* Method 2 : direct access. This method is portable but violate C standard.
|
|
103
170
|
* It can generate buggy code on targets depending on alignment.
|
|
104
|
-
* In some circumstances, it's the only known way to get the most performance (
|
|
171
|
+
* In some circumstances, it's the only known way to get the most performance (i.e. GCC + ARMv6)
|
|
105
172
|
* See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
|
|
106
173
|
* Prefer these methods in priority order (0 > 1 > 2)
|
|
107
174
|
*/
|
|
108
175
|
#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
|
|
109
176
|
# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
|
|
110
177
|
# define MEM_FORCE_MEMORY_ACCESS 2
|
|
111
|
-
# elif defined(__INTEL_COMPILER) ||
|
|
112
|
-
(defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
|
|
178
|
+
# elif defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__)
|
|
113
179
|
# define MEM_FORCE_MEMORY_ACCESS 1
|
|
114
180
|
# endif
|
|
115
181
|
#endif
|
|
@@ -130,7 +196,7 @@ Only use if no other choice to achieve best performance on target platform */
|
|
|
130
196
|
MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }
|
|
131
197
|
MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }
|
|
132
198
|
MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }
|
|
133
|
-
MEM_STATIC
|
|
199
|
+
MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; }
|
|
134
200
|
|
|
135
201
|
MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
|
|
136
202
|
MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
|
|
@@ -140,16 +206,28 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
|
|
|
140
206
|
|
|
141
207
|
/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
|
|
142
208
|
/* currently only defined for gcc and icc */
|
|
143
|
-
|
|
209
|
+
#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32))
|
|
210
|
+
__pragma( pack(push, 1) )
|
|
211
|
+
typedef struct { U16 v; } unalign16;
|
|
212
|
+
typedef struct { U32 v; } unalign32;
|
|
213
|
+
typedef struct { U64 v; } unalign64;
|
|
214
|
+
typedef struct { size_t v; } unalignArch;
|
|
215
|
+
__pragma( pack(pop) )
|
|
216
|
+
#else
|
|
217
|
+
typedef struct { U16 v; } __attribute__((packed)) unalign16;
|
|
218
|
+
typedef struct { U32 v; } __attribute__((packed)) unalign32;
|
|
219
|
+
typedef struct { U64 v; } __attribute__((packed)) unalign64;
|
|
220
|
+
typedef struct { size_t v; } __attribute__((packed)) unalignArch;
|
|
221
|
+
#endif
|
|
144
222
|
|
|
145
|
-
MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const
|
|
146
|
-
MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const
|
|
147
|
-
MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const
|
|
148
|
-
MEM_STATIC
|
|
223
|
+
MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign16*)ptr)->v; }
|
|
224
|
+
MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign32*)ptr)->v; }
|
|
225
|
+
MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign64*)ptr)->v; }
|
|
226
|
+
MEM_STATIC size_t MEM_readST(const void* ptr) { return ((const unalignArch*)ptr)->v; }
|
|
149
227
|
|
|
150
|
-
MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((
|
|
151
|
-
MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((
|
|
152
|
-
MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((
|
|
228
|
+
MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign16*)memPtr)->v = value; }
|
|
229
|
+
MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign32*)memPtr)->v = value; }
|
|
230
|
+
MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v = value; }
|
|
153
231
|
|
|
154
232
|
#else
|
|
155
233
|
|
|
@@ -197,7 +275,8 @@ MEM_STATIC U32 MEM_swap32(U32 in)
|
|
|
197
275
|
{
|
|
198
276
|
#if defined(_MSC_VER) /* Visual Studio */
|
|
199
277
|
return _byteswap_ulong(in);
|
|
200
|
-
#elif defined (__GNUC__)
|
|
278
|
+
#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
|
|
279
|
+
|| (defined(__clang__) && __has_builtin(__builtin_bswap32))
|
|
201
280
|
return __builtin_bswap32(in);
|
|
202
281
|
#else
|
|
203
282
|
return ((in << 24) & 0xff000000 ) |
|
|
@@ -211,7 +290,8 @@ MEM_STATIC U64 MEM_swap64(U64 in)
|
|
|
211
290
|
{
|
|
212
291
|
#if defined(_MSC_VER) /* Visual Studio */
|
|
213
292
|
return _byteswap_uint64(in);
|
|
214
|
-
#elif defined (__GNUC__)
|
|
293
|
+
#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
|
|
294
|
+
|| (defined(__clang__) && __has_builtin(__builtin_bswap64))
|
|
215
295
|
return __builtin_bswap64(in);
|
|
216
296
|
#else
|
|
217
297
|
return ((in << 56) & 0xff00000000000000ULL) |
|
|
@@ -256,6 +336,17 @@ MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
|
|
|
256
336
|
}
|
|
257
337
|
}
|
|
258
338
|
|
|
339
|
+
MEM_STATIC U32 MEM_readLE24(const void* memPtr)
|
|
340
|
+
{
|
|
341
|
+
return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
|
|
345
|
+
{
|
|
346
|
+
MEM_writeLE16(memPtr, (U16)val);
|
|
347
|
+
((BYTE*)memPtr)[2] = (BYTE)(val>>16);
|
|
348
|
+
}
|
|
349
|
+
|
|
259
350
|
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
|
|
260
351
|
{
|
|
261
352
|
if (MEM_isLittleEndian())
|
|
@@ -355,23 +446,8 @@ MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
|
|
|
355
446
|
}
|
|
356
447
|
|
|
357
448
|
|
|
358
|
-
/* function safe only for comparisons */
|
|
359
|
-
MEM_STATIC U32 MEM_readMINMATCH(const void* memPtr, U32 length)
|
|
360
|
-
{
|
|
361
|
-
switch (length)
|
|
362
|
-
{
|
|
363
|
-
default :
|
|
364
|
-
case 4 : return MEM_read32(memPtr);
|
|
365
|
-
case 3 : if (MEM_isLittleEndian())
|
|
366
|
-
return MEM_read32(memPtr)<<8;
|
|
367
|
-
else
|
|
368
|
-
return MEM_read32(memPtr)>>8;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
449
|
#if defined (__cplusplus)
|
|
373
450
|
}
|
|
374
451
|
#endif
|
|
375
452
|
|
|
376
453
|
#endif /* MEM_H_MODULE */
|
|
377
|
-
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under both the BSD-style license (found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
7
|
+
* in the COPYING file in the root directory of this source tree).
|
|
8
|
+
* You may select, at your option, one of the above-listed licenses.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/* ====== Dependencies ======= */
|
|
13
|
+
#include <stddef.h> /* size_t */
|
|
14
|
+
#include "debug.h" /* assert */
|
|
15
|
+
#include "zstd_internal.h" /* ZSTD_malloc, ZSTD_free */
|
|
16
|
+
#include "pool.h"
|
|
17
|
+
|
|
18
|
+
/* ====== Compiler specifics ====== */
|
|
19
|
+
#if defined(_MSC_VER)
|
|
20
|
+
# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
#ifdef ZSTD_MULTITHREAD
|
|
25
|
+
|
|
26
|
+
#include "threading.h" /* pthread adaptation */
|
|
27
|
+
|
|
28
|
+
/* A job is a function and an opaque argument */
|
|
29
|
+
typedef struct POOL_job_s {
|
|
30
|
+
POOL_function function;
|
|
31
|
+
void *opaque;
|
|
32
|
+
} POOL_job;
|
|
33
|
+
|
|
34
|
+
struct POOL_ctx_s {
|
|
35
|
+
ZSTD_customMem customMem;
|
|
36
|
+
/* Keep track of the threads */
|
|
37
|
+
ZSTD_pthread_t* threads;
|
|
38
|
+
size_t threadCapacity;
|
|
39
|
+
size_t threadLimit;
|
|
40
|
+
|
|
41
|
+
/* The queue is a circular buffer */
|
|
42
|
+
POOL_job *queue;
|
|
43
|
+
size_t queueHead;
|
|
44
|
+
size_t queueTail;
|
|
45
|
+
size_t queueSize;
|
|
46
|
+
|
|
47
|
+
/* The number of threads working on jobs */
|
|
48
|
+
size_t numThreadsBusy;
|
|
49
|
+
/* Indicates if the queue is empty */
|
|
50
|
+
int queueEmpty;
|
|
51
|
+
|
|
52
|
+
/* The mutex protects the queue */
|
|
53
|
+
ZSTD_pthread_mutex_t queueMutex;
|
|
54
|
+
/* Condition variable for pushers to wait on when the queue is full */
|
|
55
|
+
ZSTD_pthread_cond_t queuePushCond;
|
|
56
|
+
/* Condition variables for poppers to wait on when the queue is empty */
|
|
57
|
+
ZSTD_pthread_cond_t queuePopCond;
|
|
58
|
+
/* Indicates if the queue is shutting down */
|
|
59
|
+
int shutdown;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/* POOL_thread() :
|
|
63
|
+
* Work thread for the thread pool.
|
|
64
|
+
* Waits for jobs and executes them.
|
|
65
|
+
* @returns : NULL on failure else non-null.
|
|
66
|
+
*/
|
|
67
|
+
static void* POOL_thread(void* opaque) {
|
|
68
|
+
POOL_ctx* const ctx = (POOL_ctx*)opaque;
|
|
69
|
+
if (!ctx) { return NULL; }
|
|
70
|
+
for (;;) {
|
|
71
|
+
/* Lock the mutex and wait for a non-empty queue or until shutdown */
|
|
72
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
73
|
+
|
|
74
|
+
while ( ctx->queueEmpty
|
|
75
|
+
|| (ctx->numThreadsBusy >= ctx->threadLimit) ) {
|
|
76
|
+
if (ctx->shutdown) {
|
|
77
|
+
/* even if !queueEmpty, (possible if numThreadsBusy >= threadLimit),
|
|
78
|
+
* a few threads will be shutdown while !queueEmpty,
|
|
79
|
+
* but enough threads will remain active to finish the queue */
|
|
80
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
81
|
+
return opaque;
|
|
82
|
+
}
|
|
83
|
+
ZSTD_pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex);
|
|
84
|
+
}
|
|
85
|
+
/* Pop a job off the queue */
|
|
86
|
+
{ POOL_job const job = ctx->queue[ctx->queueHead];
|
|
87
|
+
ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;
|
|
88
|
+
ctx->numThreadsBusy++;
|
|
89
|
+
ctx->queueEmpty = ctx->queueHead == ctx->queueTail;
|
|
90
|
+
/* Unlock the mutex, signal a pusher, and run the job */
|
|
91
|
+
ZSTD_pthread_cond_signal(&ctx->queuePushCond);
|
|
92
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
93
|
+
|
|
94
|
+
job.function(job.opaque);
|
|
95
|
+
|
|
96
|
+
/* If the intended queue size was 0, signal after finishing job */
|
|
97
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
98
|
+
ctx->numThreadsBusy--;
|
|
99
|
+
if (ctx->queueSize == 1) {
|
|
100
|
+
ZSTD_pthread_cond_signal(&ctx->queuePushCond);
|
|
101
|
+
}
|
|
102
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
103
|
+
}
|
|
104
|
+
} /* for (;;) */
|
|
105
|
+
assert(0); /* Unreachable */
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
|
|
109
|
+
return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
|
|
113
|
+
ZSTD_customMem customMem) {
|
|
114
|
+
POOL_ctx* ctx;
|
|
115
|
+
/* Check parameters */
|
|
116
|
+
if (!numThreads) { return NULL; }
|
|
117
|
+
/* Allocate the context and zero initialize */
|
|
118
|
+
ctx = (POOL_ctx*)ZSTD_calloc(sizeof(POOL_ctx), customMem);
|
|
119
|
+
if (!ctx) { return NULL; }
|
|
120
|
+
/* Initialize the job queue.
|
|
121
|
+
* It needs one extra space since one space is wasted to differentiate
|
|
122
|
+
* empty and full queues.
|
|
123
|
+
*/
|
|
124
|
+
ctx->queueSize = queueSize + 1;
|
|
125
|
+
ctx->queue = (POOL_job*)ZSTD_malloc(ctx->queueSize * sizeof(POOL_job), customMem);
|
|
126
|
+
ctx->queueHead = 0;
|
|
127
|
+
ctx->queueTail = 0;
|
|
128
|
+
ctx->numThreadsBusy = 0;
|
|
129
|
+
ctx->queueEmpty = 1;
|
|
130
|
+
{
|
|
131
|
+
int error = 0;
|
|
132
|
+
error |= ZSTD_pthread_mutex_init(&ctx->queueMutex, NULL);
|
|
133
|
+
error |= ZSTD_pthread_cond_init(&ctx->queuePushCond, NULL);
|
|
134
|
+
error |= ZSTD_pthread_cond_init(&ctx->queuePopCond, NULL);
|
|
135
|
+
if (error) { POOL_free(ctx); return NULL; }
|
|
136
|
+
}
|
|
137
|
+
ctx->shutdown = 0;
|
|
138
|
+
/* Allocate space for the thread handles */
|
|
139
|
+
ctx->threads = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
|
|
140
|
+
ctx->threadCapacity = 0;
|
|
141
|
+
ctx->customMem = customMem;
|
|
142
|
+
/* Check for errors */
|
|
143
|
+
if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
|
|
144
|
+
/* Initialize the threads */
|
|
145
|
+
{ size_t i;
|
|
146
|
+
for (i = 0; i < numThreads; ++i) {
|
|
147
|
+
if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
|
|
148
|
+
ctx->threadCapacity = i;
|
|
149
|
+
POOL_free(ctx);
|
|
150
|
+
return NULL;
|
|
151
|
+
} }
|
|
152
|
+
ctx->threadCapacity = numThreads;
|
|
153
|
+
ctx->threadLimit = numThreads;
|
|
154
|
+
}
|
|
155
|
+
return ctx;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/*! POOL_join() :
|
|
159
|
+
Shutdown the queue, wake any sleeping threads, and join all of the threads.
|
|
160
|
+
*/
|
|
161
|
+
static void POOL_join(POOL_ctx* ctx) {
|
|
162
|
+
/* Shut down the queue */
|
|
163
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
164
|
+
ctx->shutdown = 1;
|
|
165
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
166
|
+
/* Wake up sleeping threads */
|
|
167
|
+
ZSTD_pthread_cond_broadcast(&ctx->queuePushCond);
|
|
168
|
+
ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);
|
|
169
|
+
/* Join all of the threads */
|
|
170
|
+
{ size_t i;
|
|
171
|
+
for (i = 0; i < ctx->threadCapacity; ++i) {
|
|
172
|
+
ZSTD_pthread_join(ctx->threads[i], NULL); /* note : could fail */
|
|
173
|
+
} }
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
void POOL_free(POOL_ctx *ctx) {
|
|
177
|
+
if (!ctx) { return; }
|
|
178
|
+
POOL_join(ctx);
|
|
179
|
+
ZSTD_pthread_mutex_destroy(&ctx->queueMutex);
|
|
180
|
+
ZSTD_pthread_cond_destroy(&ctx->queuePushCond);
|
|
181
|
+
ZSTD_pthread_cond_destroy(&ctx->queuePopCond);
|
|
182
|
+
ZSTD_free(ctx->queue, ctx->customMem);
|
|
183
|
+
ZSTD_free(ctx->threads, ctx->customMem);
|
|
184
|
+
ZSTD_free(ctx, ctx->customMem);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
size_t POOL_sizeof(POOL_ctx *ctx) {
|
|
190
|
+
if (ctx==NULL) return 0; /* supports sizeof NULL */
|
|
191
|
+
return sizeof(*ctx)
|
|
192
|
+
+ ctx->queueSize * sizeof(POOL_job)
|
|
193
|
+
+ ctx->threadCapacity * sizeof(ZSTD_pthread_t);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
/* @return : 0 on success, 1 on error */
|
|
198
|
+
static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
|
|
199
|
+
{
|
|
200
|
+
if (numThreads <= ctx->threadCapacity) {
|
|
201
|
+
if (!numThreads) return 1;
|
|
202
|
+
ctx->threadLimit = numThreads;
|
|
203
|
+
return 0;
|
|
204
|
+
}
|
|
205
|
+
/* numThreads > threadCapacity */
|
|
206
|
+
{ ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
|
|
207
|
+
if (!threadPool) return 1;
|
|
208
|
+
/* replace existing thread pool */
|
|
209
|
+
memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool));
|
|
210
|
+
ZSTD_free(ctx->threads, ctx->customMem);
|
|
211
|
+
ctx->threads = threadPool;
|
|
212
|
+
/* Initialize additional threads */
|
|
213
|
+
{ size_t threadId;
|
|
214
|
+
for (threadId = ctx->threadCapacity; threadId < numThreads; ++threadId) {
|
|
215
|
+
if (ZSTD_pthread_create(&threadPool[threadId], NULL, &POOL_thread, ctx)) {
|
|
216
|
+
ctx->threadCapacity = threadId;
|
|
217
|
+
return 1;
|
|
218
|
+
} }
|
|
219
|
+
} }
|
|
220
|
+
/* successfully expanded */
|
|
221
|
+
ctx->threadCapacity = numThreads;
|
|
222
|
+
ctx->threadLimit = numThreads;
|
|
223
|
+
return 0;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* @return : 0 on success, 1 on error */
|
|
227
|
+
int POOL_resize(POOL_ctx* ctx, size_t numThreads)
|
|
228
|
+
{
|
|
229
|
+
int result;
|
|
230
|
+
if (ctx==NULL) return 1;
|
|
231
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
232
|
+
result = POOL_resize_internal(ctx, numThreads);
|
|
233
|
+
ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);
|
|
234
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Returns 1 if the queue is full and 0 otherwise.
|
|
240
|
+
*
|
|
241
|
+
* When queueSize is 1 (pool was created with an intended queueSize of 0),
|
|
242
|
+
* then a queue is empty if there is a thread free _and_ no job is waiting.
|
|
243
|
+
*/
|
|
244
|
+
static int isQueueFull(POOL_ctx const* ctx) {
|
|
245
|
+
if (ctx->queueSize > 1) {
|
|
246
|
+
return ctx->queueHead == ((ctx->queueTail + 1) % ctx->queueSize);
|
|
247
|
+
} else {
|
|
248
|
+
return (ctx->numThreadsBusy == ctx->threadLimit) ||
|
|
249
|
+
!ctx->queueEmpty;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
static void POOL_add_internal(POOL_ctx* ctx, POOL_function function, void *opaque)
|
|
255
|
+
{
|
|
256
|
+
POOL_job const job = {function, opaque};
|
|
257
|
+
assert(ctx != NULL);
|
|
258
|
+
if (ctx->shutdown) return;
|
|
259
|
+
|
|
260
|
+
ctx->queueEmpty = 0;
|
|
261
|
+
ctx->queue[ctx->queueTail] = job;
|
|
262
|
+
ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize;
|
|
263
|
+
ZSTD_pthread_cond_signal(&ctx->queuePopCond);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque)
|
|
267
|
+
{
|
|
268
|
+
assert(ctx != NULL);
|
|
269
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
270
|
+
/* Wait until there is space in the queue for the new job */
|
|
271
|
+
while (isQueueFull(ctx) && (!ctx->shutdown)) {
|
|
272
|
+
ZSTD_pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex);
|
|
273
|
+
}
|
|
274
|
+
POOL_add_internal(ctx, function, opaque);
|
|
275
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque)
|
|
280
|
+
{
|
|
281
|
+
assert(ctx != NULL);
|
|
282
|
+
ZSTD_pthread_mutex_lock(&ctx->queueMutex);
|
|
283
|
+
if (isQueueFull(ctx)) {
|
|
284
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
285
|
+
return 0;
|
|
286
|
+
}
|
|
287
|
+
POOL_add_internal(ctx, function, opaque);
|
|
288
|
+
ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
|
|
289
|
+
return 1;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
#else /* ZSTD_MULTITHREAD not defined */
|
|
294
|
+
|
|
295
|
+
/* ========================== */
|
|
296
|
+
/* No multi-threading support */
|
|
297
|
+
/* ========================== */
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
/* We don't need any data, but if it is empty, malloc() might return NULL. */
|
|
301
|
+
struct POOL_ctx_s {
|
|
302
|
+
int dummy;
|
|
303
|
+
};
|
|
304
|
+
static POOL_ctx g_ctx;
|
|
305
|
+
|
|
306
|
+
POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
|
|
307
|
+
return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) {
|
|
311
|
+
(void)numThreads;
|
|
312
|
+
(void)queueSize;
|
|
313
|
+
(void)customMem;
|
|
314
|
+
return &g_ctx;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
void POOL_free(POOL_ctx* ctx) {
|
|
318
|
+
assert(!ctx || ctx == &g_ctx);
|
|
319
|
+
(void)ctx;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
int POOL_resize(POOL_ctx* ctx, size_t numThreads) {
|
|
323
|
+
(void)ctx; (void)numThreads;
|
|
324
|
+
return 0;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque) {
|
|
328
|
+
(void)ctx;
|
|
329
|
+
function(opaque);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) {
|
|
333
|
+
(void)ctx;
|
|
334
|
+
function(opaque);
|
|
335
|
+
return 1;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
size_t POOL_sizeof(POOL_ctx* ctx) {
|
|
339
|
+
if (ctx==NULL) return 0; /* supports sizeof NULL */
|
|
340
|
+
assert(ctx == &g_ctx);
|
|
341
|
+
return sizeof(*ctx);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
#endif /* ZSTD_MULTITHREAD */
|