/* MtCoder.h -- Multi-thread Coder 2018-07-04 : Igor Pavlov : Public domain */ #ifndef __MT_CODER_H #define __MT_CODER_H #include "MtDec.h" EXTERN_C_BEGIN /* if ( defined MTCODER__USE_WRITE_THREAD) : main thread writes all data blocks to output stream if (not defined MTCODER__USE_WRITE_THREAD) : any coder thread can write data blocks to output stream */ /* #define MTCODER__USE_WRITE_THREAD */ #ifndef _7ZIP_ST #define MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1) #define MTCODER__THREADS_MAX 64 #define MTCODER__BLOCKS_MAX (MTCODER__GET_NUM_BLOCKS_FROM_THREADS(MTCODER__THREADS_MAX) + 3) #else #define MTCODER__THREADS_MAX 1 #define MTCODER__BLOCKS_MAX 1 #endif #ifndef _7ZIP_ST typedef struct { ICompressProgress vt; CMtProgress *mtProgress; UInt64 inSize; UInt64 outSize; } CMtProgressThunk; void MtProgressThunk_CreateVTable(CMtProgressThunk *p); #define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; } struct _CMtCoder; typedef struct { struct _CMtCoder *mtCoder; unsigned index; int stop; Byte *inBuf; CAutoResetEvent startEvent; CThread thread; } CMtCoderThread; typedef struct { SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex, const Byte *src, size_t srcSize, int finished); SRes (*Write)(void *p, unsigned outBufIndex); } IMtCoderCallback2; typedef struct { SRes res; unsigned bufIndex; BoolInt finished; } CMtCoderBlock; typedef struct _CMtCoder { /* input variables */ size_t blockSize; /* size of input block */ unsigned numThreadsMax; UInt64 expectedDataSize; ISeqInStream *inStream; const Byte *inData; size_t inDataSize; ICompressProgress *progress; ISzAllocPtr allocBig; IMtCoderCallback2 *mtCallback; void *mtCallbackObject; /* internal variables */ size_t allocatedBufsSize; CAutoResetEvent readEvent; CSemaphore blocksSemaphore; BoolInt stopReading; SRes readRes; #ifdef MTCODER__USE_WRITE_THREAD CAutoResetEvent writeEvents[MTCODER__BLOCKS_MAX]; #else CAutoResetEvent finishedEvent; SRes writeRes; unsigned writeIndex; Byte ReadyBlocks[MTCODER__BLOCKS_MAX]; LONG numFinishedThreads; #endif unsigned numStartedThreadsLimit; unsigned numStartedThreads; unsigned numBlocksMax; unsigned blockIndex; UInt64 readProcessed; CCriticalSection cs; unsigned freeBlockHead; unsigned freeBlockList[MTCODER__BLOCKS_MAX]; CMtProgress mtProgress; CMtCoderBlock blocks[MTCODER__BLOCKS_MAX]; CMtCoderThread threads[MTCODER__THREADS_MAX]; } CMtCoder; void MtCoder_Construct(CMtCoder *p); void MtCoder_Destruct(CMtCoder *p); SRes MtCoder_Code(CMtCoder *p); #endif EXTERN_C_END #endif