zstd/lib/common
Adenilson Cavalcanti 345bcb5ff7 [zstd][dict] Ensure that dictionary training functions are fully reentrant
The two main functions used for dictionary training using the COVER
algorithm require initialization of a COVER_ctx_t where a call
to qsort() is performed.

The issue is that the standard C99 qsort() function doesn't offer
a way to pass an extra parameter for the comparison function callback
(e.g. a pointer to a context) and currently zstd relies on a *global*
static variable to hold a pointer to a context needed to perform
the sort operation.

If a zstd library user invokes either ZDICT_trainFromBuffer_cover or
ZDICT_optimizeTrainFromBuffer_cover from multiple threads, the
global context may be overwritten before/during the call/execution to qsort()
in the initialization of the COVER_ctx_t, thus yielding to crashes
and other bad things (Tm) as reported on issue #4045.

Enters qsort_r(): it was designed to address precisely this situation,
to quote from the documention [1]: "the comparison function does not need to
use global variables to pass through arbitrary arguments, and is therefore
reentrant and safe to use in threads."

It is available with small variations for multiple OSes (GNU, BSD[2],
Windows[3]), and the ISO C11 [4] standard features on annex B-21 qsort_s() as
part of the <stdlib.h>. Let's hope that compilers eventually catch up
with it.

For now, we have to handle the small variations in function parameters
for each platform.

The current fix solves the problem by allowing each executing thread
pass its own COVER_ctx_t instance to qsort_r(), removing the use of
a global pointer and allowing the code to be reentrant.

Unfortunately for *BSD, we cannot leverage qsort_r() given that its API
has changed on newer versions of FreeBSD (14.0) and the other BSD variants
(e.g. NetBSD, OpenBSD) don't implement it.

For such cases we provide a fallback that will work only requiring support
for compilers implementing support for C90.

[1] https://man7.org/linux/man-pages/man3/qsort_r.3.html
[2] https://man.freebsd.org/cgi/man.cgi?query=qsort_r
[3] https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/qsort-s?view=msvc-170
[4] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf
2024-07-01 23:52:31 -07:00
..
allocations.h fixed MEM_STATIC already defined in Linux Kernel mode 2023-06-14 20:07:18 -07:00
bits.h Improve support for IAR compiler with attributes and intrinsics 2024-05-14 17:01:19 +08:00
bitstream.h removed _old variant from splitLit 2023-06-16 14:42:28 -07:00
compiler.h Fix typos not found by codespell 2024-06-20 20:16:25 +02:00
cpu.h Fix building on windows-x86 if clang already includes 2024-04-01 09:53:08 -07:00
debug.c [debug] Don't define g_debuglevel in the kernel 2023-11-17 09:54:10 -08:00
debug.h add line number to debug traces 2024-03-14 12:11:11 -07:00
entropy_common.c revert FSE_readNCount_body attribute 2024-05-15 10:47:50 +08:00
error_private.c Rename "External Matchfinder" to "Block-Level Sequence Producer" (#3484) 2023-02-09 17:01:17 -05:00
error_private.h Modernize macros to use do { } while (0) 2023-11-21 20:05:17 -05:00
fse.h revert to manually defining DTable 2023-10-18 22:45:57 -07:00
fse_decompress.c Throw error if Huffman weight initial states are truncated 2024-06-20 17:46:16 -04:00
huf.h Fix & refactor Huffman repeat tables for dictionaries 2023-08-25 13:21:58 -04:00
mem.h Improve support for IAR compiler with attributes and intrinsics 2024-05-14 17:01:19 +08:00
pool.c playTests.sh does no longer needs grep -E 2024-01-15 11:16:46 -08:00
pool.h Fix new typos found by codespell 2023-09-23 18:56:01 +02:00
portability_macros.h Fix typos not found by codespell 2024-06-20 20:16:25 +02:00
threading.c fixed incorrect test in Win32 pthread wrapper 2023-06-20 08:34:26 -07:00
threading.h Fix race condition in the Windows thread / pthread translation layer 2022-12-17 13:38:02 -08:00
xxhash.c update license text 2023-11-16 16:19:25 -08:00
xxhash.h Merge pull request #3933 from facebook/fix3819 2024-03-12 09:46:48 -07:00
zstd_common.c Fix zstd-dll build missing dependencies (#3496) 2023-02-12 12:32:31 -08:00
zstd_deps.h [zstd][dict] Ensure that dictionary training functions are fully reentrant 2024-07-01 23:52:31 -07:00
zstd_internal.h Modernize macros to use do { } while (0) 2023-11-21 20:05:17 -05:00
zstd_trace.h Update Copyright Headers 'Facebook' -> 'Meta Platforms' 2022-12-20 12:37:57 -05:00