⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_memory.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
}static INLINE voidwrote_area_aux(em_area *area, em_state *state, em_buf_queue *queue, int do_lock){    em_buffer *buf;    if (do_lock)	mutex_lock(&queue->mutex);    buf = queue->last;    ASSERT(area->ptr);    ASSERT(area->size);    ASSERT(buf);    ASSERT(buf->data_end == area->ptr);    ASSERT(buf->end >= area->ptr + area->size);    buf->data_end = area->ptr + area->size;    area->ptr = NULL;    area->size = 0;    cond_signal(&queue->cond);    if (do_lock)	mutex_unlock(&queue->mutex);}static INLINE voidwrote_area(em_area *area, em_state *state, em_buf_queue *queue){    wrote_area_aux(area, state, queue, 1);}static voidget_next_write_area(em_area *area, em_state *state, em_buf_queue *queue,		    size_t size){    em_buffer *buf;    mutex_lock(&queue->mutex);    ASSERT(!area->size || area->ptr);     if (area->size)	wrote_area_aux(area, state, queue, 0);    buf = ((queue->last && queue->last->end - queue->last->data_end >= size)	   ? queue->last	   : enqueue(state, queue, size));    if (buf) {	ASSERT(buf->end - buf->data_end >= size);	area->ptr = buf->data_end;	area->size = buf->end - buf->data_end;    }    else {	area->ptr = NULL;	area->size = 0;    }    if (queue->tot_buf_size > queue->max_buf_size) {	fprintf(stderr,		"emem: Maximum %s buffer size (%lu) exceeded. "		"Terminating...\n",		queue->name,		(unsigned long) queue->max_buf_size);	exit(1);    }    mutex_unlock(&queue->mutex);}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Output                                                                  * *                                                                         *\*                                                                         */static INLINE size_twrite_str(usgnd_int_8 **dstpp, char *srcp){    size_t i = 0;    if (dstpp)	while (srcp[i])	    *((*dstpp)++) = (usgnd_int_8) srcp[i++];    else	while (srcp[i]) i++;    return i;}static size_twrite_strings(usgnd_int_8 **ptr,	      char **strings,	      char *first_line_prefix,	      char *line_prefix,	      size_t max_line_size){    size_t size;    size_t tot_size = 0;    size_t line_size = 0;    size_t line_prefix_size;    sgnd_int_32 ix;    tot_size = line_size = line_prefix_size = write_str(ptr, first_line_prefix);    for (ix = 0; strings[ix]; ix++) {	size = write_str(NULL, strings[ix]);	if (line_size + 1 + size > max_line_size) {	    tot_size += write_str(ptr, "\n");	    tot_size += write_str(ptr, line_prefix);	    line_size = line_prefix_size;	}	tot_size += write_str(ptr, " ");	tot_size += ptr ? write_str(ptr, strings[ix]) : size;	line_size += 1 + size;    }    tot_size += write_str(ptr, "\n");    return tot_size;}static size_twrite_title(usgnd_int_8 **bufp, size_t *overflow, size_t width, char *str){    size_t i, sz, ws;    usgnd_int_8 *p, *endp;    /*     * Writes at least one '|' character at the beginning.     * Right aligns "str".     * If "str" is larger than "width - 1" and overflow is NULL,     * then "str" is trucated; otherwise, string is not truncated.     */    if (width <= 0)	return 0;    if (!bufp && !overflow)	return width;    sz = strlen(str) + 1;    if (sz > width) {	ws = 0;	if (overflow)	    *overflow += sz - width;	else	    sz = width;    }    else {	ws = width - sz;	if (overflow) {	    if (ws >= *overflow) {		ws -= *overflow;		*overflow = 0;	    }	    else {		*overflow -= ws;		ws = 0;	    }	}	sz += ws;    }    if (!bufp)	return sz;    p = *bufp;    endp = p + width;    *(p++) = '|';    while (ws > 1) {	ws--;	*(p++) = (usgnd_int_8) ' ';    }    i = 0;    while (str[i] && (overflow || p < endp))	*(p++) = (usgnd_int_8) str[i++];    while (ws) {	ws--;	*(p++) = (usgnd_int_8) ' ';    }    ASSERT(overflow || p == endp);    ASSERT(sz == (size_t) (p - *bufp));    *bufp = p;    return sz;}static size_twrite_obj_sub_titles(em_state *state, usgnd_int_8 **bufp, size_t *overflow){    size_t field_width = state->output.field_width;    size_t size = write_title(bufp, overflow, field_width, "size");    if (state->output.max_min_values) {	size += write_title(bufp, overflow, field_width, "min size");	size += write_title(bufp, overflow, field_width, "max size");    }    if (state->output.block_counts) {	size += write_title(bufp, overflow, field_width, "no");	if (state->output.max_min_values) {	    size += write_title(bufp, overflow, field_width,  "min no");	    size += write_title(bufp, overflow, field_width,  "max no");	}    }    if (state->output.op_counts) {	size += write_title(bufp, overflow, field_width, "alloc()");	size += write_title(bufp, overflow, field_width, "realloc()");	size += write_title(bufp, overflow, field_width, "free()");    }    return size;}static size_twrite_header(em_state *state, usgnd_int_8 *ptr, int trunc){#define MIN_LTEXT_SZ 18#define HEADER_EOL_STR "|\n"    usgnd_int_8 *p;    usgnd_int_8 **pp;    int i;    size_t overflow;    size_t *ofp;    size_t obj_size = state->output.values_per_object*state->output.field_width;    size_t size = 0;    int have_seg_crr = state->trace_info.have_segment_carrier_info;    if (ptr) {	p = ptr;	pp = &p;    }    else {	p = NULL;	pp = NULL;    }    overflow = 0;    ofp = trunc ? NULL : &overflow;    size += write_title(pp, ofp, EM_TIME_FIELD_WIDTH, "time");    if (state->output.total) {	int no = 1;	if (have_seg_crr) {	    if (state->info.allctr_prv_crr[state->trace_info.segment_ix])		no++;	    if (state->info.allctr_usd_crr[state->trace_info.segment_ix])		no++;	}	size += write_title(pp, ofp, (have_seg_crr ? 3 : 1)*obj_size, "total");    }    for (i = 0; i < state->output.no_allctrs; i++) {	int no = 1;	if (state->info.allctr_prv_crr[state->output.allctrs[i].ix])	    no++;	if (state->info.allctr_usd_crr[state->output.allctrs[i].ix])	    no++;	size += write_title(pp, ofp, no*obj_size, state->output.allctrs[i].name);    }    for (i = 0; i < state->output.no_btypes; i++)	size += write_title(pp, ofp, obj_size, state->output.btypes[i].name);    size += write_str(pp, HEADER_EOL_STR);    overflow = 0;    size += write_title(pp, ofp, EM_TIME_FIELD_WIDTH, "");    if (state->output.total) {	size += write_title(pp, ofp, obj_size, (obj_size <= MIN_LTEXT_SZ						? "alcd blks"						: "allocated blocks"));	if (have_seg_crr) {	    if (state->info.allctr_prv_crr[state->trace_info.segment_ix])		size += write_title(pp, ofp, obj_size, (obj_size <= MIN_LTEXT_SZ							? "mpd segs"							: "mapped segments"));	    if (state->info.allctr_usd_crr[state->trace_info.segment_ix])		size += write_title(pp, ofp, obj_size, (obj_size <= MIN_LTEXT_SZ							? "chd segs"							: "cached segments"));	}    }    for (i = 0; i < state->output.no_allctrs; i++) {	size += write_title(pp, ofp, obj_size, (obj_size <= MIN_LTEXT_SZ						? "alcd blks"						: "allocated blocks"));	if (state->info.allctr_prv_crr[state->output.allctrs[i].ix])	    size += write_title(pp, ofp, obj_size, (obj_size <= MIN_LTEXT_SZ						    ? "prvd crrs" 						    : "provided carriers"));	if (state->info.allctr_usd_crr[state->output.allctrs[i].ix])	    size += write_title(pp, ofp, obj_size, (obj_size <= MIN_LTEXT_SZ						    ? "usd crrs"						    : "used carriers"));    }    for (i = 0; i < state->output.no_btypes; i++)	size += write_title(pp, ofp, obj_size, (obj_size <= MIN_LTEXT_SZ						? "alcd blks"						: "allocated blocks"));    size += write_str(pp, HEADER_EOL_STR);    overflow = 0;    size += write_title(pp, ofp, EM_TIME_FIELD_WIDTH, "");     if (state->output.total) {	size += write_obj_sub_titles(state, pp, ofp);	if (have_seg_crr) {	    if (state->info.allctr_prv_crr[state->trace_info.segment_ix])		size += write_obj_sub_titles(state, pp, ofp);	    if (state->info.allctr_usd_crr[state->trace_info.segment_ix])		size += write_obj_sub_titles(state, pp, ofp);	}    }    for (i = 0; i < state->output.no_allctrs; i++) {	size += write_obj_sub_titles(state, pp, ofp);	if (state->info.allctr_prv_crr[state->output.allctrs[i].ix])	    size += write_obj_sub_titles(state, pp, ofp);	if (state->info.allctr_usd_crr[state->output.allctrs[i].ix])	    size += write_obj_sub_titles(state, pp, ofp);    }    for (i = 0; i < state->output.no_btypes; i++)	size += write_obj_sub_titles(state, pp, ofp);    size += write_str(pp, HEADER_EOL_STR);#undef MIN_LTEXT_SZ#undef HEADER_EOL_STR    return size;}static INLINE voidwrite_mem_info(em_state *state, usgnd_int_8 **p, em_mem_info *mi){    int fw = state->output.field_width - 1;    *p += sprintf(*p, "%*" USGND_INT_MAX_FSTR " ", fw, mi->size);    if (state->output.max_min_values)	*p += sprintf(*p,		      "%*" USGND_INT_MAX_FSTR		      " %*" USGND_INT_MAX_FSTR " ",		      fw, mi->min_size,		      fw, mi->max_size);    if (state->output.block_counts) {	*p += sprintf(*p, "%*" USGND_INT_MAX_FSTR " ", fw, mi->no);	if (state->output.max_min_values)	    *p += sprintf(*p,			  "%*" USGND_INT_MAX_FSTR			  " %*" USGND_INT_MAX_FSTR " ",			  fw, mi->min_no,			  fw, mi->max_no);    }    if (state->output.op_counts)	*p += sprintf(*p,		      "%*" USGND_INT_MAX_FSTR		      " %*" USGND_INT_MAX_FSTR		      " %*" USGND_INT_MAX_FSTR " ",		      fw, mi->allocs,		      fw, mi->reallocs,		      fw, mi->frees);    /* Update max ever values */    if (mi->max_ever_size < mi->max_size)	mi->max_ever_size = mi->max_size;    if (mi->max_ever_no < mi->max_no)	mi->max_ever_no = mi->max_no;    /* Reset max/min values */    mi->max_size = mi->min_size = mi->size;    mi->max_no = mi->min_no = mi->no;}static INLINE voidwrite_max_ever_mem_info(em_state *state, usgnd_int_8 **p, em_mem_info *mi){    int fw = state->output.field_width - 1;    *p += sprintf(*p, "%*" USGND_INT_MAX_FSTR " ", fw, mi->max_ever_size);    if (state->output.max_min_values)	*p += sprintf(*p, "%*s %*s ", fw, "", fw, "");    if (state->output.block_counts) {	*p += sprintf(*p, "%*" USGND_INT_MAX_FSTR " ", fw, mi->max_ever_no);	if (state->output.max_min_values)	    *p += sprintf(*p, "%*s %*s ", fw, "", fw, "");    }    if (state->output.op_counts)	*p += sprintf(*p, "%*s %*s %*s ", fw, "", fw, "", fw, "");}static voidprint_string(em_state *state, char *str){    em_area area = {NULL, 0};    usgnd_int_8 *p;    /* Get area */    get_next_write_area(&area,state,&state->output.queue,write_str(NULL,str));    p = (usgnd_int_8 *) area.ptr;    area.size = write_str(&p, str);    /* Leave area */    wrote_area(&area, state, &state->output.queue);}static intprint_emu_arg(em_state *state){    em_area area = {NULL, 0};    char hostname[100];    char carg[22];    struct sockaddr_in saddr;    struct hostent *hp;    struct in_addr iaddr;    usgnd_int_16 port;    int saddr_size = sizeof(saddr);    size_t size;    char *format = "> Emulator command line argument: +Mit %s\n";    if (getsockname(state->input.socket,		    (struct sockaddr *) &saddr,		    &saddr_size) != 0)	goto error;        port = ntohs(saddr.sin_port);    ASSERT(state->input.listen_port == 0 || state->input.listen_port == port);    state->input.listen_port = port;    if (gethostname(hostname, sizeof(hostname)) != 0)	goto error;    hp = gethostbyname(hostname);    if (!hp)	goto error;    if (hp->h_addr_list) {	(void) memcpy(&iaddr.s_addr, *hp->h_addr_list, sizeof(iaddr.s_addr));	(void) sprintf(carg, "%s:%d", inet_ntoa(iaddr), (int) port);    }    else	(void) sprintf(carg, "127.0.0.1:%d", (int) port);#if EMEM_d_SWITCH    if (state->output.erl_cmd_file) {	fprintf(state->output.erl_cmd_file, "+Mit %s\n", carg);	fclose(state->output.erl_cmd_file);	state->output.erl_cmd_file = NULL;    }#endif    size = strlen(format) + strlen(carg);    /* Get area */    get_next_write_area(&area, state, &state->output.queue, size);    area.size = sprintf(area.ptr, format, carg);    /* Leave area */    wrote_area(&area, state, &state->output.queue);    return 0; error:    return GET_SOCK_ERRNO();}static size_twrite_allocator_info(em_state *state, usgnd_int_8 *ptr){    usgnd_int_32 aix, i, j;    char *header =	"> Allocator information:\n";    char *allctr_str =	">    * Allocator:";    char *crr_prv_str =	">       * Carrier providers:";    char *blk_tp_str =	">       * Block types:";    char *line_prefix =	">         ";    size_t size = 0;    char **strings;    size_t strings_size;    size_t max_line_size = 80;    usgnd_int_8 *p = ptr;    usgnd_int_8 **pp = ptr ? &p : NULL;    strings_size = state->trace_info.max_block_type_ix + 1;    if (strings_size < state->trace_info.max_allocator_ix + 1)	strings_size = state->trace_info.max_allocator_ix + 1;    strings = (char **) (*state->alloc)((strings_size + 1)*sizeof(char *));    if (!strings)	error(ENOMEM);    size += write_str(pp, header);    for (aix = 0; aix <= state->trace_info.max_allocator_ix; aix++) {	emtp_allocator *allctr = state->trace_info.allocator[aix];	if (!allctr->valid)	    continue;	strings[0] = allctr->name;	strings[1] = NULL;	size += write_strings(pp,strings,allctr_str,line_prefix,max_line_size);	i = 0;	if (allctr->carrier.provider)	    for (j = 0; j < allctr->carrier.no_providers; j++) {		usgnd_int_32 cpix = allctr->carrier.provider[j];

⌨️ 快捷键说明

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