1 /* MtDec.h -- Multi-thread Decoder
2 2018-03-02 : Igor Pavlov : Public domain */
18 #define MTDEC__THREADS_MAX 32
20 #define MTDEC__THREADS_MAX 1
26 ICompressProgress
*progress
;
33 void MtProgress_Init(CMtProgress
*p
, ICompressProgress
*progress
);
34 SRes
MtProgress_Progress_ST(CMtProgress
*p
);
35 SRes
MtProgress_ProgressAdd(CMtProgress
*p
, UInt64 inSize
, UInt64 outSize
);
36 SRes
MtProgress_GetError(CMtProgress
*p
);
37 void MtProgress_SetError(CMtProgress
*p
, SRes res
);
43 struct _CMtDec
*mtDec
;
47 size_t inDataSize_Start
; // size of input data in start block
48 UInt64 inDataSize
; // total size of input data in all blocks
51 CAutoResetEvent canRead
;
52 CAutoResetEvent canWrite
;
56 void MtDecThread_FreeInBufs(CMtDecThread
*t
);
61 MTDEC_PARSE_CONTINUE
, // continue this block with more input data
62 MTDEC_PARSE_OVERFLOW
, // MT buffers overflow, need switch to single-thread
63 MTDEC_PARSE_NEW
, // new block
64 MTDEC_PARSE_END
// end of block threading. But we still can return to threading after Write(&needContinue)
73 // in : (srcSize == 0) is allowed
74 // out : it's allowed to return less that actually was used ?
78 EMtDecParseState state
;
79 Bool canCreateNewThread
;
80 UInt64 outPos
; // check it (size_t)
86 void (*Parse
)(void *p
, unsigned coderIndex
, CMtDecCallbackInfo
*ci
);
88 // PreCode() and Code():
89 // (SRes_return_result != SZ_OK) means stop decoding, no need another blocks
90 SRes (*PreCode
)(void *p
, unsigned coderIndex
);
91 SRes (*Code
)(void *p
, unsigned coderIndex
,
92 const Byte
*src
, size_t srcSize
, int srcFinished
,
93 UInt64
*inCodePos
, UInt64
*outCodePos
, int *stop
);
94 // stop - means stop another Code calls
97 /* Write() must be called, if Parse() was called
100 && (was not interrupted by progress)
101 && (was not interrupted in previous block)
105 if (*needContinue), decoder still need to continue decoding with new iteration,
106 even after MTDEC_PARSE_END
107 if (*canRecode), we didn't flush current block data, so we still can decode current block later.
109 SRes (*Write
)(void *p
, unsigned coderIndex
,
110 Bool needWriteToStream
,
111 const Byte
*src
, size_t srcSize
,
119 typedef struct _CMtDec
121 /* input variables */
123 size_t inBufSize
; /* size of input block */
124 unsigned numThreadsMax
;
125 // size_t inBlockMax;
126 unsigned numThreadsMax_2
;
128 ISeqInStream
*inStream
;
129 // const Byte *inData;
130 // size_t inDataSize;
132 ICompressProgress
*progress
;
135 IMtDecCallback
*mtCallback
;
136 void *mtCallbackObject
;
139 /* internal variables */
141 size_t allocatedBufsSize
;
149 SRes threadingErrorSRes
;
153 // CAutoResetEvent finishedEvent;
160 unsigned numStartedThreads_Limit
;
161 unsigned numStartedThreads
;
166 UInt64 readProcessed
;
167 Bool readWasFinished
;
170 unsigned filledThreadStart
;
171 unsigned numFilledThreads
;
175 UInt64 interruptIndex
;
176 CMtProgress mtProgress
;
177 CMtDecThread threads
[MTDEC__THREADS_MAX
];
182 void MtDec_Construct(CMtDec
*p
);
183 void MtDec_Destruct(CMtDec
*p
);
186 MtDec_Code() returns:
187 SZ_OK - in most cases
188 MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function
191 SRes
MtDec_Code(CMtDec
*p
);
192 Byte
*MtDec_GetCrossBuff(CMtDec
*p
);
194 int MtDec_PrepareRead(CMtDec
*p
);
195 const Byte
*MtDec_Read(CMtDec
*p
, size_t *inLim
);