Loading...
Searching...
No Matches
eonc::detail::ImagePool Class Reference

#include <ForEachImage.h>

Public Member Functions

 ImagePool (const ImagePool &)=delete
ImagePool & operator= (const ImagePool &)=delete
 ~ImagePool ()
void run (long n, const std::function< void(long)> &work)
std::size_t threads () const noexcept
void ensureThreads (std::size_t n)

Static Public Member Functions

static ImagePool & instance ()

Private Member Functions

 ImagePool ()
void drain ()
void loop (long index)

Static Private Member Functions

static void serial (long n, const std::function< void(long)> &work)

Private Attributes

std::vector< std::thread > threads_
std::mutex runMutex_
std::mutex mutex_
std::condition_variable wake_
std::condition_variable done_
const std::function< void(long)> * work_ {nullptr}
long n_ {0}
std::atomic< long > next_ {1}
std::exception_ptr failure_
long helpers_ {0}
long active_ {0}
std::size_t generation_ {0}
bool stop_ {false}

Detailed Description

Definition at line 44 of file ForEachImage.h.

Constructor & Destructor Documentation

◆ ImagePool() [1/2]

eonc::detail::ImagePool::ImagePool ( const ImagePool & )
delete

◆ ~ImagePool()

eonc::detail::ImagePool::~ImagePool ( )
inline

Definition at line 54 of file ForEachImage.h.

54 {
55 {
56 std::lock_guard<std::mutex> lock(mutex_);
57 stop_ = true;
58 }
59 wake_.notify_all();
60 for (auto &t : threads_)
61 t.join();
62 }
std::condition_variable wake_
std::vector< std::thread > threads_

◆ ImagePool() [2/2]

eonc::detail::ImagePool::ImagePool ( )
inlineprivate

Definition at line 111 of file ForEachImage.h.

111 {
112 const long helpers = usableCores() - 1;
113 for (long t = 0; t < helpers; t++) {
114 try {
115 threads_.emplace_back([this, t] { loop(t); });
116 } catch (...) {
117 break; // the threads already running serve every band
118 }
119 }
120 }
void loop(long index)
long usableCores()

Member Function Documentation

◆ drain()

void eonc::detail::ImagePool::drain ( )
inlineprivate

Definition at line 136 of file ForEachImage.h.

136 {
137 for (long i = next_.fetch_add(1); i <= n_; i = next_.fetch_add(1)) {
138 try {
139 (*work_)(i);
140 } catch (...) {
141 std::lock_guard<std::mutex> lock(mutex_);
142 if (!failure_)
143 failure_ = std::current_exception();
144 }
145 }
146 }
std::exception_ptr failure_
std::atomic< long > next_

◆ ensureThreads()

void eonc::detail::ImagePool::ensureThreads ( std::size_t n)
inline

Definition at line 98 of file ForEachImage.h.

98 {
99 std::lock_guard<std::mutex> busy(runMutex_);
100 while (threads_.size() < n) {
101 const long index = static_cast<long>(threads_.size());
102 try {
103 threads_.emplace_back([this, index] { loop(index); });
104 } catch (...) {
105 break;
106 }
107 }
108 }

◆ instance()

ImagePool & eonc::detail::ImagePool::instance ( )
inlinestatic

Definition at line 46 of file ForEachImage.h.

46 {
47 static ImagePool pool;
48 return pool;
49 }
ImagePool(const ImagePool &)=delete

◆ loop()

void eonc::detail::ImagePool::loop ( long index)
inlineprivate

Definition at line 148 of file ForEachImage.h.

148 {
149 std::size_t seen = 0;
150 for (;;) {
151 {
152 std::unique_lock<std::mutex> lock(mutex_);
153 wake_.wait(lock, [&] {
154 return stop_ || (generation_ != seen && index < helpers_);
155 });
156 if (stop_)
157 return;
158 seen = generation_;
159 }
160 drain();
161 {
162 std::lock_guard<std::mutex> lock(mutex_);
163 if (--active_ == 0)
164 done_.notify_one();
165 }
166 }
167 }
std::condition_variable done_

◆ operator=()

ImagePool & eonc::detail::ImagePool::operator= ( const ImagePool & )
delete

◆ run()

void eonc::detail::ImagePool::run ( long n,
const std::function< void(long)> & work )
inline

Definition at line 66 of file ForEachImage.h.

66 {
67 if (n <= 0)
68 return;
69 std::unique_lock<std::mutex> busy(runMutex_, std::try_to_lock);
70 if (!busy.owns_lock() || threads_.empty() || n == 1) {
71 serial(n, work);
72 return;
73 }
74 {
75 std::lock_guard<std::mutex> lock(mutex_);
76 work_ = &work;
77 n_ = n;
78 next_.store(1);
79 failure_ = nullptr;
80 // Only as many helpers as there are images beyond the caller's.
81 helpers_ = std::min<long>(static_cast<long>(threads_.size()), n - 1);
84 }
85 wake_.notify_all();
86 drain();
87 std::unique_lock<std::mutex> lock(mutex_);
88 done_.wait(lock, [this] { return active_ == 0; });
89 work_ = nullptr;
90 if (failure_)
91 std::rethrow_exception(failure_);
92 }
static void serial(long n, const std::function< void(long)> &work)
const std::function< void(long)> * work_

◆ serial()

void eonc::detail::ImagePool::serial ( long n,
const std::function< void(long)> & work )
inlinestaticprivate

Definition at line 122 of file ForEachImage.h.

122 {
123 std::exception_ptr failure;
124 for (long i = 1; i <= n; i++) {
125 try {
126 work(i);
127 } catch (...) {
128 if (!failure)
129 failure = std::current_exception();
130 }
131 }
132 if (failure)
133 std::rethrow_exception(failure);
134 }

◆ threads()

std::size_t eonc::detail::ImagePool::threads ( ) const
inlinenodiscardnoexcept

Definition at line 94 of file ForEachImage.h.

94{ return threads_.size(); }

Member Data Documentation

◆ active_

long eonc::detail::ImagePool::active_ {0}
private

Definition at line 179 of file ForEachImage.h.

179{0};

◆ done_

std::condition_variable eonc::detail::ImagePool::done_
private

Definition at line 173 of file ForEachImage.h.

◆ failure_

std::exception_ptr eonc::detail::ImagePool::failure_
private

Definition at line 177 of file ForEachImage.h.

◆ generation_

std::size_t eonc::detail::ImagePool::generation_ {0}
private

Definition at line 180 of file ForEachImage.h.

180{0};

◆ helpers_

long eonc::detail::ImagePool::helpers_ {0}
private

Definition at line 178 of file ForEachImage.h.

178{0};

◆ mutex_

std::mutex eonc::detail::ImagePool::mutex_
private

Definition at line 171 of file ForEachImage.h.

◆ n_

long eonc::detail::ImagePool::n_ {0}
private

Definition at line 175 of file ForEachImage.h.

175{0};

◆ next_

std::atomic<long> eonc::detail::ImagePool::next_ {1}
private

Definition at line 176 of file ForEachImage.h.

176{1};

◆ runMutex_

std::mutex eonc::detail::ImagePool::runMutex_
private

Definition at line 170 of file ForEachImage.h.

◆ stop_

bool eonc::detail::ImagePool::stop_ {false}
private

Definition at line 181 of file ForEachImage.h.

181{false};

◆ threads_

std::vector<std::thread> eonc::detail::ImagePool::threads_
private

Definition at line 169 of file ForEachImage.h.

◆ wake_

std::condition_variable eonc::detail::ImagePool::wake_
private

Definition at line 172 of file ForEachImage.h.

◆ work_

const std::function<void(long)>* eonc::detail::ImagePool::work_ {nullptr}
private

Definition at line 174 of file ForEachImage.h.

174{nullptr};

The documentation for this class was generated from the following file: