⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_alloc_util.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -