Skip to content

Commit

Permalink
chore: parallelFor tidy
Browse files Browse the repository at this point in the history
  • Loading branch information
vinniefalco committed Jun 9, 2023
1 parent 46581c0 commit 028a460
Showing 1 changed file with 24 additions and 13 deletions.
37 changes: 24 additions & 13 deletions include/mrdox/Support/ParallelFor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,51 +19,62 @@
#include <thread>
#include <vector>

#include <algorithm>

namespace clang {
namespace mrdox {

/** Visit all elements of a range concurrently.
*/
template<
class Range,
class Worker,
class Elements,
class Workers,
class... Args>
Error
parallelFor(
Range&& range,
std::vector<Worker>& workers,
Elements& elements,
Workers& workers,
Args&&... args)
{
if(std::next(std::begin(workers)) == std::end(workers))
{
// Non-concurrent
auto&& worker(*std::begin(workers));
for(auto&& element : elements)
if(! worker(element, std::forward<Args>(args)...))
return Error("canceled");
return Error::success();
}

std::mutex m;
bool cancel = false;
auto it = std::begin(range);
auto const end = std::end(range);
auto it = std::begin(elements);
auto const end = std::end(elements);
auto const do_work =
[&](Worker& worker)
[&](auto&& agent)
{
std::unique_lock<std::mutex> lock(m);
if(it == end || cancel)
return false;
auto it0 = it;
++it;
lock.unlock();
bool cancel_ = worker(*it0,
bool cancel_ = ! agent(*it0,
std::forward<Args>(args)...);
if(! cancel_)
return true;
cancel = true;
return false;
};
std::vector<std::thread> threads;
threads.reserve(workers.size());
for(std::size_t i = 0; i < workers.size(); ++i)
for(auto& worker : workers)
threads.emplace_back(std::thread(
[&](std::size_t i_)
[&](auto&& agent)
{
for(;;)
if(! do_work(workers[i]))
if(! do_work(agent))
break;
}, i));
}, worker));
for(auto& t : threads)
t.join();
if(cancel)
Expand Down

0 comments on commit 028a460

Please sign in to comment.