Skip to content

Commit

Permalink
Reintroduce Threadpools (#737)
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiolo authored Oct 31, 2024
1 parent 2c0d51f commit 6adfe39
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 7 deletions.
15 changes: 11 additions & 4 deletions src/myframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -1149,10 +1149,17 @@ struct MyFrame : wxFrame {
{ // block all other events until we finished preparing
wxEventBlocker blocker(this);
wxBusyCursor wait;
for (const auto &uimg : sys->imagelist) {
uimg->bm_display = wxNullBitmap;
uimg->Display();
}
{
ThreadPool pool(std::thread::hardware_concurrency());
for (const auto &image : sys->imagelist) {
pool.enqueue(
[](auto *img) {
img->bm_display = wxNullBitmap;
img->Display();
},
image.get());
}
} // wait until all tasks are finished
RenderFolderIcon();
if (nb) {
loop(i, nb->GetPageCount()) {
Expand Down
8 changes: 8 additions & 0 deletions src/stdafx.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,26 @@
#include <algorithm>
#include <array>
#include <clocale>
#include <condition_variable>
#include <filesystem>
#include <functional>
#include <future>
#include <locale>
#include <map>
#include <memory>
#include <mutex>
#include <new>
#include <queue>
#include <set>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <thread>
#include <utility>
#include <vector>

#include "threadpool.h"
#include "tools.h"

#ifdef _WIN32
Expand Down
13 changes: 10 additions & 3 deletions src/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,16 @@ struct System {
done:

doc->RefreshImageRefCount(false);
for (const auto &uimg : sys->imagelist) {
if (uimg->trefc) uimg->Display();
}
{
ThreadPool pool(std::thread::hardware_concurrency());
for (auto &image : sys->imagelist) {
pool.enqueue(
[](auto *img) {
if (img->trefc) img->Display();
},
image.get());
}
} // wait until all tasks are finished

FileUsed(filename, doc);
doc->Refresh();
Expand Down
72 changes: 72 additions & 0 deletions src/threadpool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
class ThreadPool {
public:
ThreadPool(size_t);
template<class F, class... Args>
auto enqueue(F&& f, Args&&... args)
-> std::future<typename std::invoke_result<F, Args...>::type>;
~ThreadPool();

private:
// need to keep track of threads so we can join them
std::vector<std::thread> workers;
// the task queue
std::queue<std::function<void()>> tasks;

// synchronization
std::mutex queue_mutex;
std::condition_variable condition;
bool stop;
};

// the constructor just launches some amount of workers
inline ThreadPool::ThreadPool(size_t threads) : stop(false) {
for (size_t i = 0; i < threads; ++i)
workers.emplace_back([this] {
for (;;) {
std::function<void()> task;

{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.wait(lock,
[this] { return this->stop || !this->tasks.empty(); });
if (this->stop && this->tasks.empty()) return;
task = std::move(this->tasks.front());
this->tasks.pop();
}

task();
}
});
}

// add new work item to the pool
template<class F, class... Args>
auto ThreadPool::enqueue(F&& f, Args&&... args)
-> std::future<typename std::invoke_result<F, Args...>::type> {
using return_type = typename std::invoke_result<F, Args...>::type;

auto task = std::make_shared<std::packaged_task<return_type()>>(
std::bind(std::forward<F>(f), std::forward<Args>(args)...));

std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);

// don't allow enqueueing after stopping the pool
assert(!stop);

tasks.emplace([task]() { (*task)(); });
}
condition.notify_one();
return res;
}

// the destructor joins all threads
inline ThreadPool::~ThreadPool() {
{
std::unique_lock<std::mutex> lock(queue_mutex);
stop = true;
}
condition.notify_all();
for (std::thread& worker : workers) worker.join();
}

0 comments on commit 6adfe39

Please sign in to comment.