static inline lagopus_result_t s_stop_callout_main_loop(void) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (s_is_stopped == false) { if (s_do_loop == true) { /* * Stop the main loop first. */ s_do_loop = false; mbar(); (void)lagopus_bbq_wakeup(&s_urgent_tsk_q, -1LL); s_lock_sched(); { while (s_is_stopped == false) { s_wait_sched(-1LL); } } s_unlock_sched(); ret = LAGOPUS_RESULT_OK; } else { ret = LAGOPUS_RESULT_OK; } } else { ret = LAGOPUS_RESULT_OK; } return ret; }
static inline lagopus_chrono_t s_do_sched(lagopus_callout_task_t t) { lagopus_result_t ret = -1LL; lagopus_result_t r; lagopus_callout_task_t e; s_lock_task_q(); { s_lock_task(t); { if (likely(t->m_is_in_timed_q == false)) { /* * Firstly (re-)compute the next exeution time of this * task. */ if (t->m_is_first == false && t->m_do_repeat == true) { t->m_next_abstime = t->m_last_abstime + t->m_interval_time; } else { WHAT_TIME_IS_IT_NOW_IN_NSEC(t->m_last_abstime); t->m_next_abstime = t->m_last_abstime + t->m_initial_delay_time; } /* * Then insert the task into the Q. */ e = TAILQ_FIRST(&s_chrono_tsk_q); if (e != NULL) { if (e->m_next_abstime > t->m_next_abstime) { TAILQ_INSERT_HEAD(&s_chrono_tsk_q, t, m_entry); } else { for (; e != NULL && e->m_next_abstime <= t->m_next_abstime; e = TAILQ_NEXT(e, m_entry)) { ; } if (e != NULL) { TAILQ_INSERT_BEFORE(e, t, m_entry); } else { TAILQ_INSERT_TAIL(&s_chrono_tsk_q, t, m_entry); } } } else { TAILQ_INSERT_TAIL(&s_chrono_tsk_q, t, m_entry); } (void)s_set_task_state_in_table(t, TASK_STATE_ENQUEUED); t->m_status = TASK_STATE_ENQUEUED; t->m_is_in_timed_q = true; ret = t->m_next_abstime; /* * Fianlly wake the master scheduler. */ lagopus_msg_debug(4, "wake the master scheduler up.\n"); /* * TODO * * Re-optimize forcible wake up by timed task submission * timing and times. See also * callout.c:s_start_callout_main_loop() */ r = lagopus_bbq_wakeup(&s_urgent_tsk_q, 0LL); if (unlikely(r != LAGOPUS_RESULT_OK)) { lagopus_perror(r); lagopus_msg_error("can't wake the callout task master " "scheduler up.\n"); } } } s_unlock_task(t); } s_unlock_task_q(); return ret; }