erl_alloc.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 2,572 行 · 第 1/5 页

C
2,572
字号
    values[i].arity = 2;    values[i].name = "fun_table";    values[i].ui[0] = erts_fun_table_sz();    i++;    values[i].arity = 2;    values[i].name = "module_refs";    values[i].ui[0] = allocated_modules*sizeof(Range);    i++;    values[i].arity = 2;    values[i].name = "loaded_code";    values[i].ui[0] = erts_total_code_size;    i++;    values[i].arity = 2;    values[i].name = "dist_table";    values[i].ui[0] = erts_dist_table_size();    i++;    values[i].arity = 2;    values[i].name = "node_table";    values[i].ui[0] = erts_node_table_size();    i++;    values[i].arity = 2;    values[i].name = "bits_bufs_size";    values[i].ui[0] = erts_bits_bufs_size();    i++;    values[i].arity = 2;    values[i].name = "bif_timer";    values[i].ui[0] = erts_bif_timer_memory_size();    i++;    values[i].arity = 2;    values[i].name = "link_lh";    values[i].ui[0] = erts_tot_link_lh_size();    i++;    {	Uint n;	for (n = ERTS_ALC_N_MIN_A_FIXED_SIZE;	     n <= ERTS_ALC_N_MAX_A_FIXED_SIZE;	     n++) {	    erts_fix_info(ERTS_ALC_N2T(n), &efi);	    values[i].arity = 3;	    values[i].name = ERTS_ALC_N2TD(n);	    values[i].ui[0] = efi.total;	    values[i].ui[1] = efi.used;	    i++;	}        }    length = i;    ASSERT(length <= MAX_AA_VALUES);    if (print_to_p) {	/* Print result... */	int to = *print_to_p;	void *arg = print_to_arg;	erts_print(to, arg, "=allocated_areas\n");	for (i = 0; i < length; i++) {	    switch (values[i].arity) {	    case 2:		erts_print(to, arg, "%s: %bpu\n",			   values[i].name, values[i].ui[0]);		break;	    case 3:		erts_print(to, arg, "%s: %bpu %bpu\n",			   values[i].name, values[i].ui[0], values[i].ui[1]);		break;	    default:		erts_print(to, arg, "ERROR: internal_error\n");		ASSERT(0);		return am_internal_error;	    }	}    }    if (proc) {	/* Build erlang term result... */	Eterm tuples[MAX_AA_VALUES];	Uint *hp;	Uint **hpp;	Uint hsz;	Uint *hszp;	hpp = NULL;	hsz = 0;	hszp = &hsz;	while (1) {	    int i;	    for (i = 0; i < length; i++) {		Eterm atom;		if (hpp)		    atom = am_atom_put(values[i].name,				       (int) strlen(values[i].name));		else		    atom = am_true;		switch (values[i].arity) {		case 2:		    tuples[i] = erts_bld_tuple(hpp, hszp, 2,					       atom,					       erts_bld_uint(hpp, hszp,							     values[i].ui[0]));		    break;		case 3:		    tuples[i] = erts_bld_tuple(hpp, hszp, 3,					       atom,					       erts_bld_uint(hpp, hszp,							     values[i].ui[0]),					       erts_bld_uint(hpp, hszp,							     values[i].ui[1]));		    break;		default:		    ASSERT(0);		    return am_internal_error;		}	    }	    res = erts_bld_list(hpp, hszp, length, tuples);	    if (hpp)		break;	    hp = HAlloc((Process *) proc, hsz);	    hpp = &hp;	    hszp = NULL;	}    }    return res;#undef MAX_AA_VALUES}Etermerts_allocator_info_term(void *proc, Eterm which_alloc){#define ERTS_AIT_RET(R) \  do { res = (R); goto done; } while (0)#define ERTS_AIT_HALLOC(P, S) \  do { hp = HAlloc((P), (S)); hp_end = hp + (S); } while (0)    ErtsAlcType_t i;    Uint sz = 0;    Uint *hp = NULL;    Uint *hp_end = NULL;    Eterm res = am_undefined;    if (is_not_atom(which_alloc))	goto done;    for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {	if (is_atom_text(which_alloc, ERTS_ALC_A2AD(i))) {	    if (!erts_allctrs_info[i].enabled)		ERTS_AIT_RET(am_false);	    else {		if (erts_allctrs_info[i].alloc_util) {		    Allctr_t *allctr = (Allctr_t *) erts_allctrs_info[i].extra;		    Eterm ires;		    /* Binary alloc has its own thread safety... */		    if (i == ERTS_ALC_A_BINARY)			erts_mtx_lock(&erts_bin_alloc_mtx);		    erts_alcu_info(allctr, 0, NULL, NULL, NULL, &sz);		    if (sz)			ERTS_AIT_HALLOC((Process *) proc, sz);		    ires = erts_alcu_info(allctr,					  1,					  NULL,					  NULL,					  &hp,					  NULL);		    if (i == ERTS_ALC_A_BINARY)			erts_mtx_unlock(&erts_bin_alloc_mtx);		    ERTS_AIT_RET(ires);		}		else {		    Eterm *szp, **hpp;		    switch (i) {		    case ERTS_ALC_A_SYSTEM: {			SysAllocStat sas;			Eterm opts_am;			Eterm opts;			Eterm as[4];			Eterm ts[4];			int l;			sys_alloc_stat(&sas);			opts_am = am_atom_put("options", 7);			szp = &sz;			hpp = NULL;		    restart_sys_alloc:			l = 0;			as[l] = am_atom_put("e", 1);			ts[l++] = am_true;#ifdef ELIB_ALLOC_IS_CLIB			as[l] = am_atom_put("m", 1);			ts[l++] = am_atom_put("elib", 4);#else			as[l] = am_atom_put("m", 1);			ts[l++] = am_atom_put("libc", 4);#endif			if(sas.trim_threshold >= 0) {			    as[l] = am_atom_put("tt", 2);			    ts[l++] = erts_bld_uint(hpp, szp,						    (Uint) sas.trim_threshold);			}			if(sas.top_pad >= 0) {			    as[l] = am_atom_put("tp", 2);			    ts[l++] = erts_bld_uint(hpp, szp, (Uint) sas.top_pad);			}			opts = erts_bld_2tup_list(hpp, szp, l, as, ts);			res = erts_bld_2tup_list(hpp, szp, 1, &opts_am, &opts);						if (szp) {			    ERTS_AIT_HALLOC((Process *) proc, sz);			    szp = NULL;			    hpp = &hp;			    goto restart_sys_alloc;			}			ERTS_AIT_RET(res);		    }		    case ERTS_ALC_A_FIXED_SIZE: {			ErtsAlcType_t n;			Eterm as[2], vs[2];			as[0] = am_atom_put("options", 7);			as[1] = am_atom_put("pools", 5);			szp = &sz;			hpp = NULL;		    restart_fix_alloc:			vs[0] = erts_bld_cons(hpp, szp,					      erts_bld_tuple(hpp, szp, 2, 							     am_atom_put("e",									 1),							     am_true),					      NIL);			vs[1] = NIL;			for (n = ERTS_ALC_N_MIN_A_FIXED_SIZE;			     n <= ERTS_ALC_N_MAX_A_FIXED_SIZE;			     n++) {			    ErtsFixInfo efi;			    erts_fix_info(ERTS_ALC_N2T(n), &efi);			    vs[1] = erts_bld_cons(				hpp, szp,				erts_bld_tuple(				    hpp, szp, 3,				    am_atom_put((char *) ERTS_ALC_N2TD(n),						strlen(ERTS_ALC_N2TD(n))),				    erts_bld_uint(hpp, szp, efi.total),				    erts_bld_uint(hpp, szp, efi.used)),				vs[1]);			}						res = erts_bld_2tup_list(hpp, szp, 2, as, vs);			if (szp) {			    ERTS_AIT_HALLOC((Process *) proc, sz);			    szp = NULL;			    hpp = &hp;			    goto restart_fix_alloc;			}			ERTS_AIT_RET(res);		    }		    default:			ASSERT(0);			goto done;		    }		}	    }	}    }    if (is_atom_text(which_alloc, "mseg_alloc")) {#if HAVE_ERTS_MSEG	erts_mseg_info(NULL, NULL, NULL, &sz);	if (sz)	    ERTS_AIT_HALLOC((Process *) proc, sz);	ERTS_AIT_RET(erts_mseg_info(NULL, NULL, &hp, NULL));#else	ERTS_AIT_RET(am_false);#endif    }    else if (is_atom_text(which_alloc, "alloc_util")) {	erts_alcu_au_info_options(NULL, NULL, NULL, &sz);	if (sz)	    ERTS_AIT_HALLOC((Process *) proc, sz);	ERTS_AIT_RET(erts_alcu_au_info_options(NULL, NULL, &hp, NULL));    } done:    if (hp) {	ASSERT(hp_end >= hp);	HRelease((Process *) proc, hp_end, hp);    }    return res;#undef ERTS_AIT_RET#undef ERTS_AIT_HALLOC}voiderts_allocator_info(int to, void *arg){    ErtsAlcType_t a;    for (a = ERTS_ALC_A_MIN; a <= ERTS_ALC_A_MAX; a++) {	erts_print(to, arg, "=allocator:%s\n", ERTS_ALC_A2AD(a));	if (!erts_allctrs_info[a].enabled)	    erts_print(to, arg, "option e: false\n");	else {	    if (erts_allctrs_info[a].alloc_util) {		/* Binary alloc has its own thread safety... */		if (a == ERTS_ALC_A_BINARY)		    erts_mtx_lock(&erts_bin_alloc_mtx);		erts_alcu_info(erts_allctrs_info[a].extra,			       0, &to, arg, NULL, NULL);		if (a == ERTS_ALC_A_BINARY)		    erts_mtx_unlock(&erts_bin_alloc_mtx);	    }	    else {		switch (a) {		case ERTS_ALC_A_SYSTEM: {		    SysAllocStat sas;		    erts_print(to, arg, "option e: true\n");#ifdef ELIB_ALLOC_IS_CLIB		    erts_print(to, arg, "option m: elib\n");#else		    erts_print(to, arg, "option m: libc\n");#endif		    sys_alloc_stat(&sas);		    if(sas.trim_threshold >= 0)			erts_print(to, arg, "option tt: %d\n", sas.trim_threshold);		    if(sas.top_pad >= 0)			erts_print(to, arg, "option tp: %d\n", sas.top_pad);		    break;		}		case ERTS_ALC_A_FIXED_SIZE: {		    ErtsAlcType_t n;		    erts_print(to, arg, "option e: true\n");		    for (n = ERTS_ALC_N_MIN_A_FIXED_SIZE;			 n <= ERTS_ALC_N_MAX_A_FIXED_SIZE;			 n++) {			ErtsFixInfo efi;			erts_fix_info(ERTS_ALC_N2T(n), &efi);			erts_print(to, arg, "%s: %lu %lu\n",				   ERTS_ALC_N2TD(n),				   efi.total,				   efi.used);		    }		    break;		}		default:		    ASSERT(0);		    break;		}	    }	}    }#if HAVE_ERTS_MSEG    erts_print(to, arg, "=allocator:mseg_alloc\n");    erts_mseg_info(&to, arg, NULL, NULL);#endif    erts_print(to, arg, "=allocator:alloc_util\n");    erts_alcu_au_info_options(&to, arg, NULL, NULL);    erts_print(to, arg, "=allocator:instr\n");    erts_print(to, arg, "option m: %s\n",	       erts_instr_memory_map ? "true" : "false");    erts_print(to, arg, "option s: %s\n",	       erts_instr_stat ? "true" : "false");    erts_print(to, arg, "option t: %s\n",	       erts_mtrace_enabled ? "true" : "false");}Etermerts_allocator_options(void *proc){#if HAVE_ERTS_MSEG    int use_mseg = 0;#endif    Uint sz, *szp, *hp, **hpp;    Eterm res, features, settings;    Eterm atoms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+5];    Uint terms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+5];    int a, length;    SysAllocStat sas;    Uint *endp = NULL;    sys_alloc_stat(&sas);    /* First find out the heap size needed ... */    hpp = NULL;    szp = &sz;    sz = 0; bld_term:    length = 0;    features = NIL;    settings = NIL;    for (a = ERTS_ALC_A_MIN; a <= ERTS_ALC_A_MAX; a++) {	Eterm tmp = NIL;	atoms[length] = am_atom_put((char *) ERTS_ALC_A2AD(a),				    strlen(ERTS_ALC_A2AD(a)));	if (erts_allctrs_info[a].enabled) {	    if (erts_allctrs_info[a].alloc_util) {#if HAVE_ERTS_MSEG		use_mseg++;#endif		/* Binary alloc has its own thread safety... */		if (a == ERTS_ALC_A_BINARY)		    erts_mtx_lock(&erts_bin_alloc_mtx);		tmp = erts_alcu_info_options(erts_allctrs_info[a].extra,					     NULL, NULL, hpp, szp);		if (a == ERTS_ALC_A_BINARY)		    erts_mtx_unlock(&erts_bin_alloc_mtx);	    }	    else {		int l = 0;		Eterm as[4];		Eterm ts[4];		as[l] = am_atom_put("e", 1);		ts[l++] = am_true;		switch (a) {		case ERTS_ALC_A_SYSTEM:#ifdef ELIB_ALLOC_IS_CLIB		    as[l] = am_atom_put("m", 1);		    ts[l++] = am_atom_put("elib", 4);#else		    as[l] = am_atom_put("m", 1);		    ts[l++] = am_atom_put("libc", 4);#endif		    if(sas.trim_threshold >= 0) {			as[l] = am_atom_put("tt", 2);			ts[l++] = erts_bld_uint(hpp, szp,						(Uint) sas.trim_threshold);		    }		    if(sas.top_pad >= 0) {			as[l] = am_atom_put("tp", 2);			ts[l++] = erts_bld_uint(hpp, szp, (Uint) sas.top_pad);		    }		    break;		default:		    break;		}		tmp = erts_bld_2tup_list(hpp, szp, l, as, ts);	    }	}	else {	    Eterm atom = am_atom_put("e", 1);	    Eterm term = am_false;	    tmp = erts_bld_2tup_list(hpp, szp, 1, &atom, &term);	}	terms[length++] = tmp;    }#if HAVE_ERTS_MSEG    if (use_mseg) {	atoms[length] = am_atom_put("mseg_alloc", 10);	terms[length++] = erts_mseg_info_options(NULL, NULL, hpp, szp);    }#endif    atoms[length] = am_atom_put("alloc_util", 10);     terms[length++] = erts_alcu_au_info_options(NULL, NULL, hpp, szp);    {	Eterm o[3], v[3];	o[0] = am_atom_put("m", 1);	v[0] = erts_instr_memory_map ? am_true : am_false;	o[1] = am_atom_put("s", 1);	v[1] = erts_instr_stat ? am_true : am_false;	o[2] = am_atom_put("t", 1);	v[2] = erts_mtrace_enabled ? am_true : am_false;	atoms[length] = am_atom_put("instr", 5); 	terms[length++] = erts_bld_2tup_list(hpp, szp, 3, o, v);    }    settings = erts_bld_2tup_list(hpp, szp, length, atoms, terms);    length = 0;    for (a = ERTS_ALC_A_MIN; a <= ERTS_ALC_A_MAX; a++) {	if (erts_allctrs_info[a].enabled) {	    terms[length++] = am_atom_put((char *) ERTS_ALC_A2AD(a),					  strlen(ERTS_ALC_A2AD(a)));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?