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

📄 erl_memory.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (state->output.allctrs)	    (*state->free)((void *) state->output.allctrs);	state->output.no_allctrs = state->trace_info.max_allocator_ix + 2;	state->output.allctrs = (*allocp)(state->output.no_allctrs					  * sizeof(em_output_types));	if (!state->output.allctrs)	    return ENOMEM;    }    for (i = -1; i <= state->trace_info.max_block_type_ix; i++) {	/* Save block type if we should print info about it */	emtp_block_type *btp = state->trace_info.block_type[i];	reset_mem_info(&state->info.btype[i]);	if (state->output.no_btypes) {	    if (state->output.all_btypes) {		state->output.btypes[i+1].name = btp->name;		state->output.btypes[i+1].ix = btp->valid ? i : -1;	    }	    else {		for (j = 0; j < state->output.no_btypes; j++)		    if (strcmp(btp->name, state->output.btypes[j].name) == 0) {			state->output.btypes[j].ix = i;			break;		    }	    }	}    }    /* Remove invalid block types */    if (state->output.no_btypes) {	for (i = 0, j = 0; i < state->output.no_btypes; i++) {	    if (state->output.btypes[i].ix >= 0) {		state->output.btypes[j].name = state->output.btypes[i].name;		state->output.btypes[j].ix = state->output.btypes[i].ix;		j++;	    }	}	state->output.no_btypes = j;    }    for (i = -1; i <= state->trace_info.max_allocator_ix; i++) {	/* Save allocator if we should print info about it */	emtp_allocator *ap = state->trace_info.allocator[i];	reset_mem_info(&state->info.allctr[i]);	if (state->output.no_allctrs) {	    if (state->output.all_allctrs) {		state->output.allctrs[i+1].name = ap->name;		state->output.allctrs[i+1].ix = ap->valid ? i : -1;	    }	    else {		for (j = 0; j < state->output.no_allctrs; j++)		    if (strcmp(ap->name, state->output.allctrs[j].name) == 0) {			state->output.allctrs[j].ix = i;			break;		    }	    }	}	/* Allocate em_mem_info if used carrier info is available */	if (ap->flags & EMTP_ALLOCATOR_FLAG_HAVE_USED_CARRIERS_INFO	    || (i == state->trace_info.segment_ix		&& state->trace_info.have_segment_carrier_info)) {			    state->info.allctr_usd_crr[i]		= (em_mem_info *) (*allocp)(sizeof(em_mem_info));	    if (!state->info.allctr_usd_crr[i])		return ENOMEM;	    reset_mem_info(state->info.allctr_usd_crr[i]);	}	/* Allocate em_mem_info for carrier providers */	if (ap->carrier.provider) {	    sgnd_int_32 j;	    for (j = 0; j < ap->carrier.no_providers; j++) {		sgnd_int_32 crr_prvdr = ap->carrier.provider[j];		if (!state->info.allctr_prv_crr[crr_prvdr]) {		    state->info.allctr_prv_crr[crr_prvdr]			= (em_mem_info *) (*allocp)(sizeof(em_mem_info));		    if (!state->info.allctr_prv_crr[crr_prvdr])			return ENOMEM;		    reset_mem_info(state->info.allctr_prv_crr[crr_prvdr]);		}	    }	}    }    /* Remove invalid allocators */    if (state->output.no_allctrs) {	for (i = 0, j = 0; i < state->output.no_allctrs; i++) {	    if (state->output.allctrs[i].ix >= 0) {		state->output.allctrs[j].name = state->output.allctrs[i].name;		state->output.allctrs[j].ix = state->output.allctrs[i].ix;		j++;	    }	}	state->output.no_allctrs = j;    }    if (state->output.no_btypes) {	state->output.btypes = (*reallocp)(state->output.btypes,					   sizeof(em_output_types)					   * state->output.no_btypes);	if (!state->output.btypes)	    return ENOMEM;    }    if (state->output.no_allctrs) {	state->output.allctrs = (*reallocp)(state->output.allctrs,					    sizeof(em_output_types)					    * state->output.no_allctrs);	if (!state->output.allctrs)	    return ENOMEM;    }    vpo = 1;    if (state->output.max_min_values)	vpo += 2;    if (state->output.block_counts) {	vpo++;	if (state->output.max_min_values)	    vpo += 2;    }    if (state->output.op_counts)	vpo += 3;    state->output.values_per_object = vpo;    vpl = 0;    vpl++;					/* time */    if (state->output.total) {	vpl += vpo;				/* total allocated */	if (state->trace_info.have_segment_carrier_info) {	    vpl += vpo;				/* total carriers */	    vpl += vpo;				/* cached carriers */	}    }    for (i = 0; i < state->output.no_allctrs; i++) {	vpl += vpo;				/* allocated */	if (state->trace_info.have_carrier_info) {	    if (state->info.allctr_prv_crr[state->output.allctrs[i].ix])		vpl += vpo;			/* provided carriers */	    vpl += vpo;				/* used carriers */	}    }    vpl += state->output.no_btypes*vpo;		/* allocated */    state->output.values_per_line = vpl;    state->output.header_size = write_header(state, NULL, 1);    state->output.header = (*state->alloc)(state->output.header_size + 1);    if (!state->output.header)	return ENOMEM;    size = write_header(state, state->output.header, 1);    ASSERT(state->output.header_size == size);    return 0;}static intprocess_trace(em_state *state){    emtp_operation ops[EM_NO_OF_OPS];    int res;    size_t ops_len;    em_area area;    while (1) {	get_next_read_area(&area, state, &state->input.queue);	if (!area.size)	    return EM_TRUNCATED_TRACE_ERROR;	res = emtp_parse(state->trace_state,			 &area.ptr, &area.size,			 NULL, 0, NULL);	if (res == EMTP_HEADER_PARSED)	    break;	if (res == EMTP_NEED_MORE_TRACE)	    continue;	if (res < 0)	    return res;	else	    return EM_TRUNCATED_TRACE_ERROR;    }	    res = complete_state(state);    if (res != 0)	return res;    print_main_header(state);    while (1) {	if (!area.size) {	    get_next_read_area(&area, state, &state->input.queue);	    if (!area.size)		return EM_TRUNCATED_TRACE_ERROR;	}	while (area.size) {	    ops_len = EM_NO_OF_OPS;	    res = emtp_parse(state->trace_state,			     &area.ptr, &area.size,			     ops, sizeof(emtp_operation), &ops_len);	    if (res < 0)		return res;	    res = insert_operations(state, ops, ops_len);	    if (res != 0)		return res;	}    }}static voidusage(char *sw, char *error){    int status = 0;    FILE *filep = stdout;#ifdef __WIN32__#define SW_CHAR "/"#else#define SW_CHAR "-"#endif    if (error) {	ASSERT(sw);	status = 1;	filep = stderr;	fprintf(filep, "emem: %s: %s\n", sw, error);    }    fprintf(filep,	    "Usage: emem "#if EMEM_A_SWITCH	    "[" SW_CHAR "A <ALLOCATOR>] "#endif	    "[" SW_CHAR "a <ALLOCATOR>] "	    "[" SW_CHAR "b <BLOCK TYPE>] "#if EMEM_C_SWITCH	    "[" SW_CHAR "C <CLASS>] "#endif#if EMEM_c_SWITCH	    "[" SW_CHAR "c <CLASS>] "#endif	    "{"#if EMEM_d_SWITCH	    SW_CHAR "d <DIRNAME>|"#endif	    SW_CHAR "f <FILENAME>} "	    "[" SW_CHAR "h] "	    "[" SW_CHAR "i <SECONDS>] "	    "[" SW_CHAR "m] "	    "[" SW_CHAR "n] "	    "[" SW_CHAR "o] "	    "{" SW_CHAR "p <PORT>} "	    "[" SW_CHAR "t] "	    "[" SW_CHAR "v] "	    "\n");    if (error)	exit(1);    else {	char *help_str =	    "\n"	    "  []        - switch is allowed any number of times\n"	    "  {}        - switch is allowed at most one time\n"#if EMEM_d_SWITCH	    "  |         - exclusive or\n"#endif	    "\n"	    " Switches:\n"#if EMEM_A_SWITCH	    "  " SW_CHAR "a <A>    - display info about Allocator <A> and all block types using <A>\n"#endif	    "  " SW_CHAR "a <A>    - display info about allocator <A>\n"	    "  " SW_CHAR "b <B>    - display info about block type <B>\n"#if EMEM_C_SWITCH	    "  " SW_CHAR "C <C>    - display info about class <C> and all block types in class <C>\n"#endif#if EMEM_c_SWITCH	    "  " SW_CHAR "b <B>    - display info about class <C>\n"#endif#if EMEM_d_SWITCH	    "  " SW_CHAR "d <D>    - run as daemon and set output directory to <D>\n"#endif	    "  " SW_CHAR "f <F>    - set output file to <F>\n"	    "  " SW_CHAR "h        - display help and exit\n"	    "  " SW_CHAR "i <I>    - set display interval to <I> seconds\n"	    "  " SW_CHAR "m        - display max/min values\n"	    "  " SW_CHAR "n        - display block/carrier/segment count values\n"	    "  " SW_CHAR "o        - display operation count values\n"	    "  " SW_CHAR "p <P>    - set listen port to <P>\n"	    "  " SW_CHAR "t        - display info about total values\n"	    "  " SW_CHAR "v        - verbose output\n";	fprintf(filep, help_str);	exit(0);    }#undef SW_CHAR}static voidparse_args(em_state *state, int argc, char *argv[]){    int port;    int i;    port = -1;    i = 1;    while (i < argc) {	if ((argv[i][0] != '-' && argv[i][0] != '/') || argv[i][2] != '\0') {	unknown_switch:	    usage(argv[i], "unknown switch");	}	switch (argv[i][1]) {#if EMEM_A_SWITCH	case 'A': /* TODO: Allocator + blocktypes using allocator */#endif	case 'a':	    if (i + 1 >= argc)		usage(argv[i], "missing allocator");	    i++;	    if (state->output.all_allctrs || strcmp(argv[i],"all") == 0) {		state->output.all_allctrs = 1;		break;	    }	    if (!state->output.allctrs)		state->output.allctrs		    = (*state->alloc)(sizeof(em_output_types)*argc/2);	    if (!state->output.allctrs)		error(ENOMEM);	    state->output.allctrs[state->output.no_allctrs].name = argv[i];	    state->output.allctrs[state->output.no_allctrs].ix = -1;	    state->output.no_allctrs++;	    break;	case 'b':	    if (i + 1 >= argc)		usage(argv[i], "missing block type");	    i++;	    if (state->output.all_btypes || strcmp(argv[i],"all") == 0) {		state->output.all_btypes = 1;		break;	    }	    if (!state->output.btypes)		state->output.btypes		    = (*state->alloc)(sizeof(em_output_types)*argc/2);	    if (!state->output.btypes)		error(ENOMEM);	    state->output.btypes[state->output.no_btypes].name = argv[i];	    state->output.btypes[state->output.no_btypes].ix = -1;	    state->output.no_btypes++;	    break;#if EMEM_C_SWITCH#endif#if EMEM_c_SWITCH	case 'c':	    break;#endif#if EMEM_d_SWITCH	case 'd': {	    char *p;	    char *fname;	    if (state->output.dir_name)		usage(argv[i], "directory already set");	    if (state->output.file_name)		usage(argv[i], "file name already set");	    if (i + 1 >= argc)		usage(argv[i], "missing directory name");	    state->output.dir_name = argv[i+1];	    fname = (*state->alloc)(strlen(state->output.dir_name)				    + 1				    + strlen(EM_ERL_CMD_FILE_NAME)				    + 1);	    state->output.go.mutex = (*state->alloc)(sizeof(ethr_mutex));	    state->output.go.cond = (*state->alloc)(sizeof(ethr_cond));	    if (!fname || !state->output.go.mutex || !state->output.go.cond)		error(ENOMEM);	    p = fname;	    (void) write_str(&p, state->output.dir_name);	    *(p++) = DIR_SEP_CHAR;	    (void) write_str(&p, EM_ERL_CMD_FILE_NAME);	    *(p++) = '\0';	    state->output.erl_cmd_file = fopen(fname, "w");	    if (!state->output.erl_cmd_file)		usage(argv[i], "cannot create files in directory");	    (*state->free)((void *) fname);	    state->output.stream = NULL;	    mutex_init(state->output.go.mutex);	    cond_init(state->output.go.cond);	    i++;	    break;	}#endif	case 'f':#if EMEM_d_SWITCH	    if (state->output.dir_name)		usage(argv[i], "directory already set");#endif	    if (state->output.file_name)		usage(argv[i], "file name already set");	    if (i + 1 >= argc)		usage(argv[i], "missing file name");	    state->output.file_name = argv[i+1];	    state->output.stream = fopen(state->output.file_name, "w");	    if (!state->output.stream)		usage(argv[i], "cannot create file");	    if (setvbuf(state->output.stream, NULL, _IONBF, 0) != 0) {		fprintf(stderr,			"emem: failed to set file %s in unbuffered mode\n",			state->output.file_name);		exit(1);	    }	    i++;	    break;	case 'h':	    usage(NULL, NULL);	    break;	case 'i': {	    int interval;	    if (argv[i][2])		goto unknown_switch;	    if (i + 1 >= argc)		usage(argv[i], "missing interval");	    interval = atoi(argv[i+1]);	    if (interval < 1) 		usage(argv[i], "bad interval");	    i++;	    state->output.next_print_inc = interval;	    break;	}	case 'm':	    state->output.max_min_values = 1;	    break;	case 'n':	    state->output.block_counts = 1;	    break;	case 'o':	    state->output.op_counts = 1;	    break;	case 'p':	    if (state->input.listen_port)		usage(argv[i], "port already set");	    if (i + 1 >= argc)		usage(argv[i], "missing port number");	    port = atoi(argv[i+1]);	    if (port <= 1024 || port >= (1 << 16)) 		usage(argv[i], "bad port number");	    i++;	    state->input.listen_port = (usgnd_int_16) port;	    break;	case 't':	    state->output.total = 1;	    break;	case 'v':	    state->output.verbose = 1;	    break;	default:	    goto unknown_switch;	}	i++;    }    if (!state->output.allctrs && !state->output.btypes)	state->output.total = 1;}static intinit_connection(em_state *state){    int res;    SOCKET lsock;    SOCKET sock = INVALID_SOCKET;    struct sockaddr_in my_addr;    int oth_addr_len;    struct sockaddr_in oth_addr;#ifdef __WIN32__    WORD wVersionRequested = MAKEWORD(2,0);    WSADATA wsaData;    if (WSAStartup(wVersionRequested, &wsaData) != 0)	return EIO;    if ((LOBYTE(wsaData.wVersion) != 2) || (HIBYTE(wsaData.wVersion) != 0))	return EIO;#endif do_socket:    sock = socket(AF_INET, SOCK_STREAM, 0);    if (IS_INVALID_SOCKET(sock)) {	res = GET_SOCK_ERRNO();	if (res == EINTR)	    goto do_socket;	goto error;    }    memset((void *) &my_addr, 0, sizeof(struct sockaddr_in));    my_addr.sin_family = AF_INET;    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);    my_addr.sin_port = htons(state->input.listen_port); do_bind:    if (bind(sock, (struct sockaddr*) &my_addr, sizeof(my_addr)) < 0) {	res = GET_SOCK_ERRNO();	if (res == EINTR)	    goto do_bind;	goto error;    } do_listen:    if (listen(sock, 1) < 0) {	res = GET_SOCK_ERRNO();	if (res == EINTR)	

⌨️ 快捷键说明

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