diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-06-21 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-12-17 14:59:19 +0500 |
commit | 5b39dc76f1bc82f941d5c800ab9f34407a06b53a (patch) | |
tree | fe5e17420300b715021a76328444088d32047963 /C/MtDec.c | |
parent | 93be7d4abfd4233228f58ee1fbbcd76d91be66a4 (diff) | |
download | 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.gz 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.bz2 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.zip |
23.0123.01
Diffstat (limited to 'C/MtDec.c')
-rw-r--r-- | C/MtDec.c | 101 |
1 files changed, 38 insertions, 63 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* MtDec.c -- Multi-thread Decoder | 1 | /* MtDec.c -- Multi-thread Decoder |
2 | 2021-12-21 : Igor Pavlov : Public domain */ | 2 | 2023-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 | ||
27 | void MtProgress_Init(CMtProgress *p, ICompressProgress *progress) | 27 | void 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 | ||
84 | static WRes ArEvent_OptCreate_And_Reset(CEvent *p) | 84 | struct 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 | |||
92 | struct __CMtDecBufLink | ||
93 | { | ||
94 | struct __CMtDecBufLink *next; | ||
95 | void *pad[3]; | 87 | void *pad[3]; |
96 | }; | 88 | }; |
97 | 89 | ||
98 | typedef struct __CMtDecBufLink CMtDecBufLink; | 90 | typedef 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 | ||
105 | static THREAD_FUNC_DECL ThreadFunc(void *pp); | 97 | static THREAD_FUNC_DECL MtDec_ThreadFunc(void *pp); |
106 | 98 | ||
107 | 99 | ||
108 | static WRes MtDecThread_CreateEvents(CMtDecThread *t) | 100 | static 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) | |||
167 | static void MtDec_CloseThreads(CMtDec *p) | 159 | static 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 | ||
182 | static 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 | |||
201 | static SRes MtDec_GetError_Spec(CMtDec *p, UInt64 interruptIndex, BoolInt *wasInterrupted) | 174 | static 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 | ||
264 | static WRes ThreadFunc2(CMtDecThread *t) | 237 | static 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 | ||
839 | static THREAD_FUNC_DECL ThreadFunc1(void *pp) | 812 | static 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 | ||
865 | static MY_NO_INLINE THREAD_FUNC_DECL ThreadFunc(void *pp) | 838 | static 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 | ||