Beispiel #1
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * 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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * 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;
}
Beispiel #4
0
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;
}