2018-11-08 11:52:06 +00:00
|
|
|
/* MtCoder.h -- Multi-thread Coder
|
2019-07-15 13:16:24 +00:00
|
|
|
2018-07-04 : Igor Pavlov : Public domain */
|
2018-11-08 11:52:06 +00:00
|
|
|
|
|
|
|
#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;
|
2019-07-15 13:16:24 +00:00
|
|
|
BoolInt finished;
|
2018-11-08 11:52:06 +00:00
|
|
|
} 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;
|
|
|
|
|
2019-07-15 13:16:24 +00:00
|
|
|
BoolInt stopReading;
|
2018-11-08 11:52:06 +00:00
|
|
|
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
|