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();
|
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 BarrierState;
|
||||||
|
|
||||||
class BarrierLock {
|
/// Barrier delays the execution of one or more Tasks.
|
||||||
shared_ptr<BarrierState> m_barrier_state;
|
/// The Tasks are executed when the last shared reference to the
|
||||||
BarrierLock(shared_ptr<BarrierState> pbs);
|
/// BarrierState is released. Copies of Barrier objects refer
|
||||||
friend class Barrier;
|
/// to the same Barrier state.
|
||||||
public:
|
|
||||||
// Release this Lock immediately and permanently
|
|
||||||
void release();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Barrier {
|
class Barrier {
|
||||||
shared_ptr<BarrierState> m_barrier_state;
|
shared_ptr<BarrierState> m_barrier_state;
|
||||||
|
|
||||||
Barrier(shared_ptr<BarrierState> pbs);
|
|
||||||
public:
|
public:
|
||||||
Barrier();
|
Barrier();
|
||||||
|
|
||||||
// Prevent execution of tasks behind barrier until
|
/// Schedule a task for execution when last Barrier is released.
|
||||||
// BarrierLock destructor or release() method is called.
|
|
||||||
BarrierLock lock();
|
|
||||||
|
|
||||||
// Schedule a task for execution when no Locks exist
|
|
||||||
void insert_task(Task t);
|
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.
|
// 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);
|
void insert_task(Task t);
|
||||||
};
|
};
|
||||||
|
|
||||||
Barrier::Barrier(shared_ptr<BarrierState> pbs) :
|
|
||||||
m_barrier_state(pbs)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Barrier::Barrier() :
|
|
||||||
m_barrier_state(make_shared<BarrierState>())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BarrierState::release()
|
BarrierState::release()
|
||||||
{
|
{
|
||||||
@ -813,17 +803,6 @@ namespace crucible {
|
|||||||
release();
|
release();
|
||||||
}
|
}
|
||||||
|
|
||||||
BarrierLock::BarrierLock(shared_ptr<BarrierState> pbs) :
|
|
||||||
m_barrier_state(pbs)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
BarrierLock::release()
|
|
||||||
{
|
|
||||||
m_barrier_state.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BarrierState::insert_task(Task t)
|
BarrierState::insert_task(Task t)
|
||||||
{
|
{
|
||||||
@ -831,16 +810,21 @@ namespace crucible {
|
|||||||
m_tasks.insert(t);
|
m_tasks.insert(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Barrier::Barrier() :
|
||||||
|
m_barrier_state(make_shared<BarrierState>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Barrier::insert_task(Task t)
|
Barrier::insert_task(Task t)
|
||||||
{
|
{
|
||||||
m_barrier_state->insert_task(t);
|
m_barrier_state->insert_task(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
BarrierLock
|
void
|
||||||
Barrier::lock()
|
Barrier::release()
|
||||||
{
|
{
|
||||||
return BarrierLock(m_barrier_state);
|
m_barrier_state.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExclusionState {
|
class ExclusionState {
|
||||||
|
50
test/task.cc
50
test/task.cc
@ -90,47 +90,51 @@ test_barrier(size_t count)
|
|||||||
|
|
||||||
mutex mtx;
|
mutex mtx;
|
||||||
condition_variable cv;
|
condition_variable cv;
|
||||||
|
bool done_flag = false;
|
||||||
|
|
||||||
unique_lock<mutex> lock(mtx);
|
unique_lock<mutex> lock(mtx);
|
||||||
|
|
||||||
auto b = make_shared<Barrier>();
|
Barrier b;
|
||||||
|
|
||||||
// Run several tasks in parallel
|
// Run several tasks in parallel
|
||||||
for (size_t c = 0; c < count; ++c) {
|
for (size_t c = 0; c < count; ++c) {
|
||||||
auto bl = b->lock();
|
|
||||||
ostringstream oss;
|
ostringstream oss;
|
||||||
oss << "task #" << c;
|
oss << "task #" << c;
|
||||||
|
auto b_hold = b;
|
||||||
Task t(
|
Task t(
|
||||||
oss.str(),
|
oss.str(),
|
||||||
[c, &task_done, &mtx, bl]() mutable {
|
[c, &task_done, &mtx, b_hold]() mutable {
|
||||||
// cerr << "Task #" << c << endl;
|
// ostringstream oss;
|
||||||
|
// oss << "Task #" << c << endl;
|
||||||
unique_lock<mutex> lock(mtx);
|
unique_lock<mutex> lock(mtx);
|
||||||
|
// cerr << oss.str();
|
||||||
task_done.at(c) = true;
|
task_done.at(c) = true;
|
||||||
bl.release();
|
b_hold.release();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
t.run();
|
t.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Need completed to go out of local scope so it will release b
|
||||||
|
{
|
||||||
|
Task completed(
|
||||||
|
"Waiting for Barrier",
|
||||||
|
[&mtx, &cv, &done_flag]() {
|
||||||
|
unique_lock<mutex> lock(mtx);
|
||||||
|
// cerr << "Running cv notify" << endl;
|
||||||
|
done_flag = true;
|
||||||
|
cv.notify_all();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
b.insert_task(completed);
|
||||||
|
}
|
||||||
|
|
||||||
// Get current status
|
// Get current status
|
||||||
ostringstream oss;
|
// TaskMaster::print_queue(cerr);
|
||||||
TaskMaster::print_queue(oss);
|
// TaskMaster::print_workers(cerr);
|
||||||
TaskMaster::print_workers(oss);
|
|
||||||
|
|
||||||
bool done_flag = false;
|
// Release our b
|
||||||
|
b.release();
|
||||||
Task completed(
|
|
||||||
"Waiting for Barrier",
|
|
||||||
[&mtx, &cv, &done_flag]() {
|
|
||||||
unique_lock<mutex> lock(mtx);
|
|
||||||
// cerr << "Running cv notify" << endl;
|
|
||||||
done_flag = true;
|
|
||||||
cv.notify_all();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
b->insert_task(completed);
|
|
||||||
|
|
||||||
b.reset();
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
size_t tasks_done = 0;
|
size_t tasks_done = 0;
|
||||||
@ -139,7 +143,7 @@ test_barrier(size_t count)
|
|||||||
++tasks_done;
|
++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) {
|
if (tasks_done == count && done_flag) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user