Skip to content

Commit 4104960

Browse files
authored
Merge pull request #24 from SpringMT/update-zstd-for-v1.4.4
Update zstd to v1.4.4
2 parents 144684f + 675a12d commit 4104960

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2034
-942
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ See https://github.com/facebook/zstd
1010
Fork from https://github.com/jarredholman/ruby-zstd.
1111

1212
## Zstd version
13-
v1.4.2 (https://github.com/facebook/zstd/tree/v1.4.2)
13+
v1.4.4 (https://github.com/facebook/zstd/tree/v1.4.4)
1414

1515
## Installation
1616

ext/zstdruby/libzstd/Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,6 @@ libzstd.pc:
244244
libzstd.pc: libzstd.pc.in
245245
@echo creating pkgconfig
246246
@sed -e 's|@PREFIX@|$(PREFIX)|' \
247-
-e 's|@LIBDIR@|$(LIBDIR)|' \
248-
-e 's|@INCLUDEDIR@|$(INCLUDEDIR)|' \
249247
-e 's|@VERSION@|$(VERSION)|' \
250248
$< >$@
251249

ext/zstdruby/libzstd/README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ Enabling multithreading requires 2 conditions :
2727
Both conditions are automatically applied when invoking `make lib-mt` target.
2828

2929
When linking a POSIX program with a multithreaded version of `libzstd`,
30-
note that it's necessary to request the `-pthread` flag during link stage.
30+
note that it's necessary to invoke the `-pthread` flag during link stage.
3131

3232
Multithreading capabilities are exposed
33-
via the [advanced API defined in `lib/zstd.h`](https://github.com/facebook/zstd/blob/v1.3.8/lib/zstd.h#L592).
33+
via the [advanced API defined in `lib/zstd.h`](https://github.com/facebook/zstd/blob/v1.4.3/lib/zstd.h#L351).
3434

3535

3636
#### API
@@ -112,6 +112,17 @@ The file structure is designed to make this selection manually achievable for an
112112
will expose the deprecated `ZSTDMT` API exposed by `zstdmt_compress.h` in
113113
the shared library, which is now hidden by default.
114114

115+
- The build macro `DYNAMIC_BMI2` can be set to 1 or 0 in order to generate binaries
116+
which can detect at runtime the presence of BMI2 instructions, and use them only if present.
117+
These instructions contribute to better performance, notably on the decoder side.
118+
By default, this feature is automatically enabled on detecting
119+
the right instruction set (x64) and compiler (clang or gcc >= 5).
120+
It's obviously disabled for different cpus,
121+
or when BMI2 instruction set is _required_ by the compiler command line
122+
(in this case, only the BMI2 code path is generated).
123+
Setting this macro will either force to generate the BMI2 dispatcher (1)
124+
or prevent it (0). It overrides automatic detection.
125+
115126

116127
#### Windows : using MinGW+MSYS to create DLL
117128

ext/zstdruby/libzstd/common/bitstream.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ extern "C" {
5757
=========================================*/
5858
#if defined(__BMI__) && defined(__GNUC__)
5959
# include <immintrin.h> /* support for bextr (experimental) */
60+
#elif defined(__ICCARM__)
61+
# include <intrinsics.h>
6062
#endif
6163

6264
#define STREAM_ACCUMULATOR_MIN_32 25
@@ -162,7 +164,9 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val)
162164
_BitScanReverse ( &r, val );
163165
return (unsigned) r;
164166
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
165-
return 31 - __builtin_clz (val);
167+
return __builtin_clz (val) ^ 31;
168+
# elif defined(__ICCARM__) /* IAR Intrinsic */
169+
return 31 - __CLZ(val);
166170
# else /* Software version */
167171
static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
168172
11, 14, 16, 18, 22, 25, 3, 30,
@@ -240,9 +244,9 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
240244
{
241245
size_t const nbBytes = bitC->bitPos >> 3;
242246
assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
247+
assert(bitC->ptr <= bitC->endPtr);
243248
MEM_writeLEST(bitC->ptr, bitC->bitContainer);
244249
bitC->ptr += nbBytes;
245-
assert(bitC->ptr <= bitC->endPtr);
246250
bitC->bitPos &= 7;
247251
bitC->bitContainer >>= nbBytes*8;
248252
}
@@ -256,6 +260,7 @@ MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
256260
{
257261
size_t const nbBytes = bitC->bitPos >> 3;
258262
assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
263+
assert(bitC->ptr <= bitC->endPtr);
259264
MEM_writeLEST(bitC->ptr, bitC->bitContainer);
260265
bitC->ptr += nbBytes;
261266
if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;

ext/zstdruby/libzstd/common/compiler.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
# define INLINE_KEYWORD
2424
#endif
2525

26-
#if defined(__GNUC__)
26+
#if defined(__GNUC__) || defined(__ICCARM__)
2727
# define FORCE_INLINE_ATTR __attribute__((always_inline))
2828
#elif defined(_MSC_VER)
2929
# define FORCE_INLINE_ATTR __forceinline
@@ -61,11 +61,18 @@
6161
# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR
6262
#endif
6363

64+
/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
65+
#if defined(__GNUC__)
66+
# define UNUSED_ATTR __attribute__((unused))
67+
#else
68+
# define UNUSED_ATTR
69+
#endif
70+
6471
/* force no inlining */
6572
#ifdef _MSC_VER
6673
# define FORCE_NOINLINE static __declspec(noinline)
6774
#else
68-
# ifdef __GNUC__
75+
# if defined(__GNUC__) || defined(__ICCARM__)
6976
# define FORCE_NOINLINE static __attribute__((__noinline__))
7077
# else
7178
# define FORCE_NOINLINE static
@@ -76,7 +83,7 @@
7683
#ifndef __has_attribute
7784
#define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
7885
#endif
79-
#if defined(__GNUC__)
86+
#if defined(__GNUC__) || defined(__ICCARM__)
8087
# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
8188
#else
8289
# define TARGET_ATTRIBUTE(target)
@@ -127,9 +134,14 @@
127134
} \
128135
}
129136

130-
/* vectorization */
137+
/* vectorization
138+
* older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */
131139
#if !defined(__clang__) && defined(__GNUC__)
132-
# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
140+
# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
141+
# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
142+
# else
143+
# define DONT_VECTORIZE _Pragma("GCC optimize(\"no-tree-vectorize\")")
144+
# endif
133145
#else
134146
# define DONT_VECTORIZE
135147
#endif

ext/zstdruby/libzstd/common/fse.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ If there is an error, the function will return an error code, which can be teste
308308
*******************************************/
309309
/* FSE buffer bounds */
310310
#define FSE_NCOUNTBOUND 512
311-
#define FSE_BLOCKBOUND(size) (size + (size>>7))
311+
#define FSE_BLOCKBOUND(size) (size + (size>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */)
312312
#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
313313

314314
/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */

ext/zstdruby/libzstd/common/fse_decompress.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@
5252
#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */
5353

5454
/* check and forward error code */
55+
#ifndef CHECK_F
5556
#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; }
57+
#endif
5658

5759

5860
/* **************************************************************

ext/zstdruby/libzstd/common/mem.h

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,79 @@ extern "C" {
4747
#define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; }
4848
MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
4949

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+
50123

51124
/*-**************************************************************
52125
* Basic Types
@@ -102,7 +175,7 @@ MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (size
102175
#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
103176
# 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__) )
104177
# define MEM_FORCE_MEMORY_ACCESS 2
105-
# elif defined(__INTEL_COMPILER) || defined(__GNUC__)
178+
# elif defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__)
106179
# define MEM_FORCE_MEMORY_ACCESS 1
107180
# endif
108181
#endif

ext/zstdruby/libzstd/common/pool.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,13 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
127127
ctx->queueTail = 0;
128128
ctx->numThreadsBusy = 0;
129129
ctx->queueEmpty = 1;
130-
(void)ZSTD_pthread_mutex_init(&ctx->queueMutex, NULL);
131-
(void)ZSTD_pthread_cond_init(&ctx->queuePushCond, NULL);
132-
(void)ZSTD_pthread_cond_init(&ctx->queuePopCond, NULL);
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+
}
133137
ctx->shutdown = 0;
134138
/* Allocate space for the thread handles */
135139
ctx->threads = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), customMem);

ext/zstdruby/libzstd/common/threading.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* This file will hold wrapper for systems, which do not support pthreads
1515
*/
1616

17+
#include "threading.h"
18+
1719
/* create fake symbol to avoid empty translation unit warning */
1820
int g_ZSTD_threading_useless_symbol;
1921

@@ -28,7 +30,6 @@ int g_ZSTD_threading_useless_symbol;
2830
/* === Dependencies === */
2931
#include <process.h>
3032
#include <errno.h>
31-
#include "threading.h"
3233

3334

3435
/* === Implementation === */
@@ -73,3 +74,47 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
7374
}
7475

7576
#endif /* ZSTD_MULTITHREAD */
77+
78+
#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
79+
80+
#include <stdlib.h>
81+
82+
int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
83+
{
84+
*mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
85+
if (!*mutex)
86+
return 1;
87+
return pthread_mutex_init(*mutex, attr);
88+
}
89+
90+
int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
91+
{
92+
if (!*mutex)
93+
return 0;
94+
{
95+
int const ret = pthread_mutex_destroy(*mutex);
96+
free(*mutex);
97+
return ret;
98+
}
99+
}
100+
101+
int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
102+
{
103+
*cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));
104+
if (!*cond)
105+
return 1;
106+
return pthread_cond_init(*cond, attr);
107+
}
108+
109+
int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
110+
{
111+
if (!*cond)
112+
return 0;
113+
{
114+
int const ret = pthread_cond_destroy(*cond);
115+
free(*cond);
116+
return ret;
117+
}
118+
}
119+
120+
#endif

ext/zstdruby/libzstd/common/threading.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#ifndef THREADING_H_938743
1414
#define THREADING_H_938743
1515

16+
#include "debug.h"
17+
1618
#if defined (__cplusplus)
1719
extern "C" {
1820
#endif
@@ -75,10 +77,12 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread, void** value_ptr);
7577
*/
7678

7779

78-
#elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */
80+
#elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */
7981
/* === POSIX Systems === */
8082
# include <pthread.h>
8183

84+
#if DEBUGLEVEL < 1
85+
8286
#define ZSTD_pthread_mutex_t pthread_mutex_t
8387
#define ZSTD_pthread_mutex_init(a, b) pthread_mutex_init((a), (b))
8488
#define ZSTD_pthread_mutex_destroy(a) pthread_mutex_destroy((a))
@@ -96,6 +100,33 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread, void** value_ptr);
96100
#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))
97101
#define ZSTD_pthread_join(a, b) pthread_join((a),(b))
98102

103+
#else /* DEBUGLEVEL >= 1 */
104+
105+
/* Debug implementation of threading.
106+
* In this implementation we use pointers for mutexes and condition variables.
107+
* This way, if we forget to init/destroy them the program will crash or ASAN
108+
* will report leaks.
109+
*/
110+
111+
#define ZSTD_pthread_mutex_t pthread_mutex_t*
112+
int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr);
113+
int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex);
114+
#define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock(*(a))
115+
#define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock(*(a))
116+
117+
#define ZSTD_pthread_cond_t pthread_cond_t*
118+
int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr);
119+
int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond);
120+
#define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait(*(a), *(b))
121+
#define ZSTD_pthread_cond_signal(a) pthread_cond_signal(*(a))
122+
#define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast(*(a))
123+
124+
#define ZSTD_pthread_t pthread_t
125+
#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))
126+
#define ZSTD_pthread_join(a, b) pthread_join((a),(b))
127+
128+
#endif
129+
99130
#else /* ZSTD_MULTITHREAD not defined */
100131
/* No multithreading support */
101132

0 commit comments

Comments
 (0)