Commit 04c561d6a965b35df35d860c262ce0e8e4819b27
1 parent
7a47d58c
Revert previous changes to thread pooling in br.cpp/meta.cpp
Since we no longer put Stream threads on the global thread pool, the previous changes are unnecessary. Also, in distribute, set up the QFutureSyncrhonizer with futures in the opposite order. In Qt 5.1, the waiting thread will wait for each future in the order they are added to the synchronizer, and thread execution will proceed in the same order. This prevents the waiting thread from every doing anything besides waiting. Reversing the QFuture order (so that it is the opposite of execution order) allows the waiting thread to steal work as intended
Showing
2 changed files
with
14 additions
and
29 deletions
app/br/br.cpp
| ... | ... | @@ -235,10 +235,8 @@ int main(int argc, char *argv[]) |
| 235 | 235 | { |
| 236 | 236 | br_initialize(argc, argv); |
| 237 | 237 | |
| 238 | - QThreadPool separate; | |
| 239 | - separate.setMaxThreadCount(1); | |
| 240 | 238 | FakeMain *fakeMain = new FakeMain(argc, argv); |
| 241 | - separate.start(fakeMain); | |
| 239 | + QThreadPool::globalInstance()->start(fakeMain); | |
| 242 | 240 | QCoreApplication::exec(); |
| 243 | 241 | |
| 244 | 242 | br_finalize(); | ... | ... |
openbr/plugins/meta.cpp
| ... | ... | @@ -597,26 +597,6 @@ static void _projectList(const Transform *transform, const TemplateList *src, Te |
| 597 | 597 | transform->project(*src, *dst); |
| 598 | 598 | } |
| 599 | 599 | |
| 600 | -class ProjectListJob : public QRunnable | |
| 601 | -{ | |
| 602 | -public: | |
| 603 | - ProjectListJob(Transform * _transform, const TemplateList * _src, TemplateList * _dst) | |
| 604 | - { | |
| 605 | - transform = _transform; | |
| 606 | - src = _src; | |
| 607 | - dst = _dst; | |
| 608 | - this->setAutoDelete(true); | |
| 609 | - } | |
| 610 | - | |
| 611 | - Transform * transform; | |
| 612 | - const TemplateList * src; | |
| 613 | - TemplateList * dst; | |
| 614 | - void run() | |
| 615 | - { | |
| 616 | - _projectList(transform, src, dst); | |
| 617 | - } | |
| 618 | -}; | |
| 619 | - | |
| 620 | 600 | class DistributeTemplateTransform : public MetaTransform |
| 621 | 601 | { |
| 622 | 602 | Q_OBJECT |
| ... | ... | @@ -665,22 +645,29 @@ public: |
| 665 | 645 | QList<TemplateList> input_buffer; |
| 666 | 646 | input_buffer.reserve(src.size()); |
| 667 | 647 | |
| 648 | + QFutureSynchronizer<void> futures; | |
| 649 | + | |
| 668 | 650 | for (int i =0; i < src.size();i++) { |
| 669 | 651 | input_buffer.append(TemplateList()); |
| 670 | 652 | output_buffer.append(TemplateList()); |
| 671 | 653 | } |
| 672 | - | |
| 654 | + QList<QFuture<void> > temp; | |
| 655 | + temp.reserve(src.size()); | |
| 673 | 656 | for (int i=0; i<src.size(); i++) { |
| 674 | 657 | input_buffer[i].append(src[i]); |
| 675 | 658 | |
| 676 | - if (Globals->parallelism) | |
| 677 | - QThreadPool::globalInstance()->start(new ProjectListJob(transform, &input_buffer[i], &output_buffer[i]), 0); | |
| 659 | + if (Globals->parallelism > 1) temp.append(QtConcurrent::run(_projectList, transform, &input_buffer[i], &output_buffer[i])); | |
| 678 | 660 | else _projectList(transform, &input_buffer[i], &output_buffer[i]); |
| 679 | 661 | } |
| 662 | + // We add the futures in reverse order, since in Qt 5.1 at least the | |
| 663 | + // waiting thread will wait on them in the order added (which for uniform priority | |
| 664 | + // threads is the order of execution), and we want the waiting thread to go in the opposite order | |
| 665 | + // so that it can steal runnables and do something besides wait. | |
| 666 | + for (int i = temp.size() - 1; i > 0; i--) { | |
| 667 | + futures.addFuture(temp[i]); | |
| 668 | + } | |
| 680 | 669 | |
| 681 | - bool wait_res = QThreadPool::globalInstance()->waitForDone(); | |
| 682 | - if (!wait_res) | |
| 683 | - qDebug("global thread pool wait failed!"); | |
| 670 | + futures.waitForFinished(); | |
| 684 | 671 | |
| 685 | 672 | for (int i=0; i<src.size(); i++) dst.append(output_buffer[i]); |
| 686 | 673 | } | ... | ... |