mirror of
https://github.com/Zygo/bees.git
synced 2025-05-17 21:35:45 +02:00
task: get rid of the separate Barrier and BarrierLock
Make one class Barrier which is copiable, so we don't have to have users making shared Barrier all the time. Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
parent
d345ea2b78
commit
7fdb87143c
@ -99,36 +99,26 @@ namespace crucible {
|
||||
static void cancel();
|
||||
};
|
||||
|
||||
// Barrier executes waiting Tasks once the last BarrierLock
|
||||
// is released. Multiple unique Tasks may be scheduled while
|
||||
// BarrierLocks exist and all will be run() at once upon
|
||||
// release. If no BarrierLocks exist, Tasks are executed
|
||||
// immediately upon insertion.
|
||||
|
||||
class BarrierState;
|
||||
|
||||
class BarrierLock {
|
||||
shared_ptr<BarrierState> m_barrier_state;
|
||||
BarrierLock(shared_ptr<BarrierState> pbs);
|
||||
friend class Barrier;
|
||||
public:
|
||||
// Release this Lock immediately and permanently
|
||||
void release();
|
||||
};
|
||||
|
||||
/// Barrier delays the execution of one or more Tasks.
|
||||
/// The Tasks are executed when the last shared reference to the
|
||||
/// BarrierState is released. Copies of Barrier objects refer
|
||||
/// to the same Barrier state.
|
||||
class Barrier {
|
||||
shared_ptr<BarrierState> m_barrier_state;
|
||||
|
||||
Barrier(shared_ptr<BarrierState> pbs);
|
||||
public:
|
||||
Barrier();
|
||||
|
||||
// Prevent execution of tasks behind barrier until
|
||||
// BarrierLock destructor or release() method is called.
|
||||
BarrierLock lock();
|
||||
|
||||
// Schedule a task for execution when no Locks exist
|
||||
/// Schedule a task for execution when last Barrier is released.
|
||||
void insert_task(Task t);
|
||||
|
||||
/// Release this reference to the barrier state.
|
||||
/// Last released reference executes the task.
|
||||
/// Barrier can only be released once, after which the
|
||||
/// object can no longer be used.
|
||||
void release();
|
||||
};
|
||||
|
||||
// Exclusion provides exclusive access to a ExclusionLock.
|
||||
|
32
lib/task.cc
32
lib/task.cc
@ -788,16 +788,6 @@ namespace crucible {
|
||||
void insert_task(Task t);
|
||||
};
|
||||
|
||||
Barrier::Barrier(shared_ptr<BarrierState> pbs) :
|
||||
m_barrier_state(pbs)
|
||||
{
|
||||
}
|
||||
|
||||
Barrier::Barrier() :
|
||||
m_barrier_state(make_shared<BarrierState>())
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BarrierState::release()
|
||||
{
|
||||
@ -813,17 +803,6 @@ namespace crucible {
|
||||
release();
|
||||
}
|
||||
|
||||
BarrierLock::BarrierLock(shared_ptr<BarrierState> pbs) :
|
||||
m_barrier_state(pbs)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BarrierLock::release()
|
||||
{
|
||||
m_barrier_state.reset();
|
||||
}
|
||||
|
||||
void
|
||||
BarrierState::insert_task(Task t)
|
||||
{
|
||||
@ -831,16 +810,21 @@ namespace crucible {
|
||||
m_tasks.insert(t);
|
||||
}
|
||||
|
||||
Barrier::Barrier() :
|
||||
m_barrier_state(make_shared<BarrierState>())
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Barrier::insert_task(Task t)
|
||||
{
|
||||
m_barrier_state->insert_task(t);
|
||||
}
|
||||
|
||||
BarrierLock
|
||||
Barrier::lock()
|
||||
void
|
||||
Barrier::release()
|
||||
{
|
||||
return BarrierLock(m_barrier_state);
|
||||
m_barrier_state.reset();
|
||||
}
|
||||
|
||||
class ExclusionState {
|
||||
|
34
test/task.cc
34
test/task.cc
@ -90,35 +90,33 @@ test_barrier(size_t count)
|
||||
|
||||
mutex mtx;
|
||||
condition_variable cv;
|
||||
bool done_flag = false;
|
||||
|
||||
unique_lock<mutex> lock(mtx);
|
||||
|
||||
auto b = make_shared<Barrier>();
|
||||
Barrier b;
|
||||
|
||||
// Run several tasks in parallel
|
||||
for (size_t c = 0; c < count; ++c) {
|
||||
auto bl = b->lock();
|
||||
ostringstream oss;
|
||||
oss << "task #" << c;
|
||||
auto b_hold = b;
|
||||
Task t(
|
||||
oss.str(),
|
||||
[c, &task_done, &mtx, bl]() mutable {
|
||||
// cerr << "Task #" << c << endl;
|
||||
[c, &task_done, &mtx, b_hold]() mutable {
|
||||
// ostringstream oss;
|
||||
// oss << "Task #" << c << endl;
|
||||
unique_lock<mutex> lock(mtx);
|
||||
// cerr << oss.str();
|
||||
task_done.at(c) = true;
|
||||
bl.release();
|
||||
b_hold.release();
|
||||
}
|
||||
);
|
||||
t.run();
|
||||
}
|
||||
|
||||
// Get current status
|
||||
ostringstream oss;
|
||||
TaskMaster::print_queue(oss);
|
||||
TaskMaster::print_workers(oss);
|
||||
|
||||
bool done_flag = false;
|
||||
|
||||
// Need completed to go out of local scope so it will release b
|
||||
{
|
||||
Task completed(
|
||||
"Waiting for Barrier",
|
||||
[&mtx, &cv, &done_flag]() {
|
||||
@ -128,9 +126,15 @@ test_barrier(size_t count)
|
||||
cv.notify_all();
|
||||
}
|
||||
);
|
||||
b->insert_task(completed);
|
||||
b.insert_task(completed);
|
||||
}
|
||||
|
||||
b.reset();
|
||||
// Get current status
|
||||
// TaskMaster::print_queue(cerr);
|
||||
// TaskMaster::print_workers(cerr);
|
||||
|
||||
// Release our b
|
||||
b.release();
|
||||
|
||||
while (true) {
|
||||
size_t tasks_done = 0;
|
||||
@ -139,7 +143,7 @@ test_barrier(size_t count)
|
||||
++tasks_done;
|
||||
}
|
||||
}
|
||||
// cerr << "Tasks done: " << tasks_done << " done_flag " << done_flag << endl;
|
||||
cerr << "Tasks done: " << tasks_done << " done_flag " << done_flag << endl;
|
||||
if (tasks_done == count && done_flag) {
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user