tb_event_ref_t tb_event_init() { return (tb_event_ref_t)tb_semaphore_init(0); }
/* ////////////////////////////////////////////////////////////////////////////////////// * interfaces */ static tb_aicp_ptor_impl_t* tb_aiop_ptor_init(tb_aicp_impl_t* aicp) { // check tb_assert_and_check_return_val(aicp && aicp->maxn, tb_null); // done tb_bool_t ok = tb_false; tb_aiop_ptor_impl_t* impl = tb_null; do { // make ptor impl = tb_malloc0_type(tb_aiop_ptor_impl_t); tb_assert_and_check_break(impl); // init base impl->base.aicp = aicp; impl->base.step = sizeof(tb_aiop_aico_t); impl->base.kill = tb_aiop_ptor_kill; impl->base.exit = tb_aiop_ptor_exit; impl->base.addo = tb_aiop_ptor_addo; impl->base.kilo = tb_aiop_ptor_kilo; impl->base.post = tb_aiop_ptor_post; impl->base.loop_spak = tb_aiop_ptor_spak; // init lock if (!tb_spinlock_init(&impl->lock)) break; // init wait impl->wait = tb_semaphore_init(0); tb_assert_and_check_break(impl->wait); // init aiop impl->aiop = tb_aiop_init(aicp->maxn); tb_assert_and_check_break(impl->aiop); // check tb_assert_and_check_break(tb_aiop_have(impl->aiop, TB_AIOE_CODE_EALL | TB_AIOE_CODE_ONESHOT)); // init spak impl->spak[0] = tb_queue_init((aicp->maxn >> 4) + 16, tb_item_func_mem(sizeof(tb_aice_t), tb_null, tb_null)); impl->spak[1] = tb_queue_init((aicp->maxn >> 4) + 16, tb_item_func_mem(sizeof(tb_aice_t), tb_null, tb_null)); tb_assert_and_check_break(impl->spak[0] && impl->spak[1]); // init file if (!tb_aicp_file_init(impl)) break; // init list impl->maxn = (aicp->maxn >> 4) + 16; impl->list = tb_nalloc0(impl->maxn, sizeof(tb_aioe_t)); tb_assert_and_check_break(impl->list); // init timer and using cache time impl->timer = tb_timer_init((aicp->maxn >> 4) + 16, tb_true); tb_assert_and_check_break(impl->timer); // init ltimer and using cache time impl->ltimer = tb_ltimer_init(aicp->maxn, TB_LTIMER_TICK_S, tb_true); tb_assert_and_check_break(impl->ltimer); // register lock profiler #ifdef TB_LOCK_PROFILER_ENABLE tb_lock_profiler_register(tb_lock_profiler(), (tb_pointer_t)&impl->lock, "aicp_aiop"); #endif // init loop impl->loop = tb_thread_init(tb_null, tb_aiop_spak_loop, impl, 0); tb_assert_and_check_break(impl->loop); // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit it if (impl) tb_aiop_ptor_exit((tb_aicp_ptor_impl_t*)impl); return tb_null; } // ok? return (tb_aicp_ptor_impl_t*)impl; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_platform_semaphore_main(tb_int_t argc, tb_char_t** argv) { // init loop tb_demo_loop_t loop[10]; tb_size_t i = 0; tb_size_t n = tb_arrayn(loop); for (i = 0; i < n; i++) { // init semaphore loop[i].semaphore = tb_semaphore_init(0); tb_assert_and_check_break(loop[i].semaphore); // post semaphore tb_semaphore_post(loop[i].semaphore, 1); // init index loop[i].index = i; // init stoped loop[i].bstoped = 0; // init loop loop[i].loop = tb_thread_init(tb_null, tb_demo_loop, loop + i, 0); tb_assert_and_check_break(loop[i].loop); } // check tb_assert_and_check_return_val(i == n, 0); // wait some time tb_msleep(100); // post tb_char_t line[256]; tb_bool_t stop = tb_false; while (!stop) { // get line tb_char_t const* p = tb_demo_gets(line, sizeof(line)); tb_assert_and_check_break(p); // trace tb_trace_i("post: %s", p); // done while (*p && !stop) { tb_char_t ch = *p++; switch (ch) { case 'q': stop = tb_true; break; default: { if (ch >= '0' && ch <= '9') { // the index tb_size_t index = ch - '0'; tb_assert_and_check_break(index < n && index == loop[index].index); // post semaphore if (loop[index].semaphore) tb_semaphore_post(loop[index].semaphore, 1); } } break; } } } // post loop for (i = 0; i < n; i++) { // quit thread tb_atomic_set(&loop[i].bstoped, 1); // post semaphore if (loop[i].semaphore) tb_semaphore_post(loop[i].semaphore, 1); } // exit loop for (i = 0; i < n; i++) { // exit loop if (loop[i].loop) { // wait it if (!tb_thread_wait(loop[i].loop, 5000)) { // trace tb_trace_e("wait loop[%lu]: timeout", i); } // exit it tb_thread_exit(loop[i].loop); } // exit semaphore if (loop[i].semaphore) tb_semaphore_exit(loop[i].semaphore); } // exit tb_trace_i("exit"); return 0; }
tb_thread_pool_ref_t tb_thread_pool_init(tb_size_t worker_maxn, tb_size_t stack) { // done tb_bool_t ok = tb_false; tb_thread_pool_impl_t* impl = tb_null; do { // make pool impl = tb_malloc0_type(tb_thread_pool_impl_t); tb_assert_and_check_break(impl); // init lock if (!tb_spinlock_init(&impl->lock)) break; // computate the default worker maxn if be zero if (!worker_maxn) worker_maxn = tb_processor_count() << 2; tb_assert_and_check_break(worker_maxn); // init thread stack impl->stack = stack; // init workers impl->worker_size = 0; impl->worker_maxn = worker_maxn; // init jobs pool impl->jobs_pool = tb_fixed_pool_init(tb_null, TB_THREAD_POOL_JOBS_POOL_GROW, sizeof(tb_thread_pool_job_t), tb_null, tb_null, tb_null); tb_assert_and_check_break(impl->jobs_pool); // init jobs urgent tb_list_entry_init(&impl->jobs_urgent, tb_thread_pool_job_t, entry, tb_null); // init jobs waiting tb_list_entry_init(&impl->jobs_waiting, tb_thread_pool_job_t, entry, tb_null); // init jobs pending tb_list_entry_init(&impl->jobs_pending, tb_thread_pool_job_t, entry, tb_null); // init semaphore impl->semaphore = tb_semaphore_init(0); tb_assert_and_check_break(impl->semaphore); // register lock profiler #ifdef TB_LOCK_PROFILER_ENABLE tb_lock_profiler_register(tb_lock_profiler(), (tb_pointer_t)&impl->lock, TB_TRACE_MODULE_NAME); #endif // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit it if (impl) tb_thread_pool_exit((tb_thread_pool_ref_t)impl); impl = tb_null; } // ok? return (tb_thread_pool_ref_t)impl; }