erl_alloc.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 2,572 行 · 第 1/5 页
C
2,572 行
char buf[10]; char *t_str; char *allctr_str; ASSERT(n >= ERTS_ALC_N_MIN); ASSERT(n <= ERTS_ALC_N_MAX); if (n < ERTS_ALC_N_MIN || ERTS_ALC_N_MAX < n) allctr_str = "UNKNOWN"; else { ErtsAlcType_t a = ERTS_ALC_T2A(ERTS_ALC_N2T(n)); if (erts_allctrs_info[a].enabled) allctr_str = (char *) ERTS_ALC_A2AD(a); else allctr_str = (char *) ERTS_ALC_A2AD(ERTS_ALC_A_SYSTEM); } t_str = type_no_str(n); if (!t_str) { sprintf(buf, "%d", (int) n); t_str = buf; } switch (error) { case ERTS_ALC_E_NOTSUP: { char *op_str; switch (func) { case ERTS_ALC_O_ALLOC: op_str = "alloc"; break; case ERTS_ALC_O_REALLOC: op_str = "realloc"; break; case ERTS_ALC_O_FREE: op_str = "free"; break; default: op_str = "UNKNOWN"; break; } erl_exit(ERTS_ABORT_EXIT, "%s: %s operation not supported (memory type: \"%s\")\n", allctr_str, op_str, t_str); break; } case ERTS_ALC_E_NOMEM: { Uint size; va_list argp; char *op = func == ERTS_ALC_O_REALLOC ? "reallocate" : "allocate"; va_start(argp, n); size = va_arg(argp, Uint); va_end(argp); erl_exit(1, "%s: Cannot %s %lu bytes of memory (of type \"%s\").\n", allctr_str, op, size, t_str); break; } case ERTS_ALC_E_NOALLCTR: erl_exit(ERTS_ABORT_EXIT, "erts_alloc: Unknown allocator type: %d\n", ERTS_ALC_T2A(ERTS_ALC_N2T(n))); break; default: erl_exit(ERTS_ABORT_EXIT, "erts_alloc: Unknown error: %d\n", error); break; }}voiderts_alloc_enomem(ErtsAlcType_t type, Uint size){ erts_alloc_n_enomem(ERTS_ALC_T2N(type), size);}voiderts_alloc_n_enomem(ErtsAlcType_t n, Uint size){ erts_alc_fatal_error(ERTS_ALC_E_NOMEM, ERTS_ALC_O_ALLOC, n, size);}voiderts_realloc_enomem(ErtsAlcType_t type, void *ptr, Uint size){ erts_realloc_n_enomem(ERTS_ALC_T2N(type), ptr, size);}voiderts_realloc_n_enomem(ErtsAlcType_t n, void *ptr, Uint size){ erts_alc_fatal_error(ERTS_ALC_E_NOMEM, ERTS_ALC_O_REALLOC, n, size);}static ERTS_INLINE intis_atom_text(Eterm atom, const char *str){ int i; char *atxt = (char*) atom_tab(atom_val(atom))->name; int alen = atom_tab(atom_val(atom))->len; for (i = 0; i < alen && str[i]; i++) if (atxt[i] != str[i]) return 0; if (alen == i && !str[i]) return 1; return 0;}Etermerts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg){#define MEM_NEED_PARTS (!erts_instr_stat && want_tot_or_sys) ErtsFixInfo efi; struct { int total; int processes; int processes_used; int system; int atom; int atom_used; int binary; int code; int ets; int maximum; } want = {0}; struct { Uint total; Uint processes; Uint processes_used; Uint system; Uint atom; Uint atom_used; Uint binary; Uint code; Uint ets; Uint maximum; } size = {0}; Eterm atoms[sizeof(size)/sizeof(Uint)]; Uint *uintps[sizeof(size)/sizeof(Uint)]; Eterm euints[sizeof(size)/sizeof(Uint)]; int need_atom; int want_tot_or_sys; int length; Eterm res = THE_NON_VALUE; int block = !ERTS_IS_CRASH_DUMPING; /* Figure out whats wanted... */ length = 0; if (earg == THE_NON_VALUE) { /* i.e. wants all */ want.total = 1; atoms[length] = am_total; uintps[length++] = &size.total; want.processes = 1; atoms[length] = am_processes; uintps[length++] = &size.processes; want.processes_used = 1; atoms[length] = am_processes_used; uintps[length++] = &size.processes_used; want.system = 1; atoms[length] = am_system; uintps[length++] = &size.system; want.atom = 1; atoms[length] = am_atom; uintps[length++] = &size.atom; want.atom_used = 1; atoms[length] = am_atom_used; uintps[length++] = &size.atom_used; want.binary = 1; atoms[length] = am_binary; uintps[length++] = &size.binary; want.code = 1; atoms[length] = am_code; uintps[length++] = &size.code; want.ets = 1; atoms[length] = am_ets; uintps[length++] = &size.ets; want.maximum = erts_instr_stat; if (want.maximum) { atoms[length] = am_maximum; uintps[length++] = &size.maximum; } } else { Eterm wanted_list; if (is_nil(earg)) return NIL; wanted_list = earg; while (is_list(wanted_list)) { switch (CAR(list_val(wanted_list))) { case am_total: if (!want.total) { want.total = 1; atoms[length] = am_total; uintps[length++] = &size.total; } break; case am_processes: if (!want.processes) { want.processes = 1; atoms[length] = am_processes; uintps[length++] = &size.processes; } break; case am_processes_used: if (!want.processes_used) { want.processes_used = 1; atoms[length] = am_processes_used; uintps[length++] = &size.processes_used; } break; case am_system: if (!want.system) { want.system = 1; atoms[length] = am_system; uintps[length++] = &size.system; } break; case am_atom: if (!want.atom) { want.atom = 1; atoms[length] = am_atom; uintps[length++] = &size.atom; } break; case am_atom_used: if (!want.atom_used) { want.atom_used = 1; atoms[length] = am_atom_used; uintps[length++] = &size.atom_used; } break; case am_binary: if (!want.binary) { want.binary = 1; atoms[length] = am_binary; uintps[length++] = &size.binary; } break; case am_code: if (!want.code) { want.code = 1; atoms[length] = am_code; uintps[length++] = &size.code; } break; case am_ets: if (!want.ets) { want.ets = 1; atoms[length] = am_ets; uintps[length++] = &size.ets; } break; case am_maximum: if (erts_instr_stat) { if (!want.maximum) { want.maximum = 1; atoms[length] = am_maximum; uintps[length++] = &size.maximum; } } else return am_badarg; break; default: return am_badarg; } wanted_list = CDR(list_val(wanted_list)); } if (is_not_nil(wanted_list)) return am_badarg; } ASSERT(length <= sizeof(atoms)/sizeof(Eterm)); ASSERT(length <= sizeof(euints)/sizeof(Eterm)); ASSERT(length <= sizeof(uintps)/sizeof(Uint)); if (block) erts_smp_block_system(0); /* Calculate values needed... */ want_tot_or_sys = want.total || want.system; need_atom = MEM_NEED_PARTS || want.atom; size.processes = size.processes_used = erts_get_tot_proc_mem(); if (MEM_NEED_PARTS || want.processes) { erts_fix_info(ERTS_ALC_T_NLINK_SH, &efi); size.processes += efi.total - efi.used; erts_fix_info(ERTS_ALC_T_MONITOR_SH, &efi); size.processes += efi.total - efi.used; erts_fix_info(ERTS_ALC_T_PROC, &efi); size.processes += efi.total - efi.used; erts_fix_info(ERTS_ALC_T_REG_PROC, &efi); size.processes += efi.total - efi.used; } if (need_atom || want.atom_used) { Uint reserved_atom_space, atom_space; erts_atom_get_text_space_sizes(&reserved_atom_space, &atom_space); size.atom = size.atom_used = atom_table_sz(); erts_fix_info(ERTS_ALC_T_ATOM, &efi); if (need_atom) { size.atom += reserved_atom_space; size.atom += efi.total; } if (want.atom_used) { size.atom_used += atom_space; size.atom_used += efi.used; } } size.binary = erts_get_binaries_size(); if (MEM_NEED_PARTS || want.code) { size.code = module_table_sz(); erts_fix_info(ERTS_ALC_T_MODULE, &efi); size.code += efi.used; size.code += export_table_sz(); erts_fix_info(ERTS_ALC_T_EXPORT, &efi); size.code += efi.used; size.code += erts_fun_table_sz(); erts_fix_info(ERTS_ALC_T_FUN_ENTRY, &efi); size.code += efi.used; size.code += allocated_modules*sizeof(Range); size.code += erts_total_code_size; } size.ets = erts_ets_memory_size(); if (erts_instr_stat && (want_tot_or_sys || want.maximum)) { size.total = erts_instr_get_total(); size.system = size.total - size.processes; size.maximum = erts_instr_get_max_total(); } else if (want_tot_or_sys) { /* Static stuff ... */ size.system = erts_max_ports*sizeof(Port); size.system += erts_timer_wheel_memory_size();#ifdef SYS_TMP_BUF_SIZE size.system += SYS_TMP_BUF_SIZE; /* tmp_buf in sys on vxworks & ose */#endif /* Misc stuff ... */ size.system += erts_sys_misc_mem_sz(); size.system += erts_dist_table_size(); size.system += erts_node_table_size(); size.system += erts_bits_bufs_size(); size.system += process_reg_sz(); erts_fix_info(ERTS_ALC_T_REG_PROC, &efi); size.system += efi.total; erts_fix_info(ERTS_ALC_T_PROC_LIST, &efi); size.system += efi.total; /* Atom, binary, code, and ets */ size.system += size.atom; size.system += size.binary; size.system += size.code; size.system += size.ets; size.total = size.system + size.processes; } if (block) erts_smp_release_system(); if (print_to_p) { int i; int to = *print_to_p; void *arg = print_to_arg; /* Print result... */ erts_print(to, arg, "=memory\n"); for (i = 0; i < length; i++) erts_print(to, arg, "%T: %bpu\n", atoms[i], *uintps[i]); } if (proc) { /* Build erlang term result... */ Uint *hp; Uint **hpp; Uint hsz; Uint *hszp; hpp = NULL; hsz = 0; hszp = &hsz; while (1) { int i; for (i = 0; i < length; i++) euints[i] = erts_bld_uint(hpp, hszp, *uintps[i]); res = erts_bld_2tup_list(hpp, hszp, length, atoms, euints); if (hpp) break; hp = HAlloc((Process *) proc, hsz); hpp = &hp; hszp = NULL; } } return res;#undef MEM_NEED_PARTS}struct aa_values { Uint arity; const char *name; Uint ui[2];};Etermerts_allocated_areas(int *print_to_p, void *print_to_arg, void *proc){#define MAX_AA_VALUES \ (20 + (ERTS_ALC_N_MAX_A_FIXED_SIZE - ERTS_ALC_N_MIN_A_FIXED_SIZE + 1)) struct aa_values values[MAX_AA_VALUES]; Eterm res = THE_NON_VALUE; int i, length; ErtsFixInfo efi; Uint reserved_atom_space, atom_space; i = 0; if (erts_instr_stat) { values[i].arity = 2; values[i].name = "total"; values[i].ui[0] = erts_instr_get_total(); i++; values[i].arity = 2; values[i].name = "maximum"; values[i].ui[0] = erts_instr_get_max_total(); i++; } values[i].arity = 3; values[i].name = "processes"; values[i].ui[0] = erts_get_tot_proc_mem(); values[i].ui[1] = erts_get_tot_proc_mem(); erts_fix_info(ERTS_ALC_T_NLINK_SH, &efi); values[i].ui[1] += efi.total - efi.used; erts_fix_info(ERTS_ALC_T_MONITOR_SH, &efi); values[i].ui[1] += efi.total - efi.used; erts_fix_info(ERTS_ALC_T_PROC, &efi); values[i].ui[1] += efi.total - efi.used; erts_fix_info(ERTS_ALC_T_REG_PROC, &efi); values[i].ui[1] += efi.total - efi.used; i++; values[i].arity = 2; values[i].name = "ets"; values[i].ui[0] = erts_ets_memory_size(); i++; values[i].arity = 2; values[i].name = "sys_misc"; values[i].ui[0] = erts_sys_misc_mem_sz(); i++; values[i].arity = 2; values[i].name = "static"; values[i].ui[0] = erts_max_ports*sizeof(Port) /* Port table */ + erts_timer_wheel_memory_size() /* Timer wheel */#ifdef SYS_TMP_BUF_SIZE + SYS_TMP_BUF_SIZE /* tmp_buf in sys on vxworks & ose */#endif ; i++; erts_atom_get_text_space_sizes(&reserved_atom_space, &atom_space); values[i].arity = 3; values[i].name = "atom_space"; values[i].ui[0] = reserved_atom_space; values[i].ui[1] = atom_space; i++; values[i].arity = 2; values[i].name = "binary"; values[i].ui[0] = erts_get_binaries_size(); i++; values[i].arity = 2; values[i].name = "atom_table"; values[i].ui[0] = atom_table_sz(); i++; values[i].arity = 2; values[i].name = "module_table"; values[i].ui[0] = module_table_sz(); i++; values[i].arity = 2; values[i].name = "export_table"; values[i].ui[0] = export_table_sz(); i++; values[i].arity = 2; values[i].name = "register_table"; values[i].ui[0] = process_reg_sz(); i++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?