tb_size_t tb_list_insert_prev(tb_list_ref_t self, tb_size_t itor, tb_cpointer_t data) { // check tb_list_t* list = (tb_list_t*)self; tb_assert_and_check_return_val(list && list->element.dupl && list->pool, 0); // full? tb_assert_and_check_return_val(tb_list_size(self) < tb_list_maxn(self), tb_iterator_tail(self)); // the node tb_list_entry_ref_t node = (tb_list_entry_ref_t)itor; tb_assert_and_check_return_val(node, tb_iterator_tail(self)); // make entry tb_list_entry_ref_t entry = (tb_list_entry_ref_t)tb_fixed_pool_malloc(list->pool); tb_assert_and_check_return_val(entry, tb_iterator_tail(self)); // init entry data list->element.dupl(&list->element, (tb_pointer_t)(((tb_list_entry_t*)entry) + 1), data); // insert it tb_list_entry_insert_prev(&list->head, node, entry); // ok return (tb_size_t)entry; }
static tb_void_t tb_lo_scheduler_make_ready(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_t* coroutine) { // check tb_assert(scheduler && coroutine); // mark ready state tb_lo_core_state_set(coroutine, TB_STATE_READY); // insert this coroutine to ready coroutines if (scheduler->running) { // .. -> coroutine(inserted) -> running -> .. tb_list_entry_insert_prev(&scheduler->coroutines_ready, &scheduler->running->entry, &coroutine->entry); } else { // .. last -> coroutine(inserted) tb_list_entry_insert_tail(&scheduler->coroutines_ready, &coroutine->entry); } }