diff --git a/include/crucible/task.h b/include/crucible/task.h index 72ee359..14b07b0 100644 --- a/include/crucible/task.h +++ b/include/crucible/task.h @@ -32,13 +32,22 @@ namespace crucible { // schedule Task before other queued tasks void run_earlier() const; + // describe Task as text + ostream &print(ostream &os) const; + // Returns currently executing task if called from exec_fn. // Usually used to reschedule the currently executing Task. static Task current_task(); + // Ordering for containers bool operator<(const Task &that) const; + + // Null test + operator bool() const; }; + ostream &operator<<(ostream &os, const Task &task); + class TaskMaster { public: // Blocks until the running thread count reaches this number diff --git a/lib/task.cc b/lib/task.cc index 3d31aa2..abaf9f7 100644 --- a/lib/task.cc +++ b/lib/task.cc @@ -15,7 +15,7 @@ namespace crucible { using namespace std; - static thread_local weak_ptr s_current_task_wp; + static thread_local weak_ptr tl_current_task_wp; class TaskState : public enable_shared_from_this { const function m_exec_fn; @@ -28,7 +28,7 @@ namespace crucible { void exec(); ostream &print(ostream &os); - TaskId id(); + TaskId id() const; }; atomic TaskState::s_next_id; @@ -87,9 +87,9 @@ namespace crucible { THROW_CHECK0(invalid_argument, m_exec_fn); weak_ptr this_task_wp = shared_from_this(); Cleanup cleaner([&]() { - swap(this_task_wp, s_current_task_wp); + swap(this_task_wp, tl_current_task_wp); }); - swap(this_task_wp, s_current_task_wp); + swap(this_task_wp, tl_current_task_wp); m_exec_fn(); } @@ -101,7 +101,7 @@ namespace crucible { } TaskId - TaskState::id() + TaskState::id() const { return m_id; } @@ -126,7 +126,6 @@ namespace crucible { void TaskMasterState::push_back(shared_ptr task) { - assert(task); THROW_CHECK0(runtime_error, task); s_tms->start_stop_threads(); unique_lock lock(s_tms->m_mutex); @@ -137,7 +136,6 @@ namespace crucible { void TaskMasterState::push_front(shared_ptr task) { - assert(task); THROW_CHECK0(runtime_error, task); s_tms->start_stop_threads(); unique_lock lock(s_tms->m_mutex); @@ -224,42 +222,51 @@ namespace crucible { Task::Task(shared_ptr pts) : m_task_state(pts) { - assert(m_task_state); } Task::Task(function exec_fn, function print_fn) : m_task_state(make_shared(exec_fn, print_fn)) { - assert(m_task_state); } void Task::run() const { - assert(m_task_state); + THROW_CHECK0(runtime_error, m_task_state); TaskMasterState::push_back(m_task_state); } void Task::run_earlier() const { - assert(m_task_state); + THROW_CHECK0(runtime_error, m_task_state); TaskMasterState::push_front(m_task_state); } Task Task::current_task() { - return Task(s_current_task_wp.lock()); + return Task(tl_current_task_wp.lock()); } + ostream & + Task::print(ostream &os) const + { + THROW_CHECK0(runtime_error, m_task_state); + return m_task_state->print(os); + } + + ostream & + operator<<(ostream &os, const Task &task) + { + return task.print(os); + }; + TaskId Task::id() const { - if (m_task_state) { - return m_task_state->id(); - } - return 0; + THROW_CHECK0(runtime_error, m_task_state); + return m_task_state->id(); } bool @@ -268,6 +275,11 @@ namespace crucible { return id() < that.id(); } + Task::operator bool() const + { + return !!m_task_state; + } + shared_ptr TaskConsumer::current_task_locked() {