From e3c42c739b3e4e7541b9c9f6d063231819e866d3 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 7 Jun 2018 13:53:30 -0700 Subject: [PATCH] clean ZSTD_compress() initialization The (pretty old) code inside ZSTD_compress() was making some pretty bold assumptions on what's inside a CCtx and how to init it. This is pretty fragile by design. CCtx content evolve. Knowledge of how to handle that should be concentrate in one place. A side effect of this strategy is that ZSTD_compress() wouldn't check for BMI2 capability, and is therefore missing out some potential speed opportunity. This patch makes ZSTD_compress() use the same initialization and release functions as the normal creator / destructor ones. Measured on my laptop, with a custom version of bench manually modified to use ZSTD_compress() (instead of the advanced API) : This patch : 1#silesia.tar : 211984896 -> 73651053 (2.878), 312.2 MB/s , 723.8 MB/s 2#silesia.tar : 211984896 -> 70163650 (3.021), 226.2 MB/s , 649.8 MB/s 3#silesia.tar : 211984896 -> 66996749 (3.164), 169.4 MB/s , 636.7 MB/s 4#silesia.tar : 211984896 -> 65998319 (3.212), 136.7 MB/s , 619.2 MB/s dev branch : 1#silesia.tar : 211984896 -> 73651053 (2.878), 291.7 MB/s , 727.5 MB/s 2#silesia.tar : 211984896 -> 70163650 (3.021), 216.2 MB/s , 655.7 MB/s 3#silesia.tar : 211984896 -> 66996749 (3.164), 162.2 MB/s , 633.1 MB/s 4#silesia.tar : 211984896 -> 65998319 (3.212), 130.6 MB/s , 618.6 MB/s --- lib/compress/zstd_compress.c | 41 ++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 7a30d5525..fe4d65b66 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -64,19 +64,26 @@ ZSTD_CCtx* ZSTD_createCCtx(void) return ZSTD_createCCtx_advanced(ZSTD_defaultCMem); } +static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager) +{ + assert(cctx != NULL); + memset(cctx, 0, sizeof(*cctx)); + cctx->customMem = memManager; + cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); + { size_t const err = ZSTD_CCtx_resetParameters(cctx); + assert(!ZSTD_isError(err)); + (void)err; + } +} + ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) { ZSTD_STATIC_ASSERT(zcss_init==0); ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1)); if (!customMem.customAlloc ^ !customMem.customFree) return NULL; - { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_calloc(sizeof(ZSTD_CCtx), customMem); + { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_malloc(sizeof(ZSTD_CCtx), customMem); if (!cctx) return NULL; - cctx->customMem = customMem; - cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); - { size_t const err = ZSTD_CCtx_resetParameters(cctx); - assert(!ZSTD_isError(err)); - (void)err; - } + ZSTD_initCCtx(cctx, customMem); return cctx; } } @@ -104,17 +111,24 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize) return cctx; } -size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) +static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx) { - if (cctx==NULL) return 0; /* support free on NULL */ - if (cctx->staticSize) return ERROR(memory_allocation); /* not compatible with static CCtx */ + assert(cctx != NULL); + assert(cctx->staticSize == 0); ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL; ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL; #ifdef ZSTD_MULTITHREAD ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL; #endif +} + +size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) +{ + if (cctx==NULL) return 0; /* support free on NULL */ + if (cctx->staticSize) return ERROR(memory_allocation); /* not compatible with static CCtx */ + ZSTD_freeCCtxContent(cctx); ZSTD_free(cctx, cctx->customMem); - return 0; /* reserved as a potential error code in the future */ + return 0; } @@ -2963,10 +2977,9 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS { size_t result; ZSTD_CCtx ctxBody; - memset(&ctxBody, 0, sizeof(ctxBody)); - ctxBody.customMem = ZSTD_defaultCMem; + ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem); result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel); - ZSTD_free(ctxBody.workSpace, ZSTD_defaultCMem); /* can't free ctxBody itself, as it's on stack; free only heap content */ + ZSTD_freeCCtxContent(&ctxBody); /* can't free ctxBody itself, as it's on stack; free only heap content */ return result; } -- 2.47.2