Eterm erts_instr_get_type_info(Process *proc) { Eterm res, *tpls; Uint hsz, *hszp, *hp, **hpp; ErtsAlcType_t n; if (!am_n) init_am_n(); if (!am_a) init_am_a(); if (!am_c) init_am_c(); tpls = (Eterm *) erts_alloc(ERTS_ALC_T_TMP, (ERTS_ALC_N_MAX-ERTS_ALC_N_MIN+1) * sizeof(Eterm)); hsz = 0; hszp = &hsz; hpp = NULL; restart_bld: #if ERTS_ALC_N_MIN != 1 #error ERTS_ALC_N_MIN is not 1 #endif for (n = ERTS_ALC_N_MIN; n <= ERTS_ALC_N_MAX; n++) { ErtsAlcType_t t = ERTS_ALC_N2T(n); ErtsAlcType_t a = ERTS_ALC_T2A(t); ErtsAlcType_t c = ERTS_ALC_T2C(t); if (!erts_allctrs_info[a].enabled) a = ERTS_ALC_A_SYSTEM; tpls[n - ERTS_ALC_N_MIN] = bld_tuple(hpp, hszp, 3, am_n[n], am_a[a], am_c[c]); } res = bld_tuplev(hpp, hszp, ERTS_ALC_N_MAX-ERTS_ALC_N_MIN+1, tpls); if (!hpp) { hp = HAlloc(proc, hsz); hszp = NULL; hpp = &hp; goto restart_bld; } erts_free(ERTS_ALC_T_TMP, tpls); return res; }
Eterm erts_instr_get_stat(Process *proc, Eterm what, int begin_max_period) { int i, len, max, min, allctr; Eterm *names, *values, res; Uint arr_size, stat_size, hsz, *hszp, *hp, **hpp; Stat_t *stat_src, *stat; if (!erts_instr_stat) return am_false; if (!atoms_initialized) init_atoms(); if (what == am.total) { min = 0; max = 0; allctr = 0; stat_size = sizeof(Stat_t); stat_src = &stats->tot; if (!am_tot) init_am_tot(); names = am_tot; } else if (what == am.allocators) { min = ERTS_ALC_A_MIN; max = ERTS_ALC_A_MAX; allctr = 1; stat_size = sizeof(Stat_t)*(ERTS_ALC_A_MAX+1); stat_src = stats->a; if (!am_a) init_am_a(); names = am_a; } else if (what == am.classes) { min = ERTS_ALC_C_MIN; max = ERTS_ALC_C_MAX; allctr = 0; stat_size = sizeof(Stat_t)*(ERTS_ALC_C_MAX+1); stat_src = stats->c; if (!am_c) init_am_c(); names = &am_c[ERTS_ALC_C_MIN]; } else if (what == am.types) { min = ERTS_ALC_N_MIN; max = ERTS_ALC_N_MAX; allctr = 0; stat_size = sizeof(Stat_t)*(ERTS_ALC_N_MAX+1); stat_src = stats->n; if (!am_n) init_am_n(); names = &am_n[ERTS_ALC_N_MIN]; } else { return THE_NON_VALUE; } stat = (Stat_t *) erts_alloc(ERTS_ALC_T_TMP, stat_size); arr_size = (max - min + 1)*sizeof(Eterm); if (allctr) names = (Eterm *) erts_alloc(ERTS_ALC_T_TMP, arr_size); values = (Eterm *) erts_alloc(ERTS_ALC_T_TMP, arr_size); erts_mtx_lock(&instr_mutex); update_max_ever_values(stat_src, min, max); sys_memcpy((void *) stat, (void *) stat_src, stat_size); if (begin_max_period) begin_new_max_period(stat_src, min, max); erts_mtx_unlock(&instr_mutex); hsz = 0; hszp = &hsz; hpp = NULL; restart_bld: len = 0; for (i = min; i <= max; i++) { if (!allctr || erts_allctrs_info[i].enabled) { Eterm s[2]; if (allctr) names[len] = am_a[i]; s[0] = bld_tuple(hpp, hszp, 4, am.sizes, bld_uint(hpp, hszp, stat[i].size), bld_uint(hpp, hszp, stat[i].max_size), bld_uint(hpp, hszp, stat[i].max_size_ever)); s[1] = bld_tuple(hpp, hszp, 4, am.blocks, bld_uint(hpp, hszp, stat[i].blocks), bld_uint(hpp, hszp, stat[i].max_blocks), bld_uint(hpp, hszp, stat[i].max_blocks_ever)); values[len] = bld_list(hpp, hszp, 2, s); len++; } } res = bld_2tup_list(hpp, hszp, len, names, values); if (!hpp) { hp = HAlloc(proc, hsz); hszp = NULL; hpp = &hp; goto restart_bld; } erts_free(ERTS_ALC_T_TMP, (void *) stat); erts_free(ERTS_ALC_T_TMP, (void *) values); if (allctr) erts_free(ERTS_ALC_T_TMP, (void *) names); return res; }
Eterm erts_instr_get_memory_map(Process *proc) { MapStatBlock_t *org_mem_anchor; Eterm hdr_tuple, md_list, res; Eterm *hp; Uint hsz; MapStatBlock_t *bp; #ifdef DEBUG Eterm *end_hp; #endif if (!erts_instr_memory_map) return am_false; if (!atoms_initialized) init_atoms(); if (!am_n) init_am_n(); if (!am_c) init_am_c(); if (!am_a) init_am_a(); erts_mtx_lock(&instr_x_mutex); erts_mtx_lock(&instr_mutex); /* Header size */ hsz = 5 + 1 + (ERTS_ALC_N_MAX+1-ERTS_ALC_N_MIN)*(1 + 4); /* Memory data list */ for (bp = mem_anchor; bp; bp = bp->next) { if (is_internal_pid(bp->pid)) { #if (_PID_NUM_SIZE - 1 > MAX_SMALL) if (internal_pid_number(bp->pid) > MAX_SMALL) hsz += BIG_UINT_HEAP_SIZE; #endif #if (_PID_SER_SIZE - 1 > MAX_SMALL) if (internal_pid_serial(bp->pid) > MAX_SMALL) hsz += BIG_UINT_HEAP_SIZE; #endif hsz += 4; } if ((UWord) bp->mem > MAX_SMALL) hsz += BIG_UINT_HEAP_SIZE; if (bp->size > MAX_SMALL) hsz += BIG_UINT_HEAP_SIZE; hsz += 5 + 2; } hsz += 3; /* Root tuple */ org_mem_anchor = mem_anchor; mem_anchor = NULL; erts_mtx_unlock(&instr_mutex); hp = HAlloc(proc, hsz); /* May end up calling map_stat_alloc() */ erts_mtx_lock(&instr_mutex); #ifdef DEBUG end_hp = hp + hsz; #endif { /* Build header */ ErtsAlcType_t n; Eterm type_map; Uint *hp2 = hp; #ifdef DEBUG Uint *hp2_end; #endif hp += (ERTS_ALC_N_MAX + 1 - ERTS_ALC_N_MIN)*4; #ifdef DEBUG hp2_end = hp; #endif type_map = make_tuple(hp); *(hp++) = make_arityval(ERTS_ALC_N_MAX + 1 - ERTS_ALC_N_MIN); for (n = ERTS_ALC_N_MIN; n <= ERTS_ALC_N_MAX; n++) { ErtsAlcType_t t = ERTS_ALC_N2T(n); ErtsAlcType_t a = ERTS_ALC_T2A(t); ErtsAlcType_t c = ERTS_ALC_T2C(t); if (!erts_allctrs_info[a].enabled) a = ERTS_ALC_A_SYSTEM; *(hp++) = TUPLE3(hp2, am_n[n], am_a[a], am_c[c]); hp2 += 4; } ASSERT(hp2 == hp2_end); hdr_tuple = TUPLE4(hp, am.instr_hdr, make_small(ERTS_INSTR_VSN), make_small(MAP_STAT_BLOCK_HEADER_SIZE), type_map); hp += 5; } /* Build memory data list */ for (md_list = NIL, bp = org_mem_anchor; bp; bp = bp->next) { Eterm tuple; Eterm type; Eterm ptr; Eterm size; Eterm pid; if (is_not_internal_pid(bp->pid)) pid = am_undefined; else { Eterm c; Eterm n; Eterm s; #if (ERST_INTERNAL_CHANNEL_NO > MAX_SMALL) #error Oversized internal channel number #endif c = make_small(ERST_INTERNAL_CHANNEL_NO); #if (_PID_NUM_SIZE - 1 > MAX_SMALL) if (internal_pid_number(bp->pid) > MAX_SMALL) { n = uint_to_big(internal_pid_number(bp->pid), hp); hp += BIG_UINT_HEAP_SIZE; } else #endif n = make_small(internal_pid_number(bp->pid)); #if (_PID_SER_SIZE - 1 > MAX_SMALL) if (internal_pid_serial(bp->pid) > MAX_SMALL) { s = uint_to_big(internal_pid_serial(bp->pid), hp); hp += BIG_UINT_HEAP_SIZE; } else #endif s = make_small(internal_pid_serial(bp->pid)); pid = TUPLE3(hp, c, n, s); hp += 4; } #if ERTS_ALC_N_MAX > MAX_SMALL #error Oversized memory type number #endif type = make_small(bp->type_no); if ((UWord) bp->mem > MAX_SMALL) { ptr = uint_to_big((UWord) bp->mem, hp); hp += BIG_UINT_HEAP_SIZE; } else ptr = make_small((UWord) bp->mem); if (bp->size > MAX_SMALL) { size = uint_to_big(bp->size, hp); hp += BIG_UINT_HEAP_SIZE; } else size = make_small(bp->size); tuple = TUPLE4(hp, type, ptr, size, pid); hp += 5; md_list = CONS(hp, tuple, md_list); hp += 2; } res = TUPLE2(hp, hdr_tuple, md_list); ASSERT(hp + 3 == end_hp); if (mem_anchor) { for (bp = mem_anchor; bp->next; bp = bp->next) ; ASSERT(org_mem_anchor); org_mem_anchor->prev = bp; bp->next = org_mem_anchor; } else { mem_anchor = org_mem_anchor; } erts_mtx_unlock(&instr_mutex); erts_mtx_unlock(&instr_x_mutex); return res; }