Exemple #1
0
void mt_task_queue::submit_core(gtask const & t, unsigned prio) {
    if (!t) return;
    switch (get_state(t).load()){
        case task_state::Created:
            get_data(t)->m_sched_info.reset(new mt_sched_info(prio));
            if (check_deps(t)) {
                if (get_state(t).load() < task_state::Running) {
                    // TODO(gabriel): we need to give up the lock on m_mutex for this
                    if (false && get_data(t)->m_flags.m_eager_execution) {
                        get_state(t) = task_state::Running;
                        execute(t);
                        handle_finished(t);
                    } else {
                        enqueue(t);
                    }
                }
            } else {
                get_state(t) = task_state::Waiting;
                m_waiting.insert(t);
                notify_queue_changed();
            }
            break;
        case task_state::Waiting: case task_state::Queued:
            bump_prio(t, prio);
            break;
        case task_state::Running: case task_state::Failed: case task_state::Success:
            break;
    }
    lean_always_assert(get_state(t).load() >= task_state::Waiting);
}
Exemple #2
0
void mt_task_queue::cancel_core(gtask const & t) {
    if (!t) return;
    switch (get_state(t).load()) {
        case task_state::Waiting:
            m_waiting.erase(t);
            /* fall-thru */
        case task_state::Created: case task_state::Queued:
            fail(t, std::make_exception_ptr(cancellation_exception()));
            handle_finished(t);
            return;
        default: return;
    }
}
Exemple #3
0
void MainGUI::toggle_rendering(bool is_world_bad) {
  if (is_world_bad) {
    handle_finished();
    QMessageBox msgBox;
    msgBox.setText("Invalid world! Check if you have selected the right folder.");
    msgBox.setIcon(QMessageBox::Warning);
    msgBox.exec();
    return;
  }
  bf->set_settings(set);
  mf->set_nbt(bf);
  delete scene;
  scene = new QGraphicsScene();
  mf->reset_view(scene);

  start_button->setText("Abort rendering");
  start_button->setEnabled(true);
  waiter_thread = boost::thread(boost::bind(&MainGUI::start_populate_scene_thread, this));
}
Exemple #4
0
void mt_task_queue::handle_finished(gtask const & t) {
    lean_always_assert(get_state(t).load() > task_state::Running);
    lean_always_assert(get_data(t));

    if (!get_data(t)->m_sched_info)
        return;  // task has never been submitted

    m_waiting.erase(t);
    get_sched_info(t).notify();

    for (auto & rdep : get_sched_info(t).m_reverse_deps) {
        switch (get_state(rdep).load()) {
            case task_state::Waiting: case task_state::Queued:
                if (check_deps(rdep)) {
                    m_waiting.erase(rdep);
                    if (get_state(rdep).load() < task_state::Running) {
                        lean_always_assert(get_data(rdep));
                        // TODO(gabriel): we need to give up the lock on m_mutex for this
                        if (false && get_data(rdep)->m_flags.m_eager_execution) {
                            get_state(rdep) = task_state::Running;
                            execute(rdep);
                            handle_finished(rdep);
                        } else {
                            enqueue(rdep);
                        }
                    }
                }
                break;
            case task_state::Failed:
                // TODO(gabriel): removed failed tasks from reverse dependency lists?
                m_waiting.erase(rdep);
                break;
            case task_state::Success:
                // this can happen if a task occurs in more than one reverse dependency list,
                // or gets submitted more than once
                break;
            default: lean_unreachable();
        }
    }

    clear(t);
}
Exemple #5
0
void MainGUI::start_populate_scene_thread() {
  boost::thread populate_scene_thread(boost::bind(&MainForm::populateScene, mf));
  populate_scene_thread.join();
  handle_finished();
}
Exemple #6
0
void mt_task_queue::spawn_worker() {
    lean_always_assert(!m_shutting_down);
    auto this_worker = std::make_shared<worker_info>();
    m_workers.push_back(this_worker);
    m_required_workers--;
    this_worker->m_thread.reset(new lthread([this, this_worker]() {
        save_stack_info(false);

        unique_lock<mutex> lock(m_mutex);
        while (true) {
            if (m_shutting_down) {
                break;
            }
            if (m_required_workers < 0) {
                scoped_add<int> inc_required(m_required_workers, +1);
                scoped_add<unsigned> inc_sleeping(m_sleeping_workers, +1);
                if (m_wake_up_worker.wait_for(lock, g_worker_max_idle_time,
                                              [&] { return m_required_workers >= 1 || m_shutting_down; })) {
                    continue;
                } else {
                    break;
                }
            }
            if (m_queue.empty()) {
                if (m_queue_added.wait_for(lock, g_worker_max_idle_time,
                                           [&] { return !m_queue.empty() || m_shutting_down; })) {
                    continue;
                } else {
                    break;
                }
            }

            auto t = dequeue();
            if (get_state(t).load() != task_state::Queued) continue;

            get_state(t) = task_state::Running;
            reset_heartbeat();
            {
                flet<gtask> _(this_worker->m_current_task, t);
                scoped_current_task scope_cur_task(&t);
                notify_queue_changed();
                lock.unlock();
                execute(t);
                lock.lock();
            }
            reset_heartbeat();

            handle_finished(t);

            notify_queue_changed();
        }

        // We need to run the finalizers while the lock is held,
        // otherwise we risk a race condition at the end of the program.
        // We would finalize in the thread, while we call the finalize() function.
        run_thread_finalizers();
        run_post_thread_finalizers();

        m_workers.erase(std::find(m_workers.begin(), m_workers.end(), this_worker));
        m_required_workers++;
        m_shut_down_cv.notify_all();
    }));
}