1
0
mirror of https://github.com/facebook/zstd.git synced 2025-07-28 00:01:53 +03:00

check pthread_*_init() success condition

This commit is contained in:
Yann Collet
2017-07-19 01:05:40 -07:00
parent 44b0838253
commit b71363b967
4 changed files with 62 additions and 53 deletions

View File

@ -80,9 +80,9 @@ extern "C" {
* bitStream encoding API (write forward) * bitStream encoding API (write forward)
********************************************/ ********************************************/
/* bitStream can mix input from multiple sources. /* bitStream can mix input from multiple sources.
* A critical property of these streams is that they encode and decode in **reverse** direction. * A critical property of these streams is that they encode and decode in **reverse** direction.
* So the first bit sequence you add will be the last to be read, like a LIFO stack. * So the first bit sequence you add will be the last to be read, like a LIFO stack.
*/ */
typedef struct typedef struct
{ {
size_t bitContainer; size_t bitContainer;
@ -203,7 +203,7 @@ static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F,
/*! BIT_initCStream() : /*! BIT_initCStream() :
* `dstCapacity` must be > sizeof(size_t) * `dstCapacity` must be > sizeof(size_t)
* @return : 0 if success, * @return : 0 if success,
otherwise an error code (can be tested using ERR_isError() ) */ * otherwise an error code (can be tested using ERR_isError()) */
MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
void* startPtr, size_t dstCapacity) void* startPtr, size_t dstCapacity)
{ {
@ -217,8 +217,8 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
} }
/*! BIT_addBits() : /*! BIT_addBits() :
can add up to 26 bits into `bitC`. * can add up to 26 bits into `bitC`.
Does not check for register overflow ! */ * Note : does not check for register overflow ! */
MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
size_t value, unsigned nbBits) size_t value, unsigned nbBits)
{ {
@ -268,7 +268,7 @@ MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
/*! BIT_closeCStream() : /*! BIT_closeCStream() :
* @return : size of CStream, in bytes, * @return : size of CStream, in bytes,
or 0 if it could not fit into dstBuffer */ * or 0 if it could not fit into dstBuffer */
MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
{ {
BIT_addBitsFast(bitC, 1, 1); /* endMark */ BIT_addBitsFast(bitC, 1, 1); /* endMark */
@ -279,14 +279,14 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
/*-******************************************************** /*-********************************************************
* bitStream decoding * bitStream decoding
**********************************************************/ **********************************************************/
/*! BIT_initDStream() : /*! BIT_initDStream() :
* Initialize a BIT_DStream_t. * Initialize a BIT_DStream_t.
* `bitD` : a pointer to an already allocated BIT_DStream_t structure. * `bitD` : a pointer to an already allocated BIT_DStream_t structure.
* `srcSize` must be the *exact* size of the bitStream, in bytes. * `srcSize` must be the *exact* size of the bitStream, in bytes.
* @return : size of stream (== srcSize) or an errorCode if a problem is detected * @return : size of stream (== srcSize), or an errorCode if a problem is detected
*/ */
MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
{ {
if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
@ -305,29 +305,30 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
bitD->bitContainer = *(const BYTE*)(bitD->start); bitD->bitContainer = *(const BYTE*)(bitD->start);
switch(srcSize) switch(srcSize)
{ {
case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
/* fall-through */ /* fall-through */
case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
/* fall-through */ /* fall-through */
case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
/* fall-through */ /* fall-through */
case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
/* fall-through */ /* fall-through */
case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
/* fall-through */ /* fall-through */
case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8; case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
/* fall-through */ /* fall-through */
default: break; default: break;
}
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
} }
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
} }
@ -363,9 +364,8 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
* local register is not modified. * local register is not modified.
* On 32-bits, maxNbBits==24. * On 32-bits, maxNbBits==24.
* On 64-bits, maxNbBits==56. * On 64-bits, maxNbBits==56.
* @return : value extracted * @return : value extracted */
*/ MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
{ {
#if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */ #if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */
return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
@ -392,8 +392,7 @@ MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
/*! BIT_readBits() : /*! BIT_readBits() :
* Read (consume) next n bits from local register and update. * Read (consume) next n bits from local register and update.
* Pay attention to not read more than nbBits contained into local register. * Pay attention to not read more than nbBits contained into local register.
* @return : extracted value. * @return : extracted value. */
*/
MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
{ {
size_t const value = BIT_lookBits(bitD, nbBits); size_t const value = BIT_lookBits(bitD, nbBits);
@ -402,7 +401,7 @@ MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
} }
/*! BIT_readBitsFast() : /*! BIT_readBitsFast() :
* unsafe version; only works only if nbBits >= 1 */ * unsafe version; only works only if nbBits >= 1 */
MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
{ {
size_t const value = BIT_lookBitsFast(bitD, nbBits); size_t const value = BIT_lookBitsFast(bitD, nbBits);
@ -412,10 +411,10 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
} }
/*! BIT_reloadDStream() : /*! BIT_reloadDStream() :
* Refill `bitD` from buffer previously set in BIT_initDStream() . * Refill `bitD` from buffer previously set in BIT_initDStream() .
* This function is safe, it guarantees it will not read beyond src buffer. * This function is safe, it guarantees it will not read beyond src buffer.
* @return : status of `BIT_DStream_t` internal register. * @return : status of `BIT_DStream_t` internal register.
if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */ * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
{ {
if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */ if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
@ -446,8 +445,8 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
} }
/*! BIT_endOfDStream() : /*! BIT_endOfDStream() :
* @return Tells if DStream has exactly reached its end (all bits consumed). * @return : 1 if DStream has _exactly_ reached its end (all bits consumed).
*/ */
MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
{ {
return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));

View File

@ -80,14 +80,14 @@ int _pthread_join(pthread_t* thread, void** value_ptr);
#else /* ZSTD_MULTITHREAD not defined */ #else /* ZSTD_MULTITHREAD not defined */
/* No multithreading support */ /* No multithreading support */
#define pthread_mutex_t int /* #define rather than typedef, as sometimes pthread support is implicit, resulting in duplicated symbols */ #define pthread_mutex_t int /* #define rather than typedef, because sometimes pthread support is implicit, resulting in duplicated symbols */
#define pthread_mutex_init(a,b) #define pthread_mutex_init(a,b) ((void)a, 0)
#define pthread_mutex_destroy(a) #define pthread_mutex_destroy(a)
#define pthread_mutex_lock(a) #define pthread_mutex_lock(a)
#define pthread_mutex_unlock(a) #define pthread_mutex_unlock(a)
#define pthread_cond_t int #define pthread_cond_t int
#define pthread_cond_init(a,b) #define pthread_cond_init(a,b) ((void)a, 0)
#define pthread_cond_destroy(a) #define pthread_cond_destroy(a)
#define pthread_cond_wait(a,b) #define pthread_cond_wait(a,b)
#define pthread_cond_signal(a) #define pthread_cond_signal(a)

View File

@ -98,7 +98,10 @@ static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned nbThreads, ZSTD_custo
ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_calloc( ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_calloc(
sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem); sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem);
if (bufPool==NULL) return NULL; if (bufPool==NULL) return NULL;
pthread_mutex_init(&bufPool->poolMutex, NULL); if (pthread_mutex_init(&bufPool->poolMutex, NULL)) {
ZSTD_free(bufPool, cMem);
return NULL;
}
bufPool->bufferSize = 64 KB; bufPool->bufferSize = 64 KB;
bufPool->totalBuffers = maxNbBuffers; bufPool->totalBuffers = maxNbBuffers;
bufPool->nbBuffers = 0; bufPool->nbBuffers = 0;
@ -213,7 +216,10 @@ static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(unsigned nbThreads,
ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_calloc( ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_calloc(
sizeof(ZSTDMT_CCtxPool) + (nbThreads-1)*sizeof(ZSTD_CCtx*), cMem); sizeof(ZSTDMT_CCtxPool) + (nbThreads-1)*sizeof(ZSTD_CCtx*), cMem);
if (!cctxPool) return NULL; if (!cctxPool) return NULL;
pthread_mutex_init(&cctxPool->poolMutex, NULL); if (pthread_mutex_init(&cctxPool->poolMutex, NULL)) {
ZSTD_free(cctxPool, cMem);
return NULL;
}
cctxPool->cMem = cMem; cctxPool->cMem = cMem;
cctxPool->totalCCtx = nbThreads; cctxPool->totalCCtx = nbThreads;
cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */ cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */
@ -429,8 +435,14 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem)
ZSTDMT_freeCCtx(mtctx); ZSTDMT_freeCCtx(mtctx);
return NULL; return NULL;
} }
pthread_mutex_init(&mtctx->jobCompleted_mutex, NULL); /* Todo : check init function return */ if (pthread_mutex_init(&mtctx->jobCompleted_mutex, NULL)) {
pthread_cond_init(&mtctx->jobCompleted_cond, NULL); ZSTDMT_freeCCtx(mtctx);
return NULL;
}
if (pthread_cond_init(&mtctx->jobCompleted_cond, NULL)) {
ZSTDMT_freeCCtx(mtctx);
return NULL;
}
DEBUGLOG(3, "mt_cctx created, for %u threads", nbThreads); DEBUGLOG(3, "mt_cctx created, for %u threads", nbThreads);
return mtctx; return mtctx;
} }

View File

@ -714,11 +714,9 @@ typedef struct COVER_best_s {
* Initialize the `COVER_best_t`. * Initialize the `COVER_best_t`.
*/ */
static void COVER_best_init(COVER_best_t *best) { static void COVER_best_init(COVER_best_t *best) {
if (!best) { if (best==NULL) return; /* compatible with init on NULL */
return; (void)pthread_mutex_init(&best->mutex, NULL);
} (void)pthread_cond_init(&best->cond, NULL);
pthread_mutex_init(&best->mutex, NULL);
pthread_cond_init(&best->cond, NULL);
best->liveJobs = 0; best->liveJobs = 0;
best->dict = NULL; best->dict = NULL;
best->dictSize = 0; best->dictSize = 0;