Skip to content

Commit 34aacb6

Browse files
committed
final quickpool version 1.4.0
1 parent e150c5f commit 34aacb6

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

inst/include/RcppThread/quickpool.hpp

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ static constexpr std::memory_order acquire = std::memory_order_acquire;
6767
static constexpr std::memory_order release = std::memory_order_release;
6868
static constexpr std::memory_order seq_cst = std::memory_order_seq_cst;
6969

70-
}
71-
7270
//! Padding char[]s always must hold at least one char. If the size of the
7371
//! object ends at an alignment point, we don't want to pad one extra byte
7472
//! however. The construct below ensures that padding bytes are only added if
@@ -148,8 +146,8 @@ free(void* ptr) noexcept
148146
}
149147
}
150148

151-
// short version of
152-
// https://www.boost.org/doc/libs/1_65_0/boost/align/aligned_allocator.hpp
149+
//! short version of
150+
//! https://www.boost.org/doc/libs/1_65_0/boost/align/aligned_allocator.hpp
153151
template<class T, std::size_t Alignment = 64>
154152
class allocator : public std::allocator<T>
155153
{
@@ -169,14 +167,14 @@ class allocator : public std::allocator<T>
169167
if (size == 0) {
170168
return 0;
171169
}
172-
void* p = aligned::alloc(min_align, sizeof(T) * size);
170+
void* p = mem::aligned::alloc(min_align, sizeof(T) * size);
173171
if (!p) {
174172
throw std::bad_alloc();
175173
}
176174
return static_cast<T*>(p);
177175
}
178176

179-
void deallocate(T* ptr, size_t) { aligned::free(ptr); }
177+
void deallocate(T* ptr, size_t) { mem::aligned::free(ptr); }
180178

181179
template<class U, class... Args>
182180
void construct(U* ptr, Args&&... args)
@@ -213,18 +211,18 @@ struct alignas(Align) atomic
213211

214212
static void* operator new(size_t count) noexcept
215213
{
216-
return aligned::alloc(Align, count);
214+
return mem::aligned::alloc(Align, count);
217215
}
218216

219-
static void operator delete(void* ptr) { aligned::free(ptr); }
217+
static void operator delete(void* ptr) { mem::aligned::free(ptr); }
220218
};
221219

222220
//! Fast and simple load/assign atomic with no memory ordering guarantees.
223221
template<typename T>
224-
struct relaxed_atomic : public aligned::atomic<T>
222+
struct relaxed_atomic : public mem::aligned::atomic<T>
225223
{
226224
explicit relaxed_atomic(T value)
227-
: aligned::atomic<T>(value)
225+
: mem::aligned::atomic<T>(value)
228226
{}
229227

230228
operator T() const noexcept { return this->load(mem::relaxed); }
@@ -236,11 +234,14 @@ struct relaxed_atomic : public aligned::atomic<T>
236234
}
237235
};
238236

237+
//! vector class for aligned types.
239238
template<class T, size_t Alignment = 64>
240-
using vector = std::vector<T, aligned::allocator<T, Alignment>>;
239+
using vector = std::vector<T, mem::aligned::allocator<T, Alignment>>;
241240

242241
} // end namespace aligned
243242

243+
} // end namespace mem
244+
244245
// 2. --------------------------------------------------------------------------
245246

246247
//! Loop related utilities.
@@ -286,7 +287,7 @@ struct Worker
286287
bool done() const { return (tasks_left() == 0); }
287288

288289
//! @param others pointer to the vector of all workers.
289-
void run(std::shared_ptr<aligned::vector<Worker>> others)
290+
void run(std::shared_ptr<mem::aligned::vector<Worker>> others)
290291
{
291292
State s, s_old; // temporary state variables
292293
do {
@@ -316,7 +317,7 @@ struct Worker
316317
}
317318

318319
//! @param workers vector of all workers.
319-
void steal_range(aligned::vector<Worker>& workers)
320+
void steal_range(mem::aligned::vector<Worker>& workers)
320321
{
321322
do {
322323
Worker& other = find_victim(workers);
@@ -338,7 +339,7 @@ struct Worker
338339
}
339340

340341
//! @param workers vector of all workers.
341-
bool all_done(const aligned::vector<Worker>& workers)
342+
bool all_done(const mem::aligned::vector<Worker>& workers)
342343
{
343344
for (const auto& worker : workers) {
344345
if (!worker.done())
@@ -350,7 +351,7 @@ struct Worker
350351
//! targets the worker with the largest remaining range to minimize
351352
//! number of steal events.
352353
//! @param others vector of all workers.
353-
Worker& find_victim(aligned::vector<Worker>& workers)
354+
Worker& find_victim(mem::aligned::vector<Worker>& workers)
354355
{
355356
std::vector<size_t> tasks_left;
356357
tasks_left.reserve(workers.size());
@@ -362,27 +363,27 @@ struct Worker
362363
return workers[idx];
363364
}
364365

365-
aligned::relaxed_atomic<State> state; //!< worker state `{pos, end}`
366+
mem::aligned::relaxed_atomic<State> state; //!< worker state `{pos, end}`
366367
Function f; //< function applied to the loop index
367368
};
368369

369370
//! creates loop workers. They must be passed to each worker using a shared
370371
//! pointer, so that they persist if an inner `parallel_for()` in a nested
371372
//! loop exits.
372373
template<typename Function>
373-
std::shared_ptr<aligned::vector<Worker<Function>>>
374+
std::shared_ptr<mem::aligned::vector<Worker<Function>>>
374375
create_workers(const Function& f, int begin, int end, size_t num_workers)
375376
{
376377
auto num_tasks = std::max(end - begin, static_cast<int>(0));
377378
num_workers = std::max(num_workers, static_cast<size_t>(1));
378-
auto workers = new aligned::vector<Worker<Function>>;
379+
auto workers = new mem::aligned::vector<Worker<Function>>;
379380
workers->reserve(num_workers);
380381
for (size_t i = 0; i < num_workers; i++) {
381382
workers->emplace_back(begin + num_tasks * i / num_workers,
382383
begin + num_tasks * (i + 1) / num_workers,
383384
f);
384385
}
385-
return std::shared_ptr<aligned::vector<Worker<Function>>>(
386+
return std::shared_ptr<mem::aligned::vector<Worker<Function>>>(
386387
std::move(workers));
387388
}
388389

@@ -529,8 +530,8 @@ class TaskQueue
529530

530531
private:
531532
//! queue indices
532-
aligned::atomic<int> top_{ 0 };
533-
aligned::atomic<int> bottom_{ 0 };
533+
mem::aligned::atomic<int> top_{ 0 };
534+
mem::aligned::atomic<int> bottom_{ 0 };
534535

535536
//! ring buffer holding task pointers
536537
std::atomic<RingBuffer<Task*>*> buffer_{ nullptr };
@@ -569,7 +570,7 @@ class TaskManager
569570
{
570571
num_queues_ = std::max(num_queues, static_cast<size_t>(1));
571572
if (num_queues > queues_.size()) {
572-
queues_ = aligned::vector<TaskQueue>(num_queues);
573+
queues_ = mem::aligned::vector<TaskQueue>(num_queues);
573574
// thread pool must have stopped the manager, reset
574575
num_waiting_ = 0;
575576
todo_ = 0;
@@ -725,13 +726,13 @@ class TaskManager
725726

726727
private:
727728
//! worker queues
728-
aligned::vector<TaskQueue> queues_;
729+
mem::aligned::vector<TaskQueue> queues_;
729730
size_t num_queues_;
730731

731732
//! task management
732-
aligned::relaxed_atomic<size_t> num_waiting_{ 0 };
733-
aligned::relaxed_atomic<size_t> push_idx_{ 0 };
734-
aligned::atomic<int> todo_{ 0 };
733+
mem::aligned::relaxed_atomic<size_t> num_waiting_{ 0 };
734+
mem::aligned::relaxed_atomic<size_t> push_idx_{ 0 };
735+
mem::aligned::atomic<int> todo_{ 0 };
735736

736737
//! synchronization variables
737738
const std::thread::id owner_id_;
@@ -741,7 +742,7 @@ class TaskManager
741742
errored,
742743
stopped
743744
};
744-
aligned::atomic<Status> status_{ Status::running };
745+
mem::aligned::atomic<Status> status_{ Status::running };
745746
std::mutex mtx_;
746747
std::condition_variable cv_;
747748
std::exception_ptr err_ptr_{ nullptr };
@@ -896,11 +897,11 @@ class ThreadPool
896897
//! @brief allocator respecting memory alignment.
897898
static void* operator new(size_t count) noexcept
898899
{
899-
return aligned::alloc(alignof(ThreadPool), count);
900+
return mem::aligned::alloc(alignof(ThreadPool), count);
900901
}
901902

902903
//! @brief deallocator respecting memory alignment.
903-
static void operator delete(void* ptr) { aligned::free(ptr); }
904+
static void operator delete(void* ptr) { mem::aligned::free(ptr); }
904905

905906
private:
906907
//! joins all worker threads.

0 commit comments

Comments
 (0)