/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_small_pool_ref_t tb_small_pool_init(tb_large_pool_ref_t large_pool) { // done tb_bool_t ok = tb_false; tb_small_pool_impl_t* impl = tb_null; do { // using the default large pool if (!large_pool) large_pool = tb_large_pool(); tb_assert_and_check_break(large_pool); // make pool impl = (tb_small_pool_impl_t*)tb_large_pool_malloc0(large_pool, sizeof(tb_small_pool_impl_t), tb_null); tb_assert_and_check_break(impl); // init pool impl->large_pool = large_pool; // ok ok = tb_true; } while (0); // failed? if (!ok) { if (impl) tb_small_pool_exit((tb_small_pool_ref_t)impl); impl = tb_null; } // ok? return (tb_small_pool_ref_t)impl; }
tb_pool_ref_t tb_pool_init(tb_allocator_ref_t allocator, tb_large_pool_ref_t large_pool) { // done tb_bool_t ok = tb_false; tb_pool_impl_t* impl = tb_null; do { // uses allocator? if (allocator) { // make pool impl = (tb_pool_impl_t*)tb_allocator_malloc0(allocator, sizeof(tb_pool_impl_t)); tb_assert_and_check_break(impl); // save allocator impl->allocator = allocator; // ok ok = tb_true; break; } // using the default large pool if (!large_pool) large_pool = tb_large_pool(); tb_assert_and_check_break(large_pool); // make pool impl = (tb_pool_impl_t*)tb_large_pool_malloc0(large_pool, sizeof(tb_pool_impl_t), tb_null); tb_assert_and_check_break(impl); // init lock if (!tb_spinlock_init(&impl->lock)) break; // init pool impl->large_pool = large_pool; impl->small_pool = tb_small_pool_init(large_pool); tb_assert_and_check_break(impl->small_pool); // 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) { if (impl) tb_pool_exit((tb_pool_ref_t)impl); impl = tb_null; } // ok? return (tb_pool_ref_t)impl; }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_fixed_pool_ref_t tb_fixed_pool_init_(tb_large_pool_ref_t large_pool, tb_size_t slot_size, tb_size_t item_size, tb_bool_t for_small_pool, tb_fixed_pool_item_init_func_t item_init, tb_fixed_pool_item_exit_func_t item_exit, tb_cpointer_t priv) { // check tb_assert_and_check_return_val(item_size, tb_null); // done tb_bool_t ok = tb_false; tb_fixed_pool_impl_t* impl = tb_null; do { // using the default large pool if (!large_pool) large_pool = tb_large_pool(); tb_assert_and_check_break(large_pool); // make pool impl = (tb_fixed_pool_impl_t*)tb_large_pool_malloc0(large_pool, sizeof(tb_fixed_pool_impl_t), tb_null); tb_assert_and_check_break(impl); // init pool impl->large_pool = large_pool; impl->slot_size = slot_size? slot_size : (tb_page_size() >> 4); impl->item_size = item_size; impl->func_init = item_init; impl->func_exit = item_exit; impl->func_priv = priv; impl->for_small_pool = for_small_pool; tb_assert_and_check_break(impl->slot_size); // init partial slots tb_list_entry_init(&impl->partial_slots, tb_fixed_pool_slot_t, entry, tb_null); // init full slots tb_list_entry_init(&impl->full_slots, tb_fixed_pool_slot_t, entry, tb_null); // ok ok = tb_true; } while (0); // failed? if (!ok) { // exit it if (impl) tb_fixed_pool_exit((tb_fixed_pool_ref_t)impl); impl = tb_null; } // ok? return (tb_fixed_pool_ref_t)impl; }
tb_pointer_t tb_small_pool_malloc0_(tb_small_pool_ref_t pool, tb_size_t size __tb_debug_decl__) { // check tb_small_pool_impl_t* impl = (tb_small_pool_impl_t*)pool; tb_assert_and_check_return_val(impl && impl->large_pool && size, tb_null); tb_assert_and_check_return_val(size <= TB_SMALL_POOL_DATA_SIZE_MAXN, tb_null); // disable small pool for debug #ifdef TB_SMALL_POOL_DISABLE return tb_large_pool_malloc0(impl->large_pool, size, tb_null); #endif // done tb_pointer_t data = tb_null; do { // the fixed pool tb_fixed_pool_ref_t fixed_pool = tb_small_pool_find_fixed(impl, size); tb_assert_and_check_break(fixed_pool); // done data = tb_fixed_pool_malloc0_(fixed_pool __tb_debug_args__); tb_assert_and_check_break(data); // the data head tb_pool_data_head_t* data_head = &(((tb_pool_data_head_t*)data)[-1]); tb_assert_abort(data_head->debug.magic == TB_POOL_DATA_MAGIC); #ifdef __tb_debug__ // fill the patch bytes if (data_head->size > size) tb_memset_((tb_byte_t*)data + size, TB_POOL_DATA_PATCH, data_head->size - size); #endif // update size data_head->size = size; } while (0); // check tb_assertf_abort(data, "malloc0(%lu) failed!", size); // ok? return data; }