📄 erl_alloc_util.c
字号:
res = THE_NON_VALUE; if (!allctr) { if (print_to_p) erts_print(*print_to_p, print_to_arg, "false\n"); if (szp) *szp = 0; return am_false; }#ifdef USE_THREADS if (allctr->thread_safe) erts_mtx_lock(&allctr->mutex);#endif if (hpp || szp) ensure_atoms_initialized(allctr); /* Update sbc values not continously updated */ allctr->sbcs.blocks.curr.no = allctr->sbcs.curr_mseg.no + allctr->sbcs.curr_sys_alloc.no; allctr->sbcs.blocks.max.no = allctr->sbcs.max.no; update_max_ever_values(&allctr->mbcs); update_max_ever_values(&allctr->sbcs); if (print_to_p) { erts_print(*print_to_p, print_to_arg, "versions: %s %s\n", allctr->vsn_str, ERTS_ALCU_VSN_STR); } sett = info_options(allctr, print_to_p, print_to_arg, hpp, szp); mbcs = info_carriers(allctr, &allctr->mbcs, "mbcs ", print_to_p, print_to_arg, hpp, szp); sbcs = info_carriers(allctr, &allctr->sbcs, "sbcs ", print_to_p, print_to_arg, hpp, szp); calls = info_calls(allctr, print_to_p, print_to_arg, hpp, szp); if (hpp || szp) { res = NIL; add_2tup(hpp, szp, &res, am.calls, calls); add_2tup(hpp, szp, &res, am.sbcs, sbcs); add_2tup(hpp, szp, &res, am.mbcs, mbcs); add_2tup(hpp, szp, &res, am.options, sett); add_3tup(hpp, szp, &res, am.versions, bld_string(hpp, szp, allctr->vsn_str), bld_string(hpp, szp, ERTS_ALCU_VSN_STR));; } if (begin_max_period) { reset_max_values(&allctr->mbcs); reset_max_values(&allctr->sbcs); }#ifdef USE_THREADS if (allctr->thread_safe) erts_mtx_unlock(&allctr->mutex);#endif return res;}/* ----------------------------------------------------------------------- */static ERTS_INLINE void *do_erts_alcu_alloc(ErtsAlcType_t type, void *extra, Uint size){ Allctr_t *allctr = (Allctr_t *) extra; void *res; ASSERT(initialized); ASSERT(allctr);#if ALLOC_ZERO_EQ_NULL if (!size) return NULL;#endif INC_CC(allctr->calls.this_alloc); if (size >= allctr->sbc_threshold) { Block_t *blk = create_carrier(allctr, size, CFLG_SBC); res = blk ? BLK2UMEM(blk) : NULL; } else res = mbc_alloc(allctr, size); DEBUG_CHECK_ALIGNMENT(res); return res;}void *erts_alcu_alloc(ErtsAlcType_t type, void *extra, Uint size){ return do_erts_alcu_alloc(type, extra, size);}#ifdef USE_THREADSvoid *erts_alcu_alloc_ts(ErtsAlcType_t type, void *extra, Uint size){ Allctr_t *allctr = (Allctr_t *) extra; void *res; erts_mtx_lock(&allctr->mutex); res = do_erts_alcu_alloc(type, extra, size); erts_mtx_unlock(&allctr->mutex); return res;}#ifdef ERTS_ALC_THR_SPEC_ALLOCSvoid *erts_alcu_alloc_thr_spec(ErtsAlcType_t type, void *unused, Uint size){ void *vallctr = erts_tsd_get(erts_allctr_thr_spec[ERTS_ALC_T2A(T)].key); if (!vallctr) { vallctr = (*erts_allctr_thr_spec[ERTS_ALC_T2A(type)].start_default)(); if (!vallctr) return NULL; } return do_erts_alcu_alloc(type, vallctr, size);}#endif#endif/* ------------------------------------------------------------------------- */static ERTS_INLINE voiddo_erts_alcu_free(ErtsAlcType_t type, void *extra, void *p){ Allctr_t *allctr = (Allctr_t *) extra; ASSERT(initialized); ASSERT(allctr); if (p) { Block_t *blk; INC_CC(allctr->calls.this_free); blk = UMEM2BLK(p); if (IS_SBC_BLK(blk)) destroy_carrier(allctr, blk); else mbc_free(allctr, p); }}void erts_alcu_free(ErtsAlcType_t type, void *extra, void *p){ do_erts_alcu_free(type, extra, p);}#ifdef USE_THREADSvoiderts_alcu_free_ts(ErtsAlcType_t type, void *extra, void *p){ Allctr_t *allctr = (Allctr_t *) extra; erts_mtx_lock(&allctr->mutex); do_erts_alcu_free(type, extra, p); erts_mtx_unlock(&allctr->mutex);}#ifdef ERTS_ALC_THR_SPEC_ALLOCSvoiderts_alcu_free_thr_spec(ErtsAlcType_t type, void *unused, void *p){ void *vallctr = erts_tsd_get(erts_allctr_thr_spec[ERTS_ALC_T2A(type)].key); ASSERT(vallctr); do_erts_alcu_free(type, vallctr, p);}#endif#endif/* ------------------------------------------------------------------------- */static ERTS_INLINE void *do_erts_alcu_realloc(ErtsAlcType_t type, void *extra, void *p, Uint size){ Allctr_t *allctr = (Allctr_t *) extra; Block_t *blk; void *res; ASSERT(initialized); ASSERT(allctr); if (!p) { res = do_erts_alcu_alloc(type, extra, size); INC_CC(allctr->calls.this_realloc); DEC_CC(allctr->calls.this_alloc); return res; }#if ALLOC_ZERO_EQ_NULL if (!size) { ASSERT(p); do_erts_alcu_free(type, extra, p); INC_CC(allctr->calls.this_realloc); DEC_CC(allctr->calls.this_free); return NULL; }#endif INC_CC(allctr->calls.this_realloc); blk = UMEM2BLK(p); if (size < allctr->sbc_threshold) { if (IS_MBC_BLK(blk)) res = mbc_realloc(allctr, p, size); else { Uint used_sz = SBC_HDR_SZ + ABLK_HDR_SZ + size; Uint crr_sz;#if HAVE_ERTS_MSEG if (IS_SYS_ALLOC_CARRIER(BLK2SBC(blk)))#endif crr_sz = SYS_ALLOC_CARRIER_CEILING(used_sz);#if HAVE_ERTS_MSEG else crr_sz = MSEG_UNIT_CEILING(used_sz);#endif if ((100*(crr_sz - used_sz))/crr_sz < allctr->sbc_move_threshold) /* Data won't be copied into a new carrier... */ goto do_carrier_resize; res = mbc_alloc(allctr, size); if (res) { sys_memcpy((void*) res, (void*) p, MIN(BLK_SZ(blk) - ABLK_HDR_SZ, size)); destroy_carrier(allctr, blk); } } } else { Block_t *new_blk; if(IS_SBC_BLK(blk)) { do_carrier_resize: new_blk = resize_carrier(allctr, blk, size, CFLG_SBC); res = new_blk ? BLK2UMEM(new_blk) : NULL; } else { new_blk = create_carrier(allctr, size, CFLG_SBC); if (new_blk) { res = BLK2UMEM(new_blk); sys_memcpy((void *) res, (void *) p, MIN(BLK_SZ(blk) - ABLK_HDR_SZ, size)); mbc_free(allctr, p); } else res = NULL; } } DEBUG_CHECK_ALIGNMENT(res); return res;}void *erts_alcu_realloc(ErtsAlcType_t type, void *extra, void *p, Uint size){ return do_erts_alcu_realloc(type, extra, p, size);}#ifdef USE_THREADSvoid *erts_alcu_realloc_ts(ErtsAlcType_t type, void *extra, void *ptr, Uint size){ Allctr_t *allctr = (Allctr_t *) extra; void *res; erts_mtx_lock(&allctr->mutex); res = do_erts_alcu_realloc(type, extra, ptr, size); erts_mtx_unlock(&allctr->mutex); return res;}#ifdef ERTS_ALC_THR_SPEC_ALLOCSvoid *erts_alcu_realloc_thr_spec(ErtsAlcType_t type, void *unused, void *ptr, Uint size){ void *vallctr = erts_tsd_get(erts_allctr_thr_spec[ERTS_ALC_T2A(T)].key); if (!vallctr) { vallctr = (*erts_allctr_thr_spec[ERTS_ALC_T2A(type)].start_default)(); if (!vallctr) return NULL; } return do_erts_alcu_realloc(type, vallctr, ptr, size);}#endif#endif/* ------------------------------------------------------------------------- */interts_alcu_start(Allctr_t *allctr, AllctrInit_t *init){ /* erts_alcu_start assumes that allctr has been zeroed */ if (!initialized) goto error;#if HAVE_ERTS_MSEG { ErtsMsegOpt_t mseg_opt = ERTS_MSEG_DEFAULT_OPT_INITIALIZER; sys_memcpy((void *) &allctr->mseg_opt, (void *) &mseg_opt, sizeof(ErtsMsegOpt_t)); }#endif allctr->name_prefix = init->name_prefix; if (!allctr->name_prefix) goto error; allctr->alloc_no = init->alloc_no; if (allctr->alloc_no < ERTS_ALC_A_MIN || ERTS_ALC_A_MAX < allctr->alloc_no) allctr->alloc_no = ERTS_ALC_A_INVALID; if (!allctr->vsn_str) goto error; allctr->name.alloc = THE_NON_VALUE; allctr->name.realloc = THE_NON_VALUE; allctr->name.free = THE_NON_VALUE; allctr->main_carrier_size = init->mmbcs; allctr->sbc_threshold = init->sbct;#if HAVE_ERTS_MSEG allctr->mseg_opt.abs_shrink_th = init->asbcst; allctr->mseg_opt.rel_shrink_th = init->rsbcst;#endif allctr->sbc_move_threshold = init->rsbcmt;#if HAVE_ERTS_MSEG allctr->max_mseg_sbcs = init->mmsbc; allctr->max_mseg_mbcs = init->mmmbc;#endif allctr->largest_mbc_size = MAX(init->lmbcs, init->smbcs); allctr->smallest_mbc_size = init->smbcs; allctr->mbc_growth_stages = MAX(1, init->mbcgs); if (allctr->min_block_size < ABLK_HDR_SZ) goto error; allctr->min_block_size = UNIT_CEILING(allctr->min_block_size + sizeof(Uint));#if HAVE_ERTS_MSEG if (allctr->mseg_opt.abs_shrink_th > ~((Uint) 0) / 100) allctr->mseg_opt.abs_shrink_th = ~((Uint) 0) / 100;#endif#ifdef USE_THREADS if (init->ts) { allctr->thread_safe = 1; erts_mtx_init_x(&allctr->mutex, "alcu_allocator", make_small(allctr->alloc_no)); erts_mtx_set_forksafe(&allctr->mutex); }#endif if(!allctr->get_free_block || !allctr->link_free_block || !allctr->unlink_free_block || !allctr->info_options) goto error; if (!allctr->get_next_mbc_size) allctr->get_next_mbc_size = get_next_mbc_size; if (allctr->mbc_header_size < sizeof(Carrier_t)) goto error; allctr->mbc_header_size = (UNIT_CEILING(allctr->mbc_header_size + FBLK_FTR_SZ + ABLK_HDR_SZ) - ABLK_HDR_SZ); if (allctr->main_carrier_size) { Block_t *blk; blk = create_carrier(allctr, allctr->main_carrier_size, CFLG_MBC | CFLG_FORCE_SIZE | CFLG_FORCE_SYS_ALLOC | CFLG_MAIN_CARRIER); if (!blk) goto error; (*allctr->link_free_block)(allctr, blk); HARD_CHECK_BLK_CARRIER(allctr, blk); } return 1; error:#ifdef USE_THREADS if (allctr->thread_safe) erts_mtx_destroy(&allctr->mutex);#endif return 0;}/* ------------------------------------------------------------------------- */voiderts_alcu_stop(Allctr_t *allctr){ allctr->stopped = 1; while (allctr->sbc_list.first) destroy_carrier(allctr, SBC2BLK(allctr->sbc_list.first)); while (allctr->mbc_list.first) destroy_carrier(allctr, MBC2FBLK(allctr, allctr->mbc_list.first));#ifdef USE_THREADS if (allctr->thread_safe) erts_mtx_destroy(&allctr->mutex);#endif}/* ------------------------------------------------------------------------- */voiderts_alcu_init(AlcUInit_t *init){#if HAVE_ERTS_MSEG mseg_unit_size = erts_mseg_unit_size(); if (mseg_unit_size % sizeof(Unit_t)) /* A little paranoid... */ erl_exit(-1, "Mseg unit size (%d) not evenly divideble by " "internal unit size of alloc_util (%d)\n", mseg_unit_size, sizeof(Unit_t)); max_mseg_carriers = init->mmc; sys_alloc_carrier_size = MSEG_UNIT_CEILING(init->ycs);#else /* #if HAVE_ERTS_MSEG */ sys_alloc_carrier_size = ((init->ycs + 4095) / 4096) * 4096;#endif#ifdef DEBUG carrier_alignment = sizeof(Unit_t);#endif erts_mtx_init(&init_atoms_mtx, "alcu_init_atoms"); atoms_initialized = 0; initialized = 1;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * NOTE: erts_alcu_test() is only supposed to be used for testing. * * * * Keep alloc_SUITE_data/allocator_test.h updated if changes are made * * to erts_alcu_test() *\* */unsigned longerts_alcu_test(unsigned long op, unsigned long a1, unsigned long a2){ switch (op) { case 0x000: return (unsigned long) BLK_SZ((Block_t *) a1); case 0x001: return (unsigned long) BLK_UMEM_SZ((Block_t *) a1); case 0x002: return (unsigned long) IS_PREV_BLK_FREE((Block_t *) a1); case 0x003: return (unsigned long) IS_FREE_BLK((Block_t *) a1); case 0x004: return (unsigned long) IS_LAST_BLK((Block_t *) a1); case 0x005: return (unsigned long) UMEM2BLK((void *) a1); case 0x006: return (unsigned long) BLK2UMEM((Block_t *) a1); case 0x007: return (unsigned long) IS_SB_CARRIER((Carrier_t *) a1); case 0x008: return (unsigned long) IS_SBC_BLK((Block_t *) a1); case 0x009: return (unsigned long) IS_MB_CARRIER((Carrier_t *) a1); case 0x00a: return (unsigned long) IS_MSEG_CARRIER((Carrier_t *) a1); case 0x00b: return (unsigned long) CARRIER_SZ((Carrier_t *) a1); case 0x00c: return (unsigned long) SBC2BLK((Carrier_t *) a1); case 0x00d: return (unsigned long) BLK2SBC((Block_t *) a1); case 0x00e: return (un
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -