📄 erl_alloc_util.c
字号:
Carrier_t *crr; Uint blk_sz, bcrr_sz, crr_sz;#if HAVE_ERTS_MSEG int have_tried_sys_alloc = 0, have_tried_mseg = 0;#endif#ifdef DEBUG int is_mseg = 0;#endif ASSERT((flags & CFLG_SBC && !(flags & CFLG_MBC)) || (flags & CFLG_MBC && !(flags & CFLG_SBC))); blk_sz = UMEMSZ2BLKSZ(allctr, umem_sz);#if HAVE_ERTS_MSEG if (flags & CFLG_FORCE_SYS_ALLOC) goto try_sys_alloc; if (flags & CFLG_FORCE_MSEG) goto try_mseg; if (erts_mseg_no() >= max_mseg_carriers) goto try_sys_alloc; if (flags & CFLG_SBC) { if (allctr->sbcs.curr_mseg.no >= allctr->max_mseg_sbcs) goto try_sys_alloc; } else { if (allctr->mbcs.curr_mseg.no >= allctr->max_mseg_mbcs) goto try_sys_alloc; } try_mseg: if (flags & CFLG_SBC) { crr_sz = blk_sz + SBC_HDR_SZ; } else { crr_sz = (*allctr->get_next_mbc_size)(allctr); if (crr_sz < allctr->mbc_header_size + blk_sz) crr_sz = allctr->mbc_header_size + blk_sz;#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG if (sizeof(Unit_t) == sizeof(Uint)) crr_sz += sizeof(Uint);#endif } crr_sz = MSEG_UNIT_CEILING(crr_sz); ASSERT(crr_sz % mseg_unit_size == 0); crr = (Carrier_t *) alcu_mseg_alloc(allctr, &crr_sz); if (!crr) { have_tried_mseg = 1; if (!(have_tried_sys_alloc || flags & CFLG_FORCE_MSEG)) goto try_sys_alloc; return NULL; }#ifdef DEBUG is_mseg = 1;#endif if (flags & CFLG_SBC) { SET_CARRIER_HDR(crr, crr_sz, SCH_MSEG|SCH_SBC); STAT_MSEG_SBC_ALLOC(allctr, crr_sz, blk_sz); goto sbc_final_touch; } else { SET_CARRIER_HDR(crr, crr_sz, SCH_MSEG|SCH_MBC); STAT_MSEG_MBC_ALLOC(allctr, crr_sz); goto mbc_final_touch; } try_sys_alloc:#endif /* #if HAVE_ERTS_MSEG */ if (flags & CFLG_SBC) { bcrr_sz = blk_sz + SBC_HDR_SZ; } else { bcrr_sz = allctr->mbc_header_size + blk_sz; if (!(flags & CFLG_MAIN_CARRIER) && bcrr_sz < allctr->smallest_mbc_size) bcrr_sz = allctr->smallest_mbc_size;#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG if (sizeof(Unit_t) == sizeof(Uint)) bcrr_sz += sizeof(Uint);#endif } crr_sz = (flags & CFLG_FORCE_SIZE ? UNIT_CEILING(bcrr_sz) : SYS_ALLOC_CARRIER_CEILING(bcrr_sz)); crr = (Carrier_t *) alcu_sys_alloc(allctr, crr_sz); if (!crr) { if (crr_sz > UNIT_CEILING(bcrr_sz)) { crr_sz = UNIT_CEILING(bcrr_sz); crr = (Carrier_t *) alcu_sys_alloc(allctr, crr_sz); } if (!crr) {#if HAVE_ERTS_MSEG have_tried_sys_alloc = 1; if (!(have_tried_mseg || flags & CFLG_FORCE_SYS_ALLOC)) goto try_mseg;#endif return NULL; } } if (flags & CFLG_SBC) { SET_CARRIER_HDR(crr, crr_sz, SCH_SYS_ALLOC|SCH_SBC); STAT_SYS_ALLOC_SBC_ALLOC(allctr, crr_sz, blk_sz);#if HAVE_ERTS_MSEG sbc_final_touch:#endif blk = SBC2BLK(crr); SET_SBC_BLK_FTR(((Uint *) blk)[-1]); SET_BLK_HDR(blk, blk_sz, SBH_THIS_ALLOCED|SBH_PREV_FREE|SBH_LAST_BLK); link_carrier(&allctr->sbc_list, crr); CHECK_1BLK_CARRIER(allctr, 1, is_mseg, crr, crr_sz, blk, blk_sz); } else { SET_CARRIER_HDR(crr, crr_sz, SCH_SYS_ALLOC|SCH_MBC); STAT_SYS_ALLOC_MBC_ALLOC(allctr, crr_sz);#if HAVE_ERTS_MSEG mbc_final_touch:#endif blk = MBC2FBLK(allctr, crr);#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG if (sizeof(Unit_t) == sizeof(Uint)) crr_sz -= sizeof(Uint);#endif blk_sz = UNIT_FLOOR(crr_sz - allctr->mbc_header_size); SET_MBC_BLK_FTR(((Uint *) blk)[-1]); SET_BLK_HDR(blk, blk_sz, SBH_THIS_FREE|SBH_PREV_FREE|SBH_LAST_BLK);#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG *((Carrier_t **) NXT_BLK(blk)) = crr;#endif if (flags & CFLG_MAIN_CARRIER) { ASSERT(!allctr->main_carrier); allctr->main_carrier = crr; } link_carrier(&allctr->mbc_list, crr);#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG if (sizeof(Unit_t) == sizeof(Uint)) crr_sz += sizeof(Uint);#endif CHECK_1BLK_CARRIER(allctr, 0, is_mseg, crr, crr_sz, blk, blk_sz);#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG if (sizeof(Unit_t) == sizeof(Uint)) crr_sz -= sizeof(Uint);#endif if (allctr->creating_mbc) (*allctr->creating_mbc)(allctr, crr); } DEBUG_SAVE_ALIGNMENT(crr); return blk;}static Block_t *resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, Uint flags){ Block_t *new_blk; Carrier_t *new_crr, *old_crr; Uint create_flags, old_crr_sz, old_blk_sz, new_blk_sz, new_crr_sz; Uint new_bcrr_sz; if (flags & CFLG_MBC) { ASSERT(0); return NULL; } ASSERT(flags & CFLG_SBC); create_flags = flags|CFLG_SBC; HARD_CHECK_BLK_CARRIER(allctr, old_blk); old_blk_sz = BLK_SZ(old_blk); old_crr = BLK2SBC(old_blk); old_crr_sz = CARRIER_SZ(old_crr); ASSERT(IS_SB_CARRIER(old_crr)); ASSERT(IS_SBC_BLK(old_blk)); new_blk_sz = UMEMSZ2BLKSZ(allctr, umem_sz);#if HAVE_ERTS_MSEG if (IS_MSEG_CARRIER(old_crr)) { STAT_MSEG_SBC_FREE(allctr, old_crr_sz, old_blk_sz); if (!(flags & CFLG_FORCE_SYS_ALLOC)) { new_crr_sz = new_blk_sz + SBC_HDR_SZ; new_crr_sz = MSEG_UNIT_CEILING(new_crr_sz); new_crr = (Carrier_t *) alcu_mseg_realloc(allctr, old_crr, old_crr_sz, &new_crr_sz); if (new_crr) { SET_CARRIER_SZ(new_crr, new_crr_sz); new_blk = SBC2BLK(new_crr); SET_BLK_SZ(new_blk, new_blk_sz); STAT_MSEG_SBC_ALLOC(allctr, new_crr_sz, new_blk_sz); relink_carrier(&allctr->sbc_list, new_crr); CHECK_1BLK_CARRIER(allctr, 1, 1, new_crr, new_crr_sz, new_blk, new_blk_sz); DEBUG_SAVE_ALIGNMENT(new_crr); return new_blk; } create_flags |= CFLG_FORCE_SYS_ALLOC; /* since mseg_realloc() failed */ } new_blk = create_carrier(allctr, umem_sz, create_flags); if (new_blk) { sys_memcpy((void *) BLK2UMEM(new_blk), (void *) BLK2UMEM(old_blk), MIN(new_blk_sz, old_blk_sz) - ABLK_HDR_SZ); unlink_carrier(&allctr->sbc_list, old_crr); alcu_mseg_dealloc(allctr, old_crr, old_crr_sz); } else { /* Old carrier unchanged; restore stat */ STAT_MSEG_SBC_ALLOC(allctr, old_crr_sz, old_blk_sz); } return new_blk; } else { if (!(flags & CFLG_FORCE_MSEG)) {#endif /* #if HAVE_ERTS_MSEG */ new_bcrr_sz = new_blk_sz + SBC_HDR_SZ; new_crr_sz = (flags & CFLG_FORCE_SIZE ? UNIT_CEILING(new_bcrr_sz) : SYS_ALLOC_CARRIER_CEILING(new_bcrr_sz)); new_crr = (Carrier_t *) alcu_sys_realloc(allctr, (void *) old_crr, new_crr_sz); if (new_crr) { sys_realloc_success: SET_CARRIER_SZ(new_crr, new_crr_sz); new_blk = SBC2BLK(new_crr); SET_BLK_SZ(new_blk, new_blk_sz); STAT_SYS_ALLOC_SBC_FREE(allctr, old_crr_sz, old_blk_sz); STAT_SYS_ALLOC_SBC_ALLOC(allctr, new_crr_sz, new_blk_sz); relink_carrier(&allctr->sbc_list, new_crr); CHECK_1BLK_CARRIER(allctr, 1, 0, new_crr, new_crr_sz, new_blk, new_blk_sz); DEBUG_SAVE_ALIGNMENT(new_crr); return new_blk; } else if (new_crr_sz > UNIT_CEILING(new_bcrr_sz)) { new_crr_sz = new_blk_sz + SBC_HDR_SZ; new_crr_sz = UNIT_CEILING(new_crr_sz); new_crr = (Carrier_t *) alcu_sys_realloc(allctr, (void *) old_crr, new_crr_sz); if (new_crr) goto sys_realloc_success; }#if !HAVE_ERTS_MSEG return NULL;#else create_flags |= CFLG_FORCE_MSEG; /* Since sys_realloc() failed */ } STAT_SYS_ALLOC_SBC_FREE(allctr, old_crr_sz, old_blk_sz); new_blk = create_carrier(allctr, umem_sz, create_flags); if (new_blk) { sys_memcpy((void *) BLK2UMEM(new_blk), (void *) BLK2UMEM(old_blk), MIN(new_blk_sz, old_blk_sz) - ABLK_HDR_SZ); unlink_carrier(&allctr->sbc_list, old_crr); alcu_sys_free(allctr, old_crr); } else { /* Old carrier unchanged; restore... */ STAT_SYS_ALLOC_SBC_ALLOC(allctr, old_crr_sz, old_blk_sz); } DEBUG_SAVE_ALIGNMENT(new_crr); return new_blk; }#endif}static voiddestroy_carrier(Allctr_t *allctr, Block_t *blk){ Uint crr_sz; Carrier_t *crr;#if HAVE_ERTS_MSEG Uint is_mseg = 0;#endif ASSERT(IS_FIRST_BLK(blk)); if (IS_SBC_BLK(blk)) { Uint blk_sz = BLK_SZ(blk); crr = BLK2SBC(blk); crr_sz = CARRIER_SZ(crr); ASSERT(IS_LAST_BLK(blk)); HARD_CHECK_BLK_CARRIER(allctr, blk);#if HAVE_ERTS_MSEG if (IS_MSEG_CARRIER(crr)) { is_mseg++; ASSERT(crr_sz % mseg_unit_size == 0); STAT_MSEG_SBC_FREE(allctr, crr_sz, blk_sz); } else#endif STAT_SYS_ALLOC_SBC_FREE(allctr, crr_sz, blk_sz); unlink_carrier(&allctr->sbc_list, crr); } else { crr = FBLK2MBC(allctr, blk); crr_sz = CARRIER_SZ(crr);#ifdef DEBUG if (!allctr->stopped) { ASSERT(IS_LAST_BLK(blk));#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG (*allctr->link_free_block)(allctr, blk); HARD_CHECK_BLK_CARRIER(allctr, blk); (*allctr->unlink_free_block)(allctr, blk);#endif }#endif#if HAVE_ERTS_MSEG if (IS_MSEG_CARRIER(crr)) { is_mseg++; ASSERT(crr_sz % mseg_unit_size == 0); STAT_MSEG_MBC_FREE(allctr, crr_sz); } else#endif STAT_SYS_ALLOC_MBC_FREE(allctr, crr_sz); unlink_carrier(&allctr->mbc_list, crr); if (allctr->destroying_mbc) (*allctr->destroying_mbc)(allctr, crr); }#if HAVE_ERTS_MSEG if (is_mseg) { alcu_mseg_dealloc(allctr, crr, crr_sz); } else#endif alcu_sys_free(allctr, crr);}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Info stuff *\* */static struct { Eterm versions; Eterm options; Eterm e; Eterm sbct;#if HAVE_ERTS_MSEG Eterm asbcst; Eterm rsbcst;#endif Eterm rsbcmt; Eterm mmbcs; Eterm msbclt;#if HAVE_ERTS_MSEG Eterm mmsbc; Eterm mmmbc;#endif Eterm lmbcs; Eterm smbcs; Eterm mbcgs;#if HAVE_ERTS_MSEG Eterm mmc;#endif Eterm ycs; Eterm mbcs; Eterm sbcs; Eterm sys_alloc_carriers_size;#if HAVE_ERTS_MSEG Eterm mseg_alloc_carriers_size;#endif Eterm carriers_size; Eterm sys_alloc_carriers;#if HAVE_ERTS_MSEG Eterm mseg_alloc_carriers;#endif Eterm carriers; Eterm blocks_size; Eterm blocks; Eterm calls; Eterm sys_alloc; Eterm sys_free; Eterm sys_realloc;#if HAVE_ERTS_MSEG Eterm mseg_alloc; Eterm mseg_dealloc; Eterm mseg_realloc;#endif#ifdef DEBUG Eterm end_of_atoms;#endif} am;static ERTS_INLINE void atom_init(Eterm *atom, char *name){ *atom = am_atom_put(name, strlen(name));}#define AM_INIT(AM) atom_init(&am.AM, #AM)static erts_mtx_t init_atoms_mtx;static voidinit_atoms(Allctr_t *allctr){#ifdef USE_THREADS if (allctr && allctr->thread_safe) erts_mtx_unlock(&allctr->mutex);#endif erts_mtx_lock(&init_atoms_mtx); if (!atoms_initialized) {#ifdef DEBUG Eterm *atom; for (atom = (Eterm *) &am; atom <= &am.end_of_atoms; atom++) { *atom = THE_NON_VALUE; }#endif AM_INIT(versions); AM_INIT(options); AM_INIT(e); AM_INIT(sbct);#if HAVE_ERTS_MSEG AM_INIT(asbcst); AM_INIT(rsbcst);#endif AM_INIT(rsbcmt); AM_INIT(mmbcs); AM_INIT(msbclt);#if HAVE_ERTS_MSEG AM_INIT(mmsbc); AM_INIT(mmmbc);#endif AM_INIT(lmbcs); AM_INIT(smbcs); AM_INIT(mbcgs);#if HAVE_ERTS_MSEG AM_INIT(mmc);#endif AM_INIT(ycs); AM_INIT(mbcs); AM_INIT(sbcs); AM_INIT(sys_alloc_carriers_size);#if HAVE_ERTS_MSEG AM_INIT(mseg_alloc_carriers_size);#endif AM_INIT(carriers_size); AM_INIT(sys_alloc_carriers);#if HAVE_ERTS_MSEG AM_INIT(mseg_alloc_carriers);#endif AM_INIT(carriers); AM_INIT(blocks_size); AM_INIT(blocks); AM_INIT(calls); AM_INIT(sys_alloc); AM_INIT(sys_free); AM_INIT(sys_realloc);#if HAVE_ERTS_MSEG AM_INIT(mseg_alloc); AM_INIT(mseg_dealloc); AM_INIT(mseg_realloc);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -