Skip to content

Commit 8460e1f

Browse files
committed
chore: add parallelFor
1 parent 21b6df1 commit 8460e1f

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

include/mrdox/Support/ParallelFor.hpp

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//
2+
// This is a derivative work. originally part of the LLVM Project.
3+
// Licensed under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
// Copyright (c) 2023 Vinnie Falco ([email protected])
8+
//
9+
// Official repository: https://github.com/cppalliance/mrdox
10+
//
11+
12+
#ifndef MRDOX_SUPPORT_PARALLELFOR_HPP
13+
#define MRDOX_SUPPORT_PARALLELFOR_HPP
14+
15+
#include <mrdox/Platform.hpp>
16+
#include <mrdox/Support/Error.hpp>
17+
#include <iterator>
18+
#include <mutex>
19+
#include <thread>
20+
#include <vector>
21+
22+
namespace clang {
23+
namespace mrdox {
24+
25+
/** Visit all elements of a range concurrently.
26+
*/
27+
template<
28+
class Range,
29+
class Worker,
30+
class... Args>
31+
Error
32+
parallelFor(
33+
Range&& range,
34+
std::vector<Worker>& workers,
35+
Args&&... args)
36+
{
37+
std::mutex m;
38+
bool cancel = false;
39+
auto it = std::begin(range);
40+
auto const end = std::end(range);
41+
auto const do_work =
42+
[&](Worker& worker)
43+
{
44+
std::unique_lock<std::mutex> lock(m);
45+
if(it == end || cancel)
46+
return false;
47+
auto it0 = it;
48+
++it;
49+
lock.unlock();
50+
bool cancel_ = worker(*it0,
51+
std::forward<Args>(args)...);
52+
if(! cancel_)
53+
return true;
54+
cancel = true;
55+
return false;
56+
};
57+
std::vector<std::thread> threads;
58+
threads.reserve(workers.size());
59+
for(std::size_t i = 0; i < workers.size(); ++i)
60+
threads.emplace_back(std::thread(
61+
[&](std::size_t i_)
62+
{
63+
for(;;)
64+
if(! do_work(workers[i]))
65+
break;
66+
}, i));
67+
for(auto& t : threads)
68+
t.join();
69+
if(cancel)
70+
return Error("canceled");
71+
return Error::success();
72+
}
73+
74+
} // mrdox
75+
} // clang
76+
77+
#endif

0 commit comments

Comments
 (0)