aboutsummaryrefslogtreecommitdiff
path: root/C/MtDec.c
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2023-06-21 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2023-12-17 14:59:19 +0500
commit5b39dc76f1bc82f941d5c800ab9f34407a06b53a (patch)
treefe5e17420300b715021a76328444088d32047963 /C/MtDec.c
parent93be7d4abfd4233228f58ee1fbbcd76d91be66a4 (diff)
download7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.gz
7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.bz2
7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.zip
23.0123.01
Diffstat (limited to 'C/MtDec.c')
-rw-r--r--C/MtDec.c101
1 files changed, 38 insertions, 63 deletions
diff --git a/C/MtDec.c b/C/MtDec.c
index 45a6713..7820699 100644
--- a/C/MtDec.c
+++ b/C/MtDec.c
@@ -1,5 +1,5 @@
1/* MtDec.c -- Multi-thread Decoder 1/* MtDec.c -- Multi-thread Decoder
22021-12-21 : Igor Pavlov : Public domain */ 22023-04-02 : Igor Pavlov : Public domain */
3 3
4#include "Precomp.h" 4#include "Precomp.h"
5 5
@@ -14,7 +14,7 @@
14 14
15#include "MtDec.h" 15#include "MtDec.h"
16 16
17#ifndef _7ZIP_ST 17#ifndef Z7_ST
18 18
19#ifdef SHOW_DEBUG_INFO 19#ifdef SHOW_DEBUG_INFO
20#define PRF(x) x 20#define PRF(x) x
@@ -24,7 +24,7 @@
24 24
25#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) 25#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d))
26 26
27void MtProgress_Init(CMtProgress *p, ICompressProgress *progress) 27void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress)
28{ 28{
29 p->progress = progress; 29 p->progress = progress;
30 p->res = SZ_OK; 30 p->res = SZ_OK;
@@ -81,36 +81,28 @@ void MtProgress_SetError(CMtProgress *p, SRes res)
81#define RINOK_THREAD(x) RINOK_WRes(x) 81#define RINOK_THREAD(x) RINOK_WRes(x)
82 82
83 83
84static WRes ArEvent_OptCreate_And_Reset(CEvent *p) 84struct CMtDecBufLink_
85{ 85{
86 if (Event_IsCreated(p)) 86 struct CMtDecBufLink_ *next;
87 return Event_Reset(p);
88 return AutoResetEvent_CreateNotSignaled(p);
89}
90
91
92struct __CMtDecBufLink
93{
94 struct __CMtDecBufLink *next;
95 void *pad[3]; 87 void *pad[3];
96}; 88};
97 89
98typedef struct __CMtDecBufLink CMtDecBufLink; 90typedef struct CMtDecBufLink_ CMtDecBufLink;
99 91
100#define MTDEC__LINK_DATA_OFFSET sizeof(CMtDecBufLink) 92#define MTDEC__LINK_DATA_OFFSET sizeof(CMtDecBufLink)
101#define MTDEC__DATA_PTR_FROM_LINK(link) ((Byte *)(link) + MTDEC__LINK_DATA_OFFSET) 93#define MTDEC__DATA_PTR_FROM_LINK(link) ((Byte *)(link) + MTDEC__LINK_DATA_OFFSET)
102 94
103 95
104 96
105static THREAD_FUNC_DECL ThreadFunc(void *pp); 97static THREAD_FUNC_DECL MtDec_ThreadFunc(void *pp);
106 98
107 99
108static WRes MtDecThread_CreateEvents(CMtDecThread *t) 100static WRes MtDecThread_CreateEvents(CMtDecThread *t)
109{ 101{
110 WRes wres = ArEvent_OptCreate_And_Reset(&t->canWrite); 102 WRes wres = AutoResetEvent_OptCreate_And_Reset(&t->canWrite);
111 if (wres == 0) 103 if (wres == 0)
112 { 104 {
113 wres = ArEvent_OptCreate_And_Reset(&t->canRead); 105 wres = AutoResetEvent_OptCreate_And_Reset(&t->canRead);
114 if (wres == 0) 106 if (wres == 0)
115 return SZ_OK; 107 return SZ_OK;
116 } 108 }
@@ -126,7 +118,7 @@ static SRes MtDecThread_CreateAndStart(CMtDecThread *t)
126 { 118 {
127 if (Thread_WasCreated(&t->thread)) 119 if (Thread_WasCreated(&t->thread))
128 return SZ_OK; 120 return SZ_OK;
129 wres = Thread_Create(&t->thread, ThreadFunc, t); 121 wres = Thread_Create(&t->thread, MtDec_ThreadFunc, t);
130 if (wres == 0) 122 if (wres == 0)
131 return SZ_OK; 123 return SZ_OK;
132 } 124 }
@@ -167,7 +159,7 @@ static void MtDecThread_CloseThread(CMtDecThread *t)
167static void MtDec_CloseThreads(CMtDec *p) 159static void MtDec_CloseThreads(CMtDec *p)
168{ 160{
169 unsigned i; 161 unsigned i;
170 for (i = 0; i < MTDEC__THREADS_MAX; i++) 162 for (i = 0; i < MTDEC_THREADS_MAX; i++)
171 MtDecThread_CloseThread(&p->threads[i]); 163 MtDecThread_CloseThread(&p->threads[i]);
172} 164}
173 165
@@ -179,25 +171,6 @@ static void MtDecThread_Destruct(CMtDecThread *t)
179 171
180 172
181 173
182static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize)
183{
184 size_t size = *processedSize;
185 *processedSize = 0;
186 while (size != 0)
187 {
188 size_t cur = size;
189 SRes res = ISeqInStream_Read(stream, data, &cur);
190 *processedSize += cur;
191 data += cur;
192 size -= cur;
193 RINOK(res);
194 if (cur == 0)
195 return SZ_OK;
196 }
197 return SZ_OK;
198}
199
200
201static SRes MtDec_GetError_Spec(CMtDec *p, UInt64 interruptIndex, BoolInt *wasInterrupted) 174static SRes MtDec_GetError_Spec(CMtDec *p, UInt64 interruptIndex, BoolInt *wasInterrupted)
202{ 175{
203 SRes res; 176 SRes res;
@@ -253,7 +226,7 @@ Byte *MtDec_GetCrossBuff(CMtDec *p)
253 226
254 227
255/* 228/*
256 ThreadFunc2() returns: 229 MtDec_ThreadFunc2() returns:
257 0 - in all normal cases (even for stream error or memory allocation error) 230 0 - in all normal cases (even for stream error or memory allocation error)
258 (!= 0) - WRes error return by system threading function 231 (!= 0) - WRes error return by system threading function
259*/ 232*/
@@ -261,11 +234,11 @@ Byte *MtDec_GetCrossBuff(CMtDec *p)
261// #define MTDEC_ProgessStep (1 << 22) 234// #define MTDEC_ProgessStep (1 << 22)
262#define MTDEC_ProgessStep (1 << 0) 235#define MTDEC_ProgessStep (1 << 0)
263 236
264static WRes ThreadFunc2(CMtDecThread *t) 237static WRes MtDec_ThreadFunc2(CMtDecThread *t)
265{ 238{
266 CMtDec *p = t->mtDec; 239 CMtDec *p = t->mtDec;
267 240
268 PRF_STR_INT("ThreadFunc2", t->index); 241 PRF_STR_INT("MtDec_ThreadFunc2", t->index)
269 242
270 // SetThreadAffinityMask(GetCurrentThread(), 1 << t->index); 243 // SetThreadAffinityMask(GetCurrentThread(), 1 << t->index);
271 244
@@ -295,13 +268,13 @@ static WRes ThreadFunc2(CMtDecThread *t)
295 // CMtDecCallbackInfo parse; 268 // CMtDecCallbackInfo parse;
296 CMtDecThread *nextThread; 269 CMtDecThread *nextThread;
297 270
298 PRF_STR_INT("=============== Event_Wait(&t->canRead)", t->index); 271 PRF_STR_INT("=============== Event_Wait(&t->canRead)", t->index)
299 272
300 RINOK_THREAD(Event_Wait(&t->canRead)); 273 RINOK_THREAD(Event_Wait(&t->canRead))
301 if (p->exitThread) 274 if (p->exitThread)
302 return 0; 275 return 0;
303 276
304 PRF_STR_INT("after Event_Wait(&t->canRead)", t->index); 277 PRF_STR_INT("after Event_Wait(&t->canRead)", t->index)
305 278
306 // if (t->index == 3) return 19; // for test 279 // if (t->index == 3) return 19; // for test
307 280
@@ -373,7 +346,7 @@ static WRes ThreadFunc2(CMtDecThread *t)
373 { 346 {
374 size = p->inBufSize; 347 size = p->inBufSize;
375 348
376 res = FullRead(p->inStream, data, &size); 349 res = SeqInStream_ReadMax(p->inStream, data, &size);
377 350
378 // size = 10; // test 351 // size = 10; // test
379 352
@@ -615,7 +588,7 @@ static WRes ThreadFunc2(CMtDecThread *t)
615 // if ( !finish ) we must call Event_Set(&nextThread->canWrite) in any case 588 // if ( !finish ) we must call Event_Set(&nextThread->canWrite) in any case
616 // if ( finish ) we switch to single-thread mode and there are 2 ways at the end of current iteration (current block): 589 // if ( finish ) we switch to single-thread mode and there are 2 ways at the end of current iteration (current block):
617 // - if (needContinue) after Write(&needContinue), we restore decoding with new iteration 590 // - if (needContinue) after Write(&needContinue), we restore decoding with new iteration
618 // - otherwise we stop decoding and exit from ThreadFunc2() 591 // - otherwise we stop decoding and exit from MtDec_ThreadFunc2()
619 592
620 // Don't change (finish) variable in the further code 593 // Don't change (finish) variable in the further code
621 594
@@ -688,7 +661,7 @@ static WRes ThreadFunc2(CMtDecThread *t)
688 661
689 // ---------- WRITE ---------- 662 // ---------- WRITE ----------
690 663
691 RINOK_THREAD(Event_Wait(&t->canWrite)); 664 RINOK_THREAD(Event_Wait(&t->canWrite))
692 665
693 { 666 {
694 BoolInt isErrorMode = False; 667 BoolInt isErrorMode = False;
@@ -801,14 +774,14 @@ static WRes ThreadFunc2(CMtDecThread *t)
801 774
802 if (!finish) 775 if (!finish)
803 { 776 {
804 RINOK_THREAD(Event_Set(&nextThread->canWrite)); 777 RINOK_THREAD(Event_Set(&nextThread->canWrite))
805 } 778 }
806 else 779 else
807 { 780 {
808 if (needContinue) 781 if (needContinue)
809 { 782 {
810 // we restore decoding with new iteration 783 // we restore decoding with new iteration
811 RINOK_THREAD(Event_Set(&p->threads[0].canWrite)); 784 RINOK_THREAD(Event_Set(&p->threads[0].canWrite))
812 } 785 }
813 else 786 else
814 { 787 {
@@ -817,7 +790,7 @@ static WRes ThreadFunc2(CMtDecThread *t)
817 return SZ_OK; 790 return SZ_OK;
818 p->exitThread = True; 791 p->exitThread = True;
819 } 792 }
820 RINOK_THREAD(Event_Set(&p->threads[0].canRead)); 793 RINOK_THREAD(Event_Set(&p->threads[0].canRead))
821 } 794 }
822 } 795 }
823 } 796 }
@@ -836,7 +809,7 @@ static WRes ThreadFunc2(CMtDecThread *t)
836#endif 809#endif
837 810
838 811
839static THREAD_FUNC_DECL ThreadFunc1(void *pp) 812static THREAD_FUNC_DECL MtDec_ThreadFunc1(void *pp)
840{ 813{
841 WRes res; 814 WRes res;
842 815
@@ -845,7 +818,7 @@ static THREAD_FUNC_DECL ThreadFunc1(void *pp)
845 818
846 // fprintf(stdout, "\n%d = %p\n", t->index, &t); 819 // fprintf(stdout, "\n%d = %p\n", t->index, &t);
847 820
848 res = ThreadFunc2(t); 821 res = MtDec_ThreadFunc2(t);
849 p = t->mtDec; 822 p = t->mtDec;
850 if (res == 0) 823 if (res == 0)
851 return (THREAD_FUNC_RET_TYPE)(UINT_PTR)p->exitThreadWRes; 824 return (THREAD_FUNC_RET_TYPE)(UINT_PTR)p->exitThreadWRes;
@@ -862,14 +835,14 @@ static THREAD_FUNC_DECL ThreadFunc1(void *pp)
862 return (THREAD_FUNC_RET_TYPE)(UINT_PTR)res; 835 return (THREAD_FUNC_RET_TYPE)(UINT_PTR)res;
863} 836}
864 837
865static MY_NO_INLINE THREAD_FUNC_DECL ThreadFunc(void *pp) 838static Z7_NO_INLINE THREAD_FUNC_DECL MtDec_ThreadFunc(void *pp)
866{ 839{
867 #ifdef USE_ALLOCA 840 #ifdef USE_ALLOCA
868 CMtDecThread *t = (CMtDecThread *)pp; 841 CMtDecThread *t = (CMtDecThread *)pp;
869 // fprintf(stderr, "\n%d = %p - before", t->index, &t); 842 // fprintf(stderr, "\n%d = %p - before", t->index, &t);
870 t->allocaPtr = alloca(t->index * 128); 843 t->allocaPtr = alloca(t->index * 128);
871 #endif 844 #endif
872 return ThreadFunc1(pp); 845 return MtDec_ThreadFunc1(pp);
873} 846}
874 847
875 848
@@ -883,7 +856,7 @@ int MtDec_PrepareRead(CMtDec *p)
883 856
884 { 857 {
885 unsigned i; 858 unsigned i;
886 for (i = 0; i < MTDEC__THREADS_MAX; i++) 859 for (i = 0; i < MTDEC_THREADS_MAX; i++)
887 if (i > p->numStartedThreads 860 if (i > p->numStartedThreads
888 || p->numFilledThreads <= 861 || p->numFilledThreads <=
889 (i >= p->filledThreadStart ? 862 (i >= p->filledThreadStart ?
@@ -987,7 +960,7 @@ void MtDec_Construct(CMtDec *p)
987 960
988 p->allocatedBufsSize = 0; 961 p->allocatedBufsSize = 0;
989 962
990 for (i = 0; i < MTDEC__THREADS_MAX; i++) 963 for (i = 0; i < MTDEC_THREADS_MAX; i++)
991 { 964 {
992 CMtDecThread *t = &p->threads[i]; 965 CMtDecThread *t = &p->threads[i];
993 t->mtDec = p; 966 t->mtDec = p;
@@ -995,7 +968,7 @@ void MtDec_Construct(CMtDec *p)
995 t->inBuf = NULL; 968 t->inBuf = NULL;
996 Event_Construct(&t->canRead); 969 Event_Construct(&t->canRead);
997 Event_Construct(&t->canWrite); 970 Event_Construct(&t->canWrite);
998 Thread_Construct(&t->thread); 971 Thread_CONSTRUCT(&t->thread)
999 } 972 }
1000 973
1001 // Event_Construct(&p->finishedEvent); 974 // Event_Construct(&p->finishedEvent);
@@ -1010,7 +983,7 @@ static void MtDec_Free(CMtDec *p)
1010 983
1011 p->exitThread = True; 984 p->exitThread = True;
1012 985
1013 for (i = 0; i < MTDEC__THREADS_MAX; i++) 986 for (i = 0; i < MTDEC_THREADS_MAX; i++)
1014 MtDecThread_Destruct(&p->threads[i]); 987 MtDecThread_Destruct(&p->threads[i]);
1015 988
1016 // Event_Close(&p->finishedEvent); 989 // Event_Close(&p->finishedEvent);
@@ -1061,15 +1034,15 @@ SRes MtDec_Code(CMtDec *p)
1061 1034
1062 { 1035 {
1063 unsigned numThreads = p->numThreadsMax; 1036 unsigned numThreads = p->numThreadsMax;
1064 if (numThreads > MTDEC__THREADS_MAX) 1037 if (numThreads > MTDEC_THREADS_MAX)
1065 numThreads = MTDEC__THREADS_MAX; 1038 numThreads = MTDEC_THREADS_MAX;
1066 p->numStartedThreads_Limit = numThreads; 1039 p->numStartedThreads_Limit = numThreads;
1067 p->numStartedThreads = 0; 1040 p->numStartedThreads = 0;
1068 } 1041 }
1069 1042
1070 if (p->inBufSize != p->allocatedBufsSize) 1043 if (p->inBufSize != p->allocatedBufsSize)
1071 { 1044 {
1072 for (i = 0; i < MTDEC__THREADS_MAX; i++) 1045 for (i = 0; i < MTDEC_THREADS_MAX; i++)
1073 { 1046 {
1074 CMtDecThread *t = &p->threads[i]; 1047 CMtDecThread *t = &p->threads[i];
1075 if (t->inBuf) 1048 if (t->inBuf)
@@ -1086,7 +1059,7 @@ SRes MtDec_Code(CMtDec *p)
1086 1059
1087 MtProgress_Init(&p->mtProgress, p->progress); 1060 MtProgress_Init(&p->mtProgress, p->progress);
1088 1061
1089 // RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->finishedEvent)); 1062 // RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->finishedEvent))
1090 p->exitThread = False; 1063 p->exitThread = False;
1091 p->exitThreadWRes = 0; 1064 p->exitThreadWRes = 0;
1092 1065
@@ -1098,7 +1071,7 @@ SRes MtDec_Code(CMtDec *p)
1098 wres = MtDecThread_CreateEvents(nextThread); 1071 wres = MtDecThread_CreateEvents(nextThread);
1099 if (wres == 0) { wres = Event_Set(&nextThread->canWrite); 1072 if (wres == 0) { wres = Event_Set(&nextThread->canWrite);
1100 if (wres == 0) { wres = Event_Set(&nextThread->canRead); 1073 if (wres == 0) { wres = Event_Set(&nextThread->canRead);
1101 if (wres == 0) { THREAD_FUNC_RET_TYPE res = ThreadFunc(nextThread); 1074 if (wres == 0) { THREAD_FUNC_RET_TYPE res = MtDec_ThreadFunc(nextThread);
1102 wres = (WRes)(UINT_PTR)res; 1075 wres = (WRes)(UINT_PTR)res;
1103 if (wres != 0) 1076 if (wres != 0)
1104 { 1077 {
@@ -1137,3 +1110,5 @@ SRes MtDec_Code(CMtDec *p)
1137} 1110}
1138 1111
1139#endif 1112#endif
1113
1114#undef PRF