-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[zstd][dict] Ensure that dictionary training functions are fully reen… #4078
Changes from all commits
0de6e7d
6fd20e1
ff61288
730b97f
30bba5e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,8 +21,16 @@ | |
/*-************************************* | ||
* Dependencies | ||
***************************************/ | ||
/* qsort_r is an extension. */ | ||
#if defined(__linux) || defined(__linux__) || defined(linux) || defined(__gnu_linux__) || defined(__CYGWIN__) || defined(__MSYS__) | ||
#if !defined(_GNU_SOURCE) | ||
#define _GNU_SOURCE | ||
#endif | ||
#endif | ||
|
||
#include <stdio.h> /* fprintf */ | ||
#include <stdlib.h> /* malloc, free, qsort */ | ||
#include <stdlib.h> /* malloc, free, qsort_r */ | ||
|
||
#include <string.h> /* memset */ | ||
#include <time.h> /* clock */ | ||
|
||
|
@@ -232,8 +240,10 @@ typedef struct { | |
unsigned d; | ||
} COVER_ctx_t; | ||
|
||
/* We need a global context for qsort... */ | ||
#if !defined(_GNU_SOURCE) && !defined(__APPLE__) && !defined(_MSC_VER) | ||
/* C90 only offers qsort() that needs a global context. */ | ||
static COVER_ctx_t *g_coverCtx = NULL; | ||
#endif | ||
|
||
/*-************************************* | ||
* Helper functions | ||
|
@@ -276,11 +286,17 @@ static int COVER_cmp8(COVER_ctx_t *ctx, const void *lp, const void *rp) { | |
|
||
/** | ||
* Same as COVER_cmp() except ties are broken by pointer value | ||
* NOTE: g_coverCtx must be set to call this function. A global is required because | ||
* qsort doesn't take an opaque pointer. | ||
*/ | ||
#if defined(_WIN32) && defined(_MSC_VER) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way Given that the function signature is a mandated parameter of the Ultimately, this is a comment focused on "readability". The functionality itself looks good. |
||
static int WIN_CDECL COVER_strict_cmp(void* g_coverCtx, const void* lp, const void* rp) { | ||
#elif defined(__APPLE__) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I got test if treating *BSD as APPLE could do the trick... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It won't. Newer FreeBSD has the same syntax as GNU, but older has the same syntax as APPLE. I will let go of FreeBSD for now and revisit the issue in a follow up patch. |
||
static int WIN_CDECL COVER_strict_cmp(void *g_coverCtx, const void *lp, const void *rp) { | ||
#elif defined(_GNU_SOURCE) | ||
static int WIN_CDECL COVER_strict_cmp(const void *lp, const void *rp, void *g_coverCtx) { | ||
#else /* C90 fallback.*/ | ||
static int WIN_CDECL COVER_strict_cmp(const void *lp, const void *rp) { | ||
int result = COVER_cmp(g_coverCtx, lp, rp); | ||
#endif | ||
int result = COVER_cmp((COVER_ctx_t*)g_coverCtx, lp, rp); | ||
if (result == 0) { | ||
result = lp < rp ? -1 : 1; | ||
} | ||
|
@@ -289,8 +305,16 @@ static int WIN_CDECL COVER_strict_cmp(const void *lp, const void *rp) { | |
/** | ||
* Faster version for d <= 8. | ||
*/ | ||
#if defined(_WIN32) && defined(_MSC_VER) | ||
static int WIN_CDECL COVER_strict_cmp8(void* g_coverCtx, const void* lp, const void* rp) { | ||
#elif defined(__APPLE__) | ||
static int WIN_CDECL COVER_strict_cmp8(void *g_coverCtx, const void *lp, const void *rp) { | ||
#elif defined(_GNU_SOURCE) | ||
static int WIN_CDECL COVER_strict_cmp8(const void *lp, const void *rp, void *g_coverCtx) { | ||
#else /* C90 fallback.*/ | ||
static int WIN_CDECL COVER_strict_cmp8(const void *lp, const void *rp) { | ||
int result = COVER_cmp8(g_coverCtx, lp, rp); | ||
#endif | ||
int result = COVER_cmp8((COVER_ctx_t*)g_coverCtx, lp, rp); | ||
if (result == 0) { | ||
result = lp < rp ? -1 : 1; | ||
} | ||
|
@@ -620,14 +644,24 @@ static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer, | |
for (i = 0; i < ctx->suffixSize; ++i) { | ||
ctx->suffix[i] = i; | ||
} | ||
/* qsort doesn't take an opaque pointer, so pass as a global. | ||
* On OpenBSD qsort() is not guaranteed to be stable, their mergesort() is. | ||
*/ | ||
g_coverCtx = ctx; | ||
#if defined(__OpenBSD__) | ||
#if defined(__APPLE__) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32), | ||
ctx, | ||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); | ||
#elif defined(_GNU_SOURCE) | ||
qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32), | ||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp), | ||
ctx); | ||
#elif defined(_WIN32) && defined(_MSC_VER) | ||
qsort_s(ctx->suffix, ctx->suffixSize, sizeof(U32), | ||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp), | ||
ctx); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And we will have to add some kind of fallback for C90. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. The fallback for no is the same code as is being shipped by zstd. In a follow up patch we can try to provide a reentrant qsort_r() for platforms that don't have it. |
||
#elif defined(__OpenBSD__) | ||
mergesort(ctx->suffix, ctx->suffixSize, sizeof(U32), | ||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); | ||
#else | ||
#else /* C90 fallback.*/ | ||
g_coverCtx = ctx; | ||
/* TODO(cavalcanti): implement a reentrant qsort() when is not available. */ | ||
qsort(ctx->suffix, ctx->suffixSize, sizeof(U32), | ||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp)); | ||
#endif | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only define it if not already defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.