erl_alloc.c

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

C
2,572
字号
    }#ifdef USE_THREADS    if (init->init.util.ts) {	af->alloc	= erts_alcu_alloc_ts;	af->realloc	= erts_alcu_realloc_ts;	af->free	= erts_alcu_free_ts;    }    else {#endif	af->alloc	= erts_alcu_alloc;	af->realloc	= erts_alcu_realloc;	af->free	= erts_alcu_free;#ifdef USE_THREADS    }#endif    af->extra		= NULL;    ai->alloc_util	= 1;    ai->enabled		= 1;}static voidstart_au_allocator(ErtsAllocatorFunctions_t *af,		   ErtsAllocatorInfo_t *ai,		   struct au_init *init,		   allocator_state *state){    if (!init->enable)	return;    switch (init->atype) {    case GOODFIT:	af->extra = (void *) erts_gfalc_start((GFAllctr_t *) state,					      &init->init.gf,					      &init->init.util);	break;    case BESTFIT:	af->extra = (void *) erts_bfalc_start((BFAllctr_t *) state,					      &init->init.bf,					      &init->init.util);	break;    case AFIT:	af->extra = (void *) erts_afalc_start((AFAllctr_t *) state,					      &init->init.af,					      &init->init.util);	break;    default:	ASSERT(0);    }    if (!af->extra)	erl_exit(ERTS_ABORT_EXIT,		 "Failed to start %salloc\n", init->init.util.name_prefix);    ai->extra = af->extra;}static void bad_param(char *param_start, char *param_end){    size_t len = param_end - param_start;    char param[100];    if (len > 99)	len = 99;    sys_memcpy((void *) param, (void *) param_start, len);    param[len] = '\0';    erts_fprintf(stderr, "bad \"%s\" parameter\n", param);    erts_usage();}static void bad_value(char *param_start, char *param_end, char *value){    size_t len = param_end - param_start;    char param[100];    if (len > 99)	len = 99;    sys_memcpy((void *) param, (void *) param_start, len);    param[len] = '\0';    erts_fprintf(stderr, "bad \"%s\" value: %s\n", param, value);    erts_usage();}/* Get arg marks argument as handled by   putting NULL in argv */static char *get_value(char* rest, char** argv, int* ip){    char *param = argv[*ip]+1;    argv[*ip] = NULL;    if (*rest == '\0') {	char *next = argv[*ip + 1];	if (next[0] == '-'	    && next[1] == '-'	    &&  next[2] == '\0') {	    bad_value(param, rest, "");	}	(*ip)++;	argv[*ip] = NULL;	return next;    }    return rest;}static ERTS_INLINE inthas_prefix(const char *prefix, const char *string){    int i;    for (i = 0; prefix[i]; i++)	if (prefix[i] != string[i])	    return 0;    return 1;}static intget_bool_value(char *param_end, char** argv, int* ip){    char *param = argv[*ip]+1;    char *value = get_value(param_end, argv, ip);    if (strcmp(value, "true") == 0)	return 1;    else if (strcmp(value, "false") == 0)	return 0;    else	bad_value(param, param_end, value);    return -1;}static Uintget_kb_value(char *param_end, char** argv, int* ip){    Sint tmp;    Uint max = ((~((Uint) 0))/1024) + 1;    char *rest;    char *param = argv[*ip]+1;    char *value = get_value(param_end, argv, ip);    errno = 0;    tmp = (Sint) strtol(value, &rest, 10);    if (errno != 0 || rest == value || tmp < 0 || max < ((Uint) tmp))	bad_value(param, param_end, value);    if (max == (Uint) tmp)	return ~((Uint) 0);    else	return ((Uint) tmp)*1024;}static Uintget_amount_value(char *param_end, char** argv, int* ip){    Sint tmp;    char *rest;    char *param = argv[*ip]+1;    char *value = get_value(param_end, argv, ip);    errno = 0;    tmp = (Sint) strtol(value, &rest, 10);    if (errno != 0 || rest == value || tmp < 0)	bad_value(param, param_end, value);    return (Uint) tmp;}static voidhandle_au_arg(struct au_init *auip,	      char* sub_param,	      char** argv,	      int* ip){    char *param = argv[*ip]+1;    switch (sub_param[0]) {    case 'a':	if(has_prefix("asbcst", sub_param)) {	    auip->init.util.asbcst = get_kb_value(sub_param + 6, argv, ip);	}	else if(has_prefix("as", sub_param)) {	    char *alg = get_value(sub_param + 2, argv, ip);	    if (strcmp("bf", alg) == 0) {		auip->atype = BESTFIT;		auip->init.bf.ao = 0;	    }	    else if (strcmp("aobf", alg) == 0) {		auip->atype = BESTFIT;		auip->init.bf.ao = 1;	    }	    else if (strcmp("gf", alg) == 0) {		auip->atype = GOODFIT;	    }	    else if (strcmp("af", alg) == 0) {		auip->atype = AFIT;	    }	    else {		bad_value(param, sub_param + 1, alg);	    }	}	else	    goto bad_switch;	break;    case 'e':	auip->enable = get_bool_value(sub_param+1, argv, ip);	break;    case 'l':	if (has_prefix("lmbcs", sub_param)) {	    auip->init.util.lmbcs = get_kb_value(sub_param + 5, argv, ip);	}	else	    goto bad_switch;	break;    case 'm':	if (has_prefix("mbcgs", sub_param)) {	    auip->init.util.mbcgs = get_amount_value(sub_param + 5, argv, ip);	}	else if (has_prefix("mbsd", sub_param)) {	    auip->init.gf.mbsd = get_amount_value(sub_param + 4, argv, ip);	    if (auip->init.gf.mbsd < 1)		auip->init.gf.mbsd = 1;	}	else if (has_prefix("mmbcs", sub_param)) {	    auip->init.util.mmbcs = get_kb_value(sub_param + 5, argv, ip);	}	else if (has_prefix("mmmbc", sub_param)) {	    auip->init.util.mmmbc = get_amount_value(sub_param + 5, argv, ip);	}	else if (has_prefix("mmsbc", sub_param)) {	    auip->init.util.mmsbc = get_amount_value(sub_param + 5, argv, ip);	}	else	    goto bad_switch;	break;    case 'r':	if(has_prefix("rsbcmt", sub_param)) {	    auip->init.util.rsbcmt = get_amount_value(sub_param + 6, argv, ip);	    if (auip->init.util.rsbcmt > 100)		auip->init.util.rsbcmt = 100;	}	else if(has_prefix("rsbcst", sub_param)) {	    auip->init.util.rsbcst = get_amount_value(sub_param + 6, argv, ip);	    if (auip->init.util.rsbcst > 100)		auip->init.util.rsbcst = 100;	}	else	    goto bad_switch;	break;    case 's':	if(has_prefix("sbct", sub_param)) {	    auip->init.util.sbct = get_kb_value(sub_param + 4, argv, ip);	}	else if (has_prefix("smbcs", sub_param)) {	    auip->init.util.smbcs = get_kb_value(sub_param + 5, argv, ip);	}	else	    goto bad_switch;	break;    default:    bad_switch:	bad_param(param, sub_param);    }}static voidhandle_args(int *argc, char **argv, init_t *init){    char *arg;    char *rest;    int i, j;    i = 1;    ASSERT(argc && argv && init);    while (i < *argc) {	if(argv[i][0] == '-') {	    char *param = argv[i]+1;	    switch (argv[i][1]) {	    case 'M':		switch (argv[i][2]) {		case 'B':		    handle_au_arg(&init->binary_alloc, &argv[i][3], argv, &i);		    break;		case 'D':		    handle_au_arg(&init->std_alloc, &argv[i][3], argv, &i);		    break;		case 'E':		    handle_au_arg(&init->ets_alloc, &argv[i][3], argv, &i);		    break;		case 'F': /* fix_alloc */		    if (has_prefix("e", param+2)) {			arg = get_value(param+3, argv, &i);			if (strcmp("true", arg) != 0)			    bad_value(param, param+3, arg);		    }		    else			bad_param(param, param+2);		    break;		case 'H':		    handle_au_arg(&init->eheap_alloc, &argv[i][3], argv, &i);		    break;		case 'L':		    handle_au_arg(&init->ll_alloc, &argv[i][3], argv, &i);		    break;		case 'M':		    if (has_prefix("amcbf", argv[i]+3)) {#if HAVE_ERTS_MSEG			init->mseg.amcbf =#endif			    get_kb_value(argv[i]+8, argv, &i);		    }		    else if (has_prefix("rmcbf", argv[i]+3)) {#if HAVE_ERTS_MSEG			init->mseg.rmcbf =#endif			    get_amount_value(argv[i]+8, argv, &i);		    }		    else if (has_prefix("mcs", argv[i]+3)) {#if HAVE_ERTS_MSEG			init->mseg.mcs =#endif			    get_amount_value(argv[i]+6, argv, &i);		    }		    else if (has_prefix("cci", argv[i]+3)) {#if HAVE_ERTS_MSEG			init->mseg.cci =#endif			    get_amount_value(argv[i]+6, argv, &i);		    }		    else {			bad_param(param, param+2);		    }		    break;		case 'S':		    handle_au_arg(&init->sl_alloc, &argv[i][3], argv, &i);		    break;		case 'T':		    handle_au_arg(&init->temp_alloc, &argv[i][3], argv, &i);		    break;		case 'Y': { /* sys_alloc */		    if (has_prefix("tt", param+2)) {			/* set trim threshold */			arg = get_value(param+4, argv, &i);			errno = 0;			init->trim_threshold = (int) strtol(arg, &rest, 10);			if (errno != 0			    || rest == arg			    || init->trim_threshold < 0			    || (INT_MAX/1024) < init->trim_threshold) {			    bad_value(param, param+4, arg);			}			VERBOSE(DEBUG_SYSTEM,                                ("using trim threshold: %d\n",                                 init->trim_threshold));			init->trim_threshold *= 1024;		    }		    else if (has_prefix("tp", param+2)) {			/* set top pad */			arg = get_value(param+4, argv, &i);			errno = 0;			init->top_pad = (int) strtol(arg, &rest, 10);			if (errno != 0			    || rest == arg			    || init->top_pad < 0			    || (INT_MAX/1024) < init->top_pad) {			    bad_value(param, param+4, arg);			}			VERBOSE(DEBUG_SYSTEM,                                ("using top pad: %d\n",init->top_pad));			init->top_pad *= 1024;		    }		    else if (has_prefix("m", param+2)) {			/* Has been handled by erlexec */			(void) get_value(param+3, argv, &i);		    }		    else if (has_prefix("e", param+2)) {			arg = get_value(param+3, argv, &i);			if (strcmp("true", arg) != 0)			    bad_value(param, param+3, arg);		    }		    else			bad_param(param, param+2);		    break;		}		case 'e':		    switch (argv[i][3]) {		    case 'a':			arg = get_value(argv[i]+4, argv, &i);			if (strcmp("min", arg) == 0) {			    init->sl_alloc.enable		= 0;			    init->std_alloc.enable		= 0;			    init->ll_alloc.enable		= 0;			    init->temp_alloc.enable		= 0;			    init->eheap_alloc.enable		= 0;			    init->binary_alloc.enable		= 0;			    init->ets_alloc.enable		= 0;			}			else if (strcmp("max", arg) == 0) {			    init->sl_alloc.enable		= 1;			    init->std_alloc.enable		= 1;			    init->ll_alloc.enable		= 1;			    init->temp_alloc.enable		= 1;			    init->eheap_alloc.enable		= 1;			    init->binary_alloc.enable		= 1;			    init->ets_alloc.enable		= 1;			}			else if (strcmp("r9c", arg) == 0) {			    init->sl_alloc.enable		= 0;			    init->std_alloc.enable		= 0;			    init->ll_alloc.enable		= 1;			    init->temp_alloc.enable		= 1;			    init->eheap_alloc.enable		= 1;			    init->binary_alloc.enable		= 0;			    init->ets_alloc.enable		= 0;			}			else {			    bad_param(param, param+3);			}			break;		    default:			bad_param(param, param+1);		    }		    break;		case 'i':		    switch (argv[i][3]) {		    case 's':			arg = get_value(argv[i]+4, argv, &i);			if (strcmp("true", arg) == 0)			    init->instr.stat = 1;			else if (strcmp("false", arg) == 0)			    init->instr.stat = 0;			else			    bad_value(param, param+3, arg);			break;		    case 'm':			arg = get_value(argv[i]+4, argv, &i);			if (strcmp("true", arg) == 0)			    init->instr.map = 1;			else if (strcmp("false", arg) == 0)			    init->instr.map = 0;			else			    bad_value(param, param+3, arg);			break;		    case 't':			init->instr.mtrace = get_value(argv[i]+4, argv, &i);			break;		    default:			bad_param(param, param+2);		    }		    break;		case 'u':		    if (has_prefix("ycs", argv[i]+3)) {			init->alloc_util.ycs			    = get_kb_value(argv[i]+6, argv, &i);		    }		    else if (has_prefix("mmc", argv[i]+3)) {			init->alloc_util.mmc			    = get_amount_value(argv[i]+6, argv, &i);		    }		    else {			bad_param(param, param+2);		    }		    break;		default:		    bad_param(param, param+1);		}		break;	    case '-':		if (argv[i][2] == '\0') {		    /* End of system flags reached */		    if (init->instr.mtrace			/* || init->instr.stat			   || init->instr.map */) {			while (i < *argc) {			    if(strcmp(argv[i], "-sname") == 0			       || strcmp(argv[i], "-name") == 0) {				if (i + 1 <*argc) {				    init->instr.nodename = argv[i+1];				    break;				}			    }			    i++;			}		    }		    goto args_parsed;		}		break;	    default:		break;	    }	}	i++;    } args_parsed:    /* Handled arguments have been marked with NULL. Slide arguments       not handled towards the beginning of argv. */    for (i = 0, j = 0; i < *argc; i++) {	if (argv[i])	    argv[j++] = argv[i];    }    *argc = j;    }static char *type_no_str(ErtsAlcType_t n){#if ERTS_ALC_N_MIN != 0    if (n < ERTS_ALC_N_MIN)	return NULL;#endif    if (n > ERTS_ALC_N_MAX)	return NULL;    return (char *) ERTS_ALC_N2TD(n);}#define type_str(T) type_no_str(ERTS_ALC_T2N((T)))voiderts_alc_fatal_error(int error, int func, ErtsAlcType_t n, ...){

⌨️ 快捷键说明

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