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 + -
显示快捷键?