diff options
Diffstat (limited to 'C/MtCoder.c')
| -rw-r--r-- | C/MtCoder.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/C/MtCoder.c b/C/MtCoder.c index 03959b6..923b19a 100644 --- a/C/MtCoder.c +++ b/C/MtCoder.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* MtCoder.c -- Multi-thread Coder | 1 | /* MtCoder.c -- Multi-thread Coder |
| 2 | 2023-09-07 : Igor Pavlov : Public domain */ | 2 | : Igor Pavlov : Public domain */ |
| 3 | 3 | ||
| 4 | #include "Precomp.h" | 4 | #include "Precomp.h" |
| 5 | 5 | ||
| @@ -39,14 +39,28 @@ void MtProgressThunk_CreateVTable(CMtProgressThunk *p) | |||
| 39 | static THREAD_FUNC_DECL ThreadFunc(void *pp); | 39 | static THREAD_FUNC_DECL ThreadFunc(void *pp); |
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t) | 42 | static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t |
| 43 | #ifdef _WIN32 | ||
| 44 | , CMtCoder * const mtc | ||
| 45 | #endif | ||
| 46 | ) | ||
| 43 | { | 47 | { |
| 44 | WRes wres = AutoResetEvent_OptCreate_And_Reset(&t->startEvent); | 48 | WRes wres = AutoResetEvent_OptCreate_And_Reset(&t->startEvent); |
| 49 | // printf("\n====== MtCoderThread_CreateAndStart : \n"); | ||
| 45 | if (wres == 0) | 50 | if (wres == 0) |
| 46 | { | 51 | { |
| 47 | t->stop = False; | 52 | t->stop = False; |
| 48 | if (!Thread_WasCreated(&t->thread)) | 53 | if (!Thread_WasCreated(&t->thread)) |
| 49 | wres = Thread_Create(&t->thread, ThreadFunc, t); | 54 | { |
| 55 | #ifdef _WIN32 | ||
| 56 | if (mtc->numThreadGroups) | ||
| 57 | wres = Thread_Create_With_Group(&t->thread, ThreadFunc, t, | ||
| 58 | ThreadNextGroup_GetNext(&mtc->nextGroup), // group | ||
| 59 | 0); // affinityMask | ||
| 60 | else | ||
| 61 | #endif | ||
| 62 | wres = Thread_Create(&t->thread, ThreadFunc, t); | ||
| 63 | } | ||
| 50 | if (wres == 0) | 64 | if (wres == 0) |
| 51 | wres = Event_Set(&t->startEvent); | 65 | wres = Event_Set(&t->startEvent); |
| 52 | } | 66 | } |
| @@ -56,6 +70,7 @@ static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t) | |||
| 56 | } | 70 | } |
| 57 | 71 | ||
| 58 | 72 | ||
| 73 | Z7_FORCE_INLINE | ||
| 59 | static void MtCoderThread_Destruct(CMtCoderThread *t) | 74 | static void MtCoderThread_Destruct(CMtCoderThread *t) |
| 60 | { | 75 | { |
| 61 | if (Thread_WasCreated(&t->thread)) | 76 | if (Thread_WasCreated(&t->thread)) |
| @@ -85,7 +100,7 @@ static void MtCoderThread_Destruct(CMtCoderThread *t) | |||
| 85 | 100 | ||
| 86 | static SRes ThreadFunc2(CMtCoderThread *t) | 101 | static SRes ThreadFunc2(CMtCoderThread *t) |
| 87 | { | 102 | { |
| 88 | CMtCoder *mtc = t->mtCoder; | 103 | CMtCoder * const mtc = t->mtCoder; |
| 89 | 104 | ||
| 90 | for (;;) | 105 | for (;;) |
| 91 | { | 106 | { |
| @@ -185,7 +200,11 @@ static SRes ThreadFunc2(CMtCoderThread *t) | |||
| 185 | if (mtc->numStartedThreads < mtc->numStartedThreadsLimit | 200 | if (mtc->numStartedThreads < mtc->numStartedThreadsLimit |
| 186 | && mtc->expectedDataSize != readProcessed) | 201 | && mtc->expectedDataSize != readProcessed) |
| 187 | { | 202 | { |
| 188 | res = MtCoderThread_CreateAndStart(&mtc->threads[mtc->numStartedThreads]); | 203 | res = MtCoderThread_CreateAndStart(&mtc->threads[mtc->numStartedThreads] |
| 204 | #ifdef _WIN32 | ||
| 205 | , mtc | ||
| 206 | #endif | ||
| 207 | ); | ||
| 189 | if (res == SZ_OK) | 208 | if (res == SZ_OK) |
| 190 | mtc->numStartedThreads++; | 209 | mtc->numStartedThreads++; |
| 191 | else | 210 | else |
| @@ -221,7 +240,7 @@ static SRes ThreadFunc2(CMtCoderThread *t) | |||
| 221 | } | 240 | } |
| 222 | 241 | ||
| 223 | { | 242 | { |
| 224 | CMtCoderBlock *block = &mtc->blocks[bi]; | 243 | CMtCoderBlock * const block = &mtc->blocks[bi]; |
| 225 | block->res = res; | 244 | block->res = res; |
| 226 | block->bufIndex = bufIndex; | 245 | block->bufIndex = bufIndex; |
| 227 | block->finished = finished; | 246 | block->finished = finished; |
| @@ -311,7 +330,7 @@ static SRes ThreadFunc2(CMtCoderThread *t) | |||
| 311 | 330 | ||
| 312 | static THREAD_FUNC_DECL ThreadFunc(void *pp) | 331 | static THREAD_FUNC_DECL ThreadFunc(void *pp) |
| 313 | { | 332 | { |
| 314 | CMtCoderThread *t = (CMtCoderThread *)pp; | 333 | CMtCoderThread * const t = (CMtCoderThread *)pp; |
| 315 | for (;;) | 334 | for (;;) |
| 316 | { | 335 | { |
| 317 | if (Event_Wait(&t->startEvent) != 0) | 336 | if (Event_Wait(&t->startEvent) != 0) |
| @@ -319,7 +338,7 @@ static THREAD_FUNC_DECL ThreadFunc(void *pp) | |||
| 319 | if (t->stop) | 338 | if (t->stop) |
| 320 | return 0; | 339 | return 0; |
| 321 | { | 340 | { |
| 322 | SRes res = ThreadFunc2(t); | 341 | const SRes res = ThreadFunc2(t); |
| 323 | CMtCoder *mtc = t->mtCoder; | 342 | CMtCoder *mtc = t->mtCoder; |
| 324 | if (res != SZ_OK) | 343 | if (res != SZ_OK) |
| 325 | { | 344 | { |
| @@ -328,7 +347,7 @@ static THREAD_FUNC_DECL ThreadFunc(void *pp) | |||
| 328 | 347 | ||
| 329 | #ifndef MTCODER_USE_WRITE_THREAD | 348 | #ifndef MTCODER_USE_WRITE_THREAD |
| 330 | { | 349 | { |
| 331 | unsigned numFinished = (unsigned)InterlockedIncrement(&mtc->numFinishedThreads); | 350 | const unsigned numFinished = (unsigned)InterlockedIncrement(&mtc->numFinishedThreads); |
| 332 | if (numFinished == mtc->numStartedThreads) | 351 | if (numFinished == mtc->numStartedThreads) |
| 333 | if (Event_Set(&mtc->finishedEvent) != 0) | 352 | if (Event_Set(&mtc->finishedEvent) != 0) |
| 334 | return (THREAD_FUNC_RET_TYPE)SZ_ERROR_THREAD; | 353 | return (THREAD_FUNC_RET_TYPE)SZ_ERROR_THREAD; |
| @@ -346,6 +365,7 @@ void MtCoder_Construct(CMtCoder *p) | |||
| 346 | 365 | ||
| 347 | p->blockSize = 0; | 366 | p->blockSize = 0; |
| 348 | p->numThreadsMax = 0; | 367 | p->numThreadsMax = 0; |
| 368 | p->numThreadGroups = 0; | ||
| 349 | p->expectedDataSize = (UInt64)(Int64)-1; | 369 | p->expectedDataSize = (UInt64)(Int64)-1; |
| 350 | 370 | ||
| 351 | p->inStream = NULL; | 371 | p->inStream = NULL; |
| @@ -429,6 +449,8 @@ SRes MtCoder_Code(CMtCoder *p) | |||
| 429 | unsigned i; | 449 | unsigned i; |
| 430 | SRes res = SZ_OK; | 450 | SRes res = SZ_OK; |
| 431 | 451 | ||
| 452 | // printf("\n====== MtCoder_Code : \n"); | ||
| 453 | |||
| 432 | if (numThreads > MTCODER_THREADS_MAX) | 454 | if (numThreads > MTCODER_THREADS_MAX) |
| 433 | numThreads = MTCODER_THREADS_MAX; | 455 | numThreads = MTCODER_THREADS_MAX; |
| 434 | numBlocksMax = MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads); | 456 | numBlocksMax = MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads); |
| @@ -492,11 +514,22 @@ SRes MtCoder_Code(CMtCoder *p) | |||
| 492 | 514 | ||
| 493 | p->numStartedThreadsLimit = numThreads; | 515 | p->numStartedThreadsLimit = numThreads; |
| 494 | p->numStartedThreads = 0; | 516 | p->numStartedThreads = 0; |
| 517 | ThreadNextGroup_Init(&p->nextGroup, p->numThreadGroups, 0); // startGroup | ||
| 495 | 518 | ||
| 496 | // for (i = 0; i < numThreads; i++) | 519 | // for (i = 0; i < numThreads; i++) |
| 497 | { | 520 | { |
| 521 | // here we create new thread for first block. | ||
| 522 | // And each new thread will create another new thread after block reading | ||
| 523 | // until numStartedThreadsLimit is reached. | ||
| 498 | CMtCoderThread *nextThread = &p->threads[p->numStartedThreads++]; | 524 | CMtCoderThread *nextThread = &p->threads[p->numStartedThreads++]; |
| 499 | RINOK(MtCoderThread_CreateAndStart(nextThread)) | 525 | { |
| 526 | const SRes res2 = MtCoderThread_CreateAndStart(nextThread | ||
| 527 | #ifdef _WIN32 | ||
| 528 | , p | ||
| 529 | #endif | ||
| 530 | ); | ||
| 531 | RINOK(res2) | ||
| 532 | } | ||
| 500 | } | 533 | } |
| 501 | 534 | ||
| 502 | RINOK_THREAD(Event_Set(&p->readEvent)) | 535 | RINOK_THREAD(Event_Set(&p->readEvent)) |
| @@ -513,9 +546,9 @@ SRes MtCoder_Code(CMtCoder *p) | |||
| 513 | RINOK_THREAD(Event_Wait(&p->writeEvents[bi])) | 546 | RINOK_THREAD(Event_Wait(&p->writeEvents[bi])) |
| 514 | 547 | ||
| 515 | { | 548 | { |
| 516 | const CMtCoderBlock *block = &p->blocks[bi]; | 549 | const CMtCoderBlock * const block = &p->blocks[bi]; |
| 517 | unsigned bufIndex = block->bufIndex; | 550 | const unsigned bufIndex = block->bufIndex; |
| 518 | BoolInt finished = block->finished; | 551 | const BoolInt finished = block->finished; |
| 519 | if (res == SZ_OK && block->res != SZ_OK) | 552 | if (res == SZ_OK && block->res != SZ_OK) |
| 520 | res = block->res; | 553 | res = block->res; |
| 521 | 554 | ||
| @@ -545,7 +578,7 @@ SRes MtCoder_Code(CMtCoder *p) | |||
| 545 | } | 578 | } |
| 546 | #else | 579 | #else |
| 547 | { | 580 | { |
| 548 | WRes wres = Event_Wait(&p->finishedEvent); | 581 | const WRes wres = Event_Wait(&p->finishedEvent); |
| 549 | res = MY_SRes_HRESULT_FROM_WRes(wres); | 582 | res = MY_SRes_HRESULT_FROM_WRes(wres); |
| 550 | } | 583 | } |
| 551 | #endif | 584 | #endif |
