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