MtDec.h 4.5 KB

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