📄 erl_instrument.c
字号:
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 ((Uint) 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 ((Uint) bp->mem > MAX_SMALL) { ptr = uint_to_big((Uint) bp->mem, hp); hp += BIG_UINT_HEAP_SIZE; } else ptr = make_small((Uint) 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;}static ERTS_INLINE voidbegin_new_max_period(Stat_t *stat, int min, int max){ int i; for (i = min; i <= max; i++) { stat[i].max_size = stat[i].size; stat[i].max_blocks = stat[i].blocks; }}static ERTS_INLINE voidupdate_max_ever_values(Stat_t *stat, int min, int max){ int i; for (i = min; i <= max; i++) { if (stat[i].max_size_ever < stat[i].max_size) stat[i].max_size_ever = stat[i].max_size; if (stat[i].max_blocks_ever < stat[i].max_blocks) stat[i].max_blocks_ever = stat[i].max_blocks; }}#define bld_string erts_bld_string#define bld_tuple erts_bld_tuple#define bld_tuplev erts_bld_tuplev#define bld_list erts_bld_list#define bld_2tup_list erts_bld_2tup_list#define bld_uint erts_bld_uintEtermerts_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;}static voiddump_stat_to_stream(FILE *fp, int begin_max_period){ ErtsAlcType_t i, a_max, a_min; erts_mtx_lock(&instr_mutex); fprintf(fp, "{instr_vsn,%lu}.\n", (unsigned long) ERTS_INSTR_VSN); update_max_ever_values(&stats->tot, 0, 0); fprintf(fp, "{total,[{total,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}]}.\n", stats->tot.size, stats->tot.max_size, stats->tot.max_size_ever, stats->tot.blocks, stats->tot.max_blocks, stats->tot.max_blocks_ever); a_max = 0; a_min = ~0; for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) { if (erts_allctrs_info[i].enabled) { if (a_min > i) a_min = i; if (a_max < i) a_max = i; } } ASSERT(ERTS_ALC_A_MIN <= a_min && a_min <= ERTS_ALC_A_MAX); ASSERT(ERTS_ALC_A_MIN <= a_max && a_max <= ERTS_ALC_A_MAX); ASSERT(a_min <= a_max); update_max_ever_values(stats->a, a_min, a_max); for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) { if (erts_allctrs_info[i].enabled) { fprintf(fp, "%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s", i == a_min ? "{allocators,\n [" : " ", ERTS_ALC_A2AD(i), stats->a[i].size, stats->a[i].max_size, stats->a[i].max_size_ever, stats->a[i].blocks, stats->a[i].max_blocks, stats->a[i].max_blocks_ever, i == a_max ? "]}.\n" : ",\n"); } } update_max_ever_values(stats->c, ERTS_ALC_C_MIN, ERTS_ALC_C_MAX); for (i = ERTS_ALC_C_MIN; i <= ERTS_ALC_C_MAX; i++) { fprintf(fp, "%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s", i == ERTS_ALC_C_MIN ? "{classes,\n [" : " ", ERTS_ALC_C2CD(i), stats->c[i].size, stats->c[i].max_size, stats->c[i].max_size_ever, stats->c[i].blocks, stats->c[i].max_blocks, stats->c[i].max_blocks_ever, i == ERTS_ALC_C_MAX ? "]}.\n" : ",\n" ); } update_max_ever_values(stats->n, ERTS_ALC_N_MIN, ERTS_ALC_N_MAX); for (i = ERTS_ALC_N_MIN; i <= ERTS_ALC_N_MAX; i++) { fprintf(fp, "%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s", i == ERTS_ALC_N_MIN ? "{types,\n [" : " ", ERTS_ALC_N2TD(i), stats->n[i].size, stats->n[i].max_size, stats->n[i].max_size_ever, stats->n[i].blocks, stats->n[i].max_blocks, stats->n[i].max_blocks_ever, i == ERTS_ALC_N_MAX ? "]}.\n" : ",\n" ); } if (begin_max_period) { begin_new_max_period(&stats->tot, 0, 0); begin_new_max_period(stats->a, a_min, a_max); begin_new_max_period(stats->c, ERTS_ALC_C_MIN, ERTS_ALC_C_MAX); begin_new_max_period(stats->n, ERTS_ALC_N_MIN, ERTS_ALC_N_MAX); } erts_mtx_unlock(&instr_mutex);}int erts_instr_dump_stat_to_fd(int fd, int begin_max_period){ char buf[BUFSIZ]; FILE *fp; if (!erts_instr_stat) return 0; fp = fdopen(fd, "w"); if (fp == NULL) return 0; /* Avoid allocating memory; we may have run out of it at this point. */ setbuf(fp, buf); dump_stat_to_stream(fp, begin_max_period); fflush(fp); return 1;}int erts_instr_dump_stat(const char *name, int begin_max_period){ FILE *file; if (!erts_instr_stat) return 0; file = fopen(name, "w"); if (file == NULL) return 0; dump_stat_to_stream(file, begin_max_period); fclose(file); return 1;}Uinterts_instr_get_total(void){ return erts_instr_stat ? stats->tot.size : 0;}Uinterts_instr_get_max_total(void){ if (erts_instr_stat) { update_max_ever_values(&stats->tot, 0, 0); return stats->tot.max_size_ever; } return 0;}Etermerts_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;}Uinterts_instr_init(int stat, int map_stat){ int i; am_tot = NULL; am_n = NULL; am_c = NULL; am_a = NULL; erts_instr_memory_map = 0; erts_instr_stat = 0; atoms_initialized = 0; if (!stat && !map_stat) return 0; stats = erts_alloc(ERTS_ALC_T_INSTR_INFO, sizeof(struct stats_)); erts_mtx_init(&instr_mutex, "instr"); erts_mtx_set_forksafe(&instr_mutex); mem_anchor = NULL; /* Install instrumentation functions */ ASSERT(sizeof(erts_allctrs) == sizeof(real_allctrs)); sys_memcpy((void *)real_allctrs,(void *)erts_allctrs,sizeof(erts_allctrs)); sys_memzero((void *) &stats->tot, sizeof(Stat_t)); sys_memzero((void *) stats->a, sizeof(Stat_t)*(ERTS_ALC_A_MAX+1)); sys_memzero((void *) stats->c, sizeof(Stat_t)*(ERTS_ALC_C_MAX+1)); sys_memzero((void *) stats->n, sizeof(Stat_t)*(ERTS_ALC_N_MAX+1)); for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) { if (erts_allctrs_info[i].enabled) stats->ap[i] = &stats->a[i]; else stats->ap[i] = &stats->a[ERTS_ALC_A_SYSTEM]; } if (map_stat) { erts_mtx_init(&instr_x_mutex, "instr_x"); erts_mtx_set_forksafe(&instr_x_mutex); erts_instr_memory_map = 1; erts_instr_stat = 1; for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) { erts_allctrs[i].alloc = map_stat_alloc; erts_allctrs[i].realloc = map_stat_realloc; erts_allctrs[i].free = map_stat_free; erts_allctrs[i].extra = (void *) &real_allctrs[i]; } return MAP_STAT_BLOCK_HEADER_SIZE; } else { erts_instr_stat = 1; for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) { erts_allctrs[i].alloc = stat_alloc; erts_allctrs[i].realloc = stat_realloc; erts_allctrs[i].free = stat_free; erts_allctrs[i].extra = (void *) &real_allctrs[i]; } return STAT_BLOCK_HEADER_SIZE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -