【WIP】Seastar框架学习

初始化流程

  • create_scheduling_group: 创建sg(调度组)
  • init_scheduling_group: 初始化每个sg,在每个sg内会创建task队列

主要结构体

task队列
  • 固定长度:长度为cores数量;
    boost::container::static_vector<std::unique_ptr<task_queue>, max_scheduling_groups()> _task_queues;
    task_queue_list _active_task_queues;
    task_queue_list _activating_task_queues;

add_task

    void add_task(task* t) noexcept {
        auto sg = t->group();
        auto* q = _task_queues[sg._id].get();
        bool was_empty = q->_q.empty();
        q->_q.push_back(std::move(t));
#ifdef SEASTAR_SHUFFLE_TASK_QUEUE
        shuffle(q->_q.back(), *q);
#endif
        if (was_empty) {
            activate(*q);
        }
    }

往task队列里添加任务:

void schedule(task* t) noexcept {
    engine().add_task(t);
}

void schedule_urgent(task* t) noexcept {
    engine().add_urgent_task(t);
}

用户层api使用:

场景1:yield方法
  • yield()函数会将task通过schedule方法添加到task队列中,并返回了future,等待调度执行;
future<>
yield() noexcept {
    memory::scoped_critical_alloc_section _;
    auto tsk = make_task([] {});
    schedule(tsk);
    return tsk->get_future();
}
场景2:在future中的使用

在future函数中,make_ready()方法会调用schedule函数添加_task到task队列中:

template <promise_base::urgent Urgent>
void promise_base::make_ready() noexcept {
    if (_task) {
        if (Urgent == urgent::yes) {
            ::seastar::schedule_urgent(std::exchange(_task, nullptr));
        } else {
            ::seastar::schedule(std::exchange(_task, nullptr));
        }
    }
}

make_ready是怎么使用的呢?

  • future和promise是相关关联的,即使其中一个或者两个都moved;
  • set_value或者set_exception调用时,future会变得ready,然后continuation会被attach到该future上,该future就被run起来;
    /// \brief Gets the promise's associated future.
    ///
    /// The future and promise will be remember each other, even if either or
    /// both are moved.  When \c set_value() or \c set_exception() are called
    /// on the promise, the future will be become ready, and if a continuation
    /// was attached to the future, it will run.
    future<T SEASTAR_ELLIPSIS> get_future() noexcept;

	template<typename T>
	template<typename Func>
	SEASTAR_CONCEPT( requires std::invocable<Func> )
	void futurize<T>::satisfy_with_result_of(promise_base_with_type&& pr, Func&& func) {
	    using ret_t = decltype(func());
	    if constexpr (std::is_void_v<ret_t>) {
	        func();
	        pr.set_value();
	    } else if constexpr (is_future<ret_t>::value) {
	        func().forward_to(std::move(pr));
	    } else {
	        pr.set_value(func());
	    }
	}

任务的调度

void
reactor::run_some_tasks() {
    if (!have_more_tasks()) {
        return;
    }
    sched_print("run_some_tasks: start");
    reset_preemption_monitor();
    update_lowres_clocks();

    sched_clock::time_point t_run_completed = now();
    STAP_PROBE(seastar, reactor_run_tasks_start);
    _cpu_stall_detector->start_task_run(t_run_completed);
    do {
        auto t_run_started = t_run_completed;
        insert_activating_task_queues();
        // 从r
        task_queue* tq = pop_active_task_queue(t_run_started);
        sched_print("running tq {} {}", (void*)tq, tq->_name);
        tq->_current = true;
        _last_vruntime = std::max(tq->_vruntime, _last_vruntime);
        // 真正的开始run task
        run_tasks(*tq);
        tq->_current = false;
        t_run_completed = now();
        auto delta = t_run_completed - t_run_started;
        account_runtime(*tq, delta);
        sched_print("run complete ({} {}); time consumed {} usec; final vruntime {} empty {}",
                (void*)tq, tq->_name, delta / 1us, tq->_vruntime, tq->_q.empty());
        tq->_ts = t_run_completed;
        if (!tq->_q.empty()) {
            insert_active_task_queue(tq);
        } else {
            tq->_active = false;
        }
    } while (have_more_tasks() && !need_preempt());
    _cpu_stall_detector->end_task_run(t_run_completed);
    STAP_PROBE(seastar, reactor_run_tasks_end);
    *internal::current_scheduling_group_ptr() = default_scheduling_group(); // Prevent inheritance from last group run
    sched_print("run_some_tasks: end");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值