flatten 20260225
This commit is contained in:
109
tjp/core/threads/Parallel.cpp
Executable file
109
tjp/core/threads/Parallel.cpp
Executable file
@@ -0,0 +1,109 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
#include "Parallel.hpp"
|
||||
#include <limits>
|
||||
|
||||
namespace tjp::core::threads {
|
||||
|
||||
|
||||
Parallel::Parallel(int max, int free)
|
||||
{
|
||||
start(max, free);
|
||||
}
|
||||
|
||||
Parallel::~Parallel()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void Parallel::start(int max, int free)
|
||||
{
|
||||
auto lock = lock_of(mutex);
|
||||
if (running)
|
||||
return;
|
||||
|
||||
running = true;
|
||||
auto n_ =
|
||||
std::max(
|
||||
1,
|
||||
std::min(
|
||||
max,
|
||||
(int)std::thread::hardware_concurrency() - free
|
||||
)
|
||||
);
|
||||
|
||||
n = n_;
|
||||
debug_assert(n > 0 && n <= max);
|
||||
|
||||
threads = new std::thread[n];
|
||||
|
||||
for (auto m=0; m<n; m++)
|
||||
{
|
||||
threads[m] = std::thread([this, m]() {
|
||||
execute(n, m);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Parallel::execute(size_t n, size_t m)
|
||||
{
|
||||
auto lock = lock_of(mutex);
|
||||
while (running)
|
||||
{
|
||||
event.wait(lock, [&](){
|
||||
return
|
||||
!running ||
|
||||
(signal & (SignalBit << m));
|
||||
});
|
||||
|
||||
if (!running)
|
||||
break;
|
||||
|
||||
{
|
||||
auto unlock = unlock_of(mutex);
|
||||
|
||||
f(n, m);
|
||||
}
|
||||
|
||||
signal ^= SignalBit << m;
|
||||
|
||||
event.notify_all();
|
||||
}
|
||||
|
||||
event.notify_all();
|
||||
}
|
||||
|
||||
void Parallel::run(F &&f_)
|
||||
{
|
||||
auto lock_ = lock_of(oneUser);
|
||||
auto lock = lock_of(mutex);
|
||||
|
||||
f = std::move(f_);
|
||||
signal = 0;
|
||||
for (auto i=0; i<n; ++i)
|
||||
signal |= (1 << i);
|
||||
|
||||
event.notify_all();
|
||||
|
||||
event.wait(lock, [&]() {
|
||||
return signal == 0 || !running;
|
||||
});
|
||||
}
|
||||
|
||||
void Parallel::stop()
|
||||
{
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
running = false;
|
||||
signal = std::numeric_limits<Signal>::max();
|
||||
event.notify_all();
|
||||
|
||||
auto n = std::thread::hardware_concurrency();
|
||||
for (auto m=0; m<n; ++m)
|
||||
threads[m].join();
|
||||
|
||||
delete[] threads;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user