tb_void_t tb_demo_small_allocator_free2() { // done tb_allocator_ref_t small_allocator = tb_null; do { // init small allocator small_allocator = tb_small_allocator_init(tb_null); tb_assert_and_check_break(small_allocator); // make data tb_pointer_t data = tb_allocator_malloc(small_allocator, 10); tb_assert_and_check_break(data); // exit data tb_allocator_free(small_allocator, data); tb_allocator_free(small_allocator, data); #ifdef __tb_debug__ // dump small_allocator tb_allocator_dump(small_allocator); #endif } while (0); // exit small allocator if (small_allocator) tb_allocator_exit(small_allocator); small_allocator = tb_null; }
tb_void_t tb_pool_exit(tb_pool_ref_t pool) { // check tb_pool_impl_t* impl = (tb_pool_impl_t*)pool; tb_assert_and_check_return(impl); // uses allocator? if (impl->allocator) { // exit it tb_allocator_free(impl->allocator, impl); return ; } // enter tb_spinlock_enter(&impl->lock); // exit small pool if (impl->small_pool) tb_small_pool_exit(impl->small_pool); impl->small_pool = tb_null; // leave tb_spinlock_leave(&impl->lock); // exit lock tb_spinlock_exit(&impl->lock); // exit pool if (impl->large_pool) tb_large_pool_free(impl->large_pool, impl); }
tb_void_t tb_demo_small_allocator_perf() { // done tb_allocator_ref_t small_allocator = tb_null; tb_allocator_ref_t large_allocator = tb_null; do { // init small allocator small_allocator = tb_small_allocator_init(tb_null); tb_assert_and_check_break(small_allocator); // init large allocator large_allocator = tb_large_allocator_init(tb_null, 0); tb_assert_and_check_break(large_allocator); // make data list tb_size_t maxn = 100000; tb_pointer_t* list = (tb_pointer_t*)tb_allocator_large_nalloc0(large_allocator, maxn, sizeof(tb_pointer_t), tb_null); tb_assert_and_check_break(list); // done __tb_volatile__ tb_size_t indx = 0; __tb_volatile__ tb_hong_t time = tb_mclock(); __tb_volatile__ tb_size_t rand = 0xbeaf; for (indx = 0; indx < maxn; indx++) { // make data list[indx] = tb_allocator_malloc0(small_allocator, (rand & 3071) + 1); tb_assert_and_check_break(list[indx]); // make rand rand = (rand * 10807 + 1) & 0xffffffff; // re-make data if (!(indx & 31)) { list[indx] = tb_allocator_ralloc(small_allocator, list[indx], (rand & 3071) + 1); tb_assert_and_check_break(list[indx]); } // free data __tb_volatile__ tb_size_t size = rand & 15; if (size > 5 && indx) { size -= 5; while (size--) { // the free index tb_size_t free_indx = rand % indx; // free it if (list[free_indx]) tb_allocator_free(small_allocator, list[free_indx]); list[free_indx] = tb_null; } } } time = tb_mclock() - time; #ifdef __tb_debug__ // dump small_allocator tb_allocator_dump(small_allocator); #endif // trace tb_trace_i("time: %lld ms", time); // clear small_allocator tb_allocator_clear(small_allocator); // exit list tb_allocator_large_free(large_allocator, list); } while (0); // exit small allocator if (small_allocator) tb_allocator_exit(small_allocator); small_allocator = tb_null; // exit large allocator if (large_allocator) tb_allocator_exit(large_allocator); large_allocator = tb_null; }