Home | History | Annotate | Download | only in C
      1 /* MtCoder.h -- Multi-thread Coder
      2 2018-07-04 : 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   BoolInt 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   BoolInt 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