1 /* MtCoder.h -- Multi-thread Coder
2 2018-02-21 : Igor Pavlov : Public domain */
3 
4 #ifndef __MT_CODER_H
5 #define __MT_CODER_H
6 
7 #include "MtDec.h"
8 
9 EXTERN_C_BEGIN
10 
11 /*
12   if (    defined MTCODER__USE_WRITE_THREAD) : main thread writes all data blocks to output stream
13   if (not defined MTCODER__USE_WRITE_THREAD) : any coder thread can write data blocks to output stream
14 */
15 /* #define MTCODER__USE_WRITE_THREAD */
16 
17 #ifndef _7ZIP_ST
18   #define MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1)
19   #define MTCODER__THREADS_MAX 64
20   #define MTCODER__BLOCKS_MAX (MTCODER__GET_NUM_BLOCKS_FROM_THREADS(MTCODER__THREADS_MAX) + 3)
21 #else
22   #define MTCODER__THREADS_MAX 1
23   #define MTCODER__BLOCKS_MAX 1
24 #endif
25 
26 
27 #ifndef _7ZIP_ST
28 
29 
30 typedef struct
31 {
32   ICompressProgress vt;
33   CMtProgress *mtProgress;
34   UInt64 inSize;
35   UInt64 outSize;
36 } CMtProgressThunk;
37 
38 void MtProgressThunk_CreateVTable(CMtProgressThunk *p);
39 
40 #define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; }
41 
42 
43 struct _CMtCoder;
44 
45 
46 typedef struct
47 {
48   struct _CMtCoder *mtCoder;
49   unsigned index;
50   int stop;
51   Byte *inBuf;
52 
53   CAutoResetEvent startEvent;
54   CThread thread;
55 } CMtCoderThread;
56 
57 
58 typedef struct
59 {
60   SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex,
61       const Byte *src, size_t srcSize, int finished);
62   SRes (*Write)(void *p, unsigned outBufIndex);
63 } IMtCoderCallback2;
64 
65 
66 typedef struct
67 {
68   SRes res;
69   unsigned bufIndex;
70   Bool finished;
71 } CMtCoderBlock;
72 
73 
74 typedef struct _CMtCoder
75 {
76   /* input variables */
77 
78   size_t blockSize;        /* size of input block */
79   unsigned numThreadsMax;
80   UInt64 expectedDataSize;
81 
82   ISeqInStream *inStream;
83   const Byte *inData;
84   size_t inDataSize;
85 
86   ICompressProgress *progress;
87   ISzAllocPtr allocBig;
88 
89   IMtCoderCallback2 *mtCallback;
90   void *mtCallbackObject;
91 
92 
93   /* internal variables */
94 
95   size_t allocatedBufsSize;
96 
97   CAutoResetEvent readEvent;
98   CSemaphore blocksSemaphore;
99 
100   Bool stopReading;
101   SRes readRes;
102 
103   #ifdef MTCODER__USE_WRITE_THREAD
104     CAutoResetEvent writeEvents[MTCODER__BLOCKS_MAX];
105   #else
106     CAutoResetEvent finishedEvent;
107     SRes writeRes;
108     unsigned writeIndex;
109     Byte ReadyBlocks[MTCODER__BLOCKS_MAX];
110     LONG numFinishedThreads;
111   #endif
112 
113   unsigned numStartedThreadsLimit;
114   unsigned numStartedThreads;
115 
116   unsigned numBlocksMax;
117   unsigned blockIndex;
118   UInt64 readProcessed;
119 
120   CCriticalSection cs;
121 
122   unsigned freeBlockHead;
123   unsigned freeBlockList[MTCODER__BLOCKS_MAX];
124 
125   CMtProgress mtProgress;
126   CMtCoderBlock blocks[MTCODER__BLOCKS_MAX];
127   CMtCoderThread threads[MTCODER__THREADS_MAX];
128 } CMtCoder;
129 
130 
131 void MtCoder_Construct(CMtCoder *p);
132 void MtCoder_Destruct(CMtCoder *p);
133 SRes MtCoder_Code(CMtCoder *p);
134 
135 
136 #endif
137 
138 
139 EXTERN_C_END
140 
141 #endif
142