xref: /aosp_15_r20/external/lzma/C/MtDec.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* MtDec.h -- Multi-thread Decoder
2*f6dc9357SAndroid Build Coastguard Worker 2023-04-02 : Igor Pavlov : Public domain */
3*f6dc9357SAndroid Build Coastguard Worker 
4*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_MT_DEC_H
5*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_MT_DEC_H
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "7zTypes.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
10*f6dc9357SAndroid Build Coastguard Worker #include "Threads.h"
11*f6dc9357SAndroid Build Coastguard Worker #endif
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
18*f6dc9357SAndroid Build Coastguard Worker   #define MTDEC_THREADS_MAX 32
19*f6dc9357SAndroid Build Coastguard Worker #else
20*f6dc9357SAndroid Build Coastguard Worker   #define MTDEC_THREADS_MAX 1
21*f6dc9357SAndroid Build Coastguard Worker #endif
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker typedef struct
25*f6dc9357SAndroid Build Coastguard Worker {
26*f6dc9357SAndroid Build Coastguard Worker   ICompressProgressPtr progress;
27*f6dc9357SAndroid Build Coastguard Worker   SRes res;
28*f6dc9357SAndroid Build Coastguard Worker   UInt64 totalInSize;
29*f6dc9357SAndroid Build Coastguard Worker   UInt64 totalOutSize;
30*f6dc9357SAndroid Build Coastguard Worker   CCriticalSection cs;
31*f6dc9357SAndroid Build Coastguard Worker } CMtProgress;
32*f6dc9357SAndroid Build Coastguard Worker 
33*f6dc9357SAndroid Build Coastguard Worker void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress);
34*f6dc9357SAndroid Build Coastguard Worker SRes MtProgress_Progress_ST(CMtProgress *p);
35*f6dc9357SAndroid Build Coastguard Worker SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize);
36*f6dc9357SAndroid Build Coastguard Worker SRes MtProgress_GetError(CMtProgress *p);
37*f6dc9357SAndroid Build Coastguard Worker void MtProgress_SetError(CMtProgress *p, SRes res);
38*f6dc9357SAndroid Build Coastguard Worker 
39*f6dc9357SAndroid Build Coastguard Worker struct CMtDec;
40*f6dc9357SAndroid Build Coastguard Worker 
41*f6dc9357SAndroid Build Coastguard Worker typedef struct
42*f6dc9357SAndroid Build Coastguard Worker {
43*f6dc9357SAndroid Build Coastguard Worker   struct CMtDec_ *mtDec;
44*f6dc9357SAndroid Build Coastguard Worker   unsigned index;
45*f6dc9357SAndroid Build Coastguard Worker   void *inBuf;
46*f6dc9357SAndroid Build Coastguard Worker 
47*f6dc9357SAndroid Build Coastguard Worker   size_t inDataSize_Start; // size of input data in start block
48*f6dc9357SAndroid Build Coastguard Worker   UInt64 inDataSize;       // total size of input data in all blocks
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker   CThread thread;
51*f6dc9357SAndroid Build Coastguard Worker   CAutoResetEvent canRead;
52*f6dc9357SAndroid Build Coastguard Worker   CAutoResetEvent canWrite;
53*f6dc9357SAndroid Build Coastguard Worker   void  *allocaPtr;
54*f6dc9357SAndroid Build Coastguard Worker } CMtDecThread;
55*f6dc9357SAndroid Build Coastguard Worker 
56*f6dc9357SAndroid Build Coastguard Worker void MtDecThread_FreeInBufs(CMtDecThread *t);
57*f6dc9357SAndroid Build Coastguard Worker 
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker typedef enum
60*f6dc9357SAndroid Build Coastguard Worker {
61*f6dc9357SAndroid Build Coastguard Worker   MTDEC_PARSE_CONTINUE, // continue this block with more input data
62*f6dc9357SAndroid Build Coastguard Worker   MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread
63*f6dc9357SAndroid Build Coastguard Worker   MTDEC_PARSE_NEW,      // new block
64*f6dc9357SAndroid Build Coastguard Worker   MTDEC_PARSE_END       // end of block threading. But we still can return to threading after Write(&needContinue)
65*f6dc9357SAndroid Build Coastguard Worker } EMtDecParseState;
66*f6dc9357SAndroid Build Coastguard Worker 
67*f6dc9357SAndroid Build Coastguard Worker typedef struct
68*f6dc9357SAndroid Build Coastguard Worker {
69*f6dc9357SAndroid Build Coastguard Worker   // in
70*f6dc9357SAndroid Build Coastguard Worker   int startCall;
71*f6dc9357SAndroid Build Coastguard Worker   const Byte *src;
72*f6dc9357SAndroid Build Coastguard Worker   size_t srcSize;
73*f6dc9357SAndroid Build Coastguard Worker       // in  : (srcSize == 0) is allowed
74*f6dc9357SAndroid Build Coastguard Worker       // out : it's allowed to return less that actually was used ?
75*f6dc9357SAndroid Build Coastguard Worker   int srcFinished;
76*f6dc9357SAndroid Build Coastguard Worker 
77*f6dc9357SAndroid Build Coastguard Worker   // out
78*f6dc9357SAndroid Build Coastguard Worker   EMtDecParseState state;
79*f6dc9357SAndroid Build Coastguard Worker   BoolInt canCreateNewThread;
80*f6dc9357SAndroid Build Coastguard Worker   UInt64 outPos; // check it (size_t)
81*f6dc9357SAndroid Build Coastguard Worker } CMtDecCallbackInfo;
82*f6dc9357SAndroid Build Coastguard Worker 
83*f6dc9357SAndroid Build Coastguard Worker 
84*f6dc9357SAndroid Build Coastguard Worker typedef struct
85*f6dc9357SAndroid Build Coastguard Worker {
86*f6dc9357SAndroid Build Coastguard Worker   void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci);
87*f6dc9357SAndroid Build Coastguard Worker 
88*f6dc9357SAndroid Build Coastguard Worker   // PreCode() and Code():
89*f6dc9357SAndroid Build Coastguard Worker   // (SRes_return_result != SZ_OK) means stop decoding, no need another blocks
90*f6dc9357SAndroid Build Coastguard Worker   SRes (*PreCode)(void *p, unsigned coderIndex);
91*f6dc9357SAndroid Build Coastguard Worker   SRes (*Code)(void *p, unsigned coderIndex,
92*f6dc9357SAndroid Build Coastguard Worker       const Byte *src, size_t srcSize, int srcFinished,
93*f6dc9357SAndroid Build Coastguard Worker       UInt64 *inCodePos, UInt64 *outCodePos, int *stop);
94*f6dc9357SAndroid Build Coastguard Worker   // stop - means stop another Code calls
95*f6dc9357SAndroid Build Coastguard Worker 
96*f6dc9357SAndroid Build Coastguard Worker 
97*f6dc9357SAndroid Build Coastguard Worker   /* Write() must be called, if Parse() was called
98*f6dc9357SAndroid Build Coastguard Worker       set (needWrite) if
99*f6dc9357SAndroid Build Coastguard Worker       {
100*f6dc9357SAndroid Build Coastguard Worker          && (was not interrupted by progress)
101*f6dc9357SAndroid Build Coastguard Worker          && (was not interrupted in previous block)
102*f6dc9357SAndroid Build Coastguard Worker       }
103*f6dc9357SAndroid Build Coastguard Worker 
104*f6dc9357SAndroid Build Coastguard Worker     out:
105*f6dc9357SAndroid Build Coastguard Worker       if (*needContinue), decoder still need to continue decoding with new iteration,
106*f6dc9357SAndroid Build Coastguard Worker          even after MTDEC_PARSE_END
107*f6dc9357SAndroid Build Coastguard Worker       if (*canRecode), we didn't flush current block data, so we still can decode current block later.
108*f6dc9357SAndroid Build Coastguard Worker   */
109*f6dc9357SAndroid Build Coastguard Worker   SRes (*Write)(void *p, unsigned coderIndex,
110*f6dc9357SAndroid Build Coastguard Worker       BoolInt needWriteToStream,
111*f6dc9357SAndroid Build Coastguard Worker       const Byte *src, size_t srcSize, BoolInt isCross,
112*f6dc9357SAndroid Build Coastguard Worker       // int srcFinished,
113*f6dc9357SAndroid Build Coastguard Worker       BoolInt *needContinue,
114*f6dc9357SAndroid Build Coastguard Worker       BoolInt *canRecode);
115*f6dc9357SAndroid Build Coastguard Worker 
116*f6dc9357SAndroid Build Coastguard Worker } IMtDecCallback2;
117*f6dc9357SAndroid Build Coastguard Worker 
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker 
120*f6dc9357SAndroid Build Coastguard Worker typedef struct CMtDec_
121*f6dc9357SAndroid Build Coastguard Worker {
122*f6dc9357SAndroid Build Coastguard Worker   /* input variables */
123*f6dc9357SAndroid Build Coastguard Worker 
124*f6dc9357SAndroid Build Coastguard Worker   size_t inBufSize;        /* size of input block */
125*f6dc9357SAndroid Build Coastguard Worker   unsigned numThreadsMax;
126*f6dc9357SAndroid Build Coastguard Worker   // size_t inBlockMax;
127*f6dc9357SAndroid Build Coastguard Worker   unsigned numThreadsMax_2;
128*f6dc9357SAndroid Build Coastguard Worker 
129*f6dc9357SAndroid Build Coastguard Worker   ISeqInStreamPtr inStream;
130*f6dc9357SAndroid Build Coastguard Worker   // const Byte *inData;
131*f6dc9357SAndroid Build Coastguard Worker   // size_t inDataSize;
132*f6dc9357SAndroid Build Coastguard Worker 
133*f6dc9357SAndroid Build Coastguard Worker   ICompressProgressPtr progress;
134*f6dc9357SAndroid Build Coastguard Worker   ISzAllocPtr alloc;
135*f6dc9357SAndroid Build Coastguard Worker 
136*f6dc9357SAndroid Build Coastguard Worker   IMtDecCallback2 *mtCallback;
137*f6dc9357SAndroid Build Coastguard Worker   void *mtCallbackObject;
138*f6dc9357SAndroid Build Coastguard Worker 
139*f6dc9357SAndroid Build Coastguard Worker 
140*f6dc9357SAndroid Build Coastguard Worker   /* internal variables */
141*f6dc9357SAndroid Build Coastguard Worker 
142*f6dc9357SAndroid Build Coastguard Worker   size_t allocatedBufsSize;
143*f6dc9357SAndroid Build Coastguard Worker 
144*f6dc9357SAndroid Build Coastguard Worker   BoolInt exitThread;
145*f6dc9357SAndroid Build Coastguard Worker   WRes exitThreadWRes;
146*f6dc9357SAndroid Build Coastguard Worker 
147*f6dc9357SAndroid Build Coastguard Worker   UInt64 blockIndex;
148*f6dc9357SAndroid Build Coastguard Worker   BoolInt isAllocError;
149*f6dc9357SAndroid Build Coastguard Worker   BoolInt overflow;
150*f6dc9357SAndroid Build Coastguard Worker   SRes threadingErrorSRes;
151*f6dc9357SAndroid Build Coastguard Worker 
152*f6dc9357SAndroid Build Coastguard Worker   BoolInt needContinue;
153*f6dc9357SAndroid Build Coastguard Worker 
154*f6dc9357SAndroid Build Coastguard Worker   // CAutoResetEvent finishedEvent;
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker   SRes readRes;
157*f6dc9357SAndroid Build Coastguard Worker   SRes codeRes;
158*f6dc9357SAndroid Build Coastguard Worker 
159*f6dc9357SAndroid Build Coastguard Worker   BoolInt wasInterrupted;
160*f6dc9357SAndroid Build Coastguard Worker 
161*f6dc9357SAndroid Build Coastguard Worker   unsigned numStartedThreads_Limit;
162*f6dc9357SAndroid Build Coastguard Worker   unsigned numStartedThreads;
163*f6dc9357SAndroid Build Coastguard Worker 
164*f6dc9357SAndroid Build Coastguard Worker   Byte *crossBlock;
165*f6dc9357SAndroid Build Coastguard Worker   size_t crossStart;
166*f6dc9357SAndroid Build Coastguard Worker   size_t crossEnd;
167*f6dc9357SAndroid Build Coastguard Worker   UInt64 readProcessed;
168*f6dc9357SAndroid Build Coastguard Worker   BoolInt readWasFinished;
169*f6dc9357SAndroid Build Coastguard Worker   UInt64 inProcessed;
170*f6dc9357SAndroid Build Coastguard Worker 
171*f6dc9357SAndroid Build Coastguard Worker   unsigned filledThreadStart;
172*f6dc9357SAndroid Build Coastguard Worker   unsigned numFilledThreads;
173*f6dc9357SAndroid Build Coastguard Worker 
174*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
175*f6dc9357SAndroid Build Coastguard Worker   BoolInt needInterrupt;
176*f6dc9357SAndroid Build Coastguard Worker   UInt64 interruptIndex;
177*f6dc9357SAndroid Build Coastguard Worker   CMtProgress mtProgress;
178*f6dc9357SAndroid Build Coastguard Worker   CMtDecThread threads[MTDEC_THREADS_MAX];
179*f6dc9357SAndroid Build Coastguard Worker   #endif
180*f6dc9357SAndroid Build Coastguard Worker } CMtDec;
181*f6dc9357SAndroid Build Coastguard Worker 
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker void MtDec_Construct(CMtDec *p);
184*f6dc9357SAndroid Build Coastguard Worker void MtDec_Destruct(CMtDec *p);
185*f6dc9357SAndroid Build Coastguard Worker 
186*f6dc9357SAndroid Build Coastguard Worker /*
187*f6dc9357SAndroid Build Coastguard Worker MtDec_Code() returns:
188*f6dc9357SAndroid Build Coastguard Worker   SZ_OK - in most cases
189*f6dc9357SAndroid Build Coastguard Worker   MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function
190*f6dc9357SAndroid Build Coastguard Worker */
191*f6dc9357SAndroid Build Coastguard Worker 
192*f6dc9357SAndroid Build Coastguard Worker SRes MtDec_Code(CMtDec *p);
193*f6dc9357SAndroid Build Coastguard Worker Byte *MtDec_GetCrossBuff(CMtDec *p);
194*f6dc9357SAndroid Build Coastguard Worker 
195*f6dc9357SAndroid Build Coastguard Worker int MtDec_PrepareRead(CMtDec *p);
196*f6dc9357SAndroid Build Coastguard Worker const Byte *MtDec_Read(CMtDec *p, size_t *inLim);
197*f6dc9357SAndroid Build Coastguard Worker 
198*f6dc9357SAndroid Build Coastguard Worker #endif
199*f6dc9357SAndroid Build Coastguard Worker 
200*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
201*f6dc9357SAndroid Build Coastguard Worker 
202*f6dc9357SAndroid Build Coastguard Worker #endif
203