hprof_thread.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 581 行 · 第 1/2 页

C
581
字号
    if (leading_comma) {        hprof_printf(",");    }    if (thread == NULL) {        hprof_printf(" <unknown thread>");    } else {        hprof_printf(" thread %d", thread->serial_num);    }}static hprof_thread_local_t *hprof_alloc_thread_local_info(void){    hprof_thread_local_t *info =        HPROF_CALLOC(ALLOC_TYPE_THREAD_LOCAL, sizeof(hprof_thread_local_t));        if (cpu_timing) {        char lockname[128];	static int lock_serial_number = 0;	        info->stack = HPROF_CALLOC(ALLOC_TYPE_METHOD_TIME,	    sizeof(hprof_method_time_t) * HPROF_STACK_LIMIT);	info->stack_top = info->stack;	info->stack_limit = HPROF_STACK_LIMIT;	sprintf(lockname, "_hprof_thread_local_lock-%d", lock_serial_number++);	info->table_lock = CALL(RawMonitorCreate)(lockname);	info->frames_array_limit = HPROF_FRAMES_ARRAY_LIMIT;	info->frames_array = HPROF_CALLOC(ALLOC_TYPE_JMETHODID,	    sizeof(jmethodID) * info->frames_array_limit);	info->cur_frame_index = 0;	info->table =	    HPROF_CALLOC(ALLOC_TYPE_HASH_TABLES + ALLOC_HASH_FRAMES_COST,	        sizeof(hprof_frames_cost_t *) * HPROF_FRAMES_TABLE_SIZE);#ifdef HASH_STATS        info->table_hits   = 0;        info->table_misses = 0;	info->thread_name  = NULL;	info->group_name   = NULL;	info->parent_name  = NULL;#endif /* HASH_STATS */	info->gc_start_time = jint_to_jlong(-1);    }        if (monitor_tracing) {        info->mon = HPROF_CALLOC(ALLOC_TYPE_CONTENDED_MONITOR,	    sizeof(hprof_contended_monitor_t));	info->mon->time = jint_to_jlong(-1);	info->mon->trace_serial_num = 0;	info->mon->num_hits = 0;    }        return info;}static void hprof_free_thread_local_info(JNIEnv *env_id){    hprof_thread_local_t *info =         (hprof_thread_local_t *)(CALL(GetThreadLocalStorage)(env_id));        if (info == NULL) {        fprintf(stderr, 		"HPROF ERROR: thread local table NULL for env_id = %p," 		" cannot free it\n", env_id);	return;    }    if (cpu_timing) {        hprof_frames_cost_t **table;	int i;#ifdef HASH_STATS	if (print_thread_hash_stats_on_exit) {	    hprof_print_per_thread_hash_stats(stderr, info);	}#endif /* HASH_STATS */	table = info->table;	for (i = 0; i < HPROF_FRAMES_TABLE_SIZE; i++) {            hprof_frames_cost_t *fc = table[i];	    while (fc != NULL) {	        hprof_frames_cost_t *next = fc->next;		hprof_free(fc);		fc = next;	    }	}	hprof_free(info->table);	CALL(RawMonitorDestroy)(info->table_lock);	hprof_free(info->stack);	hprof_free(info->frames_array);    }    if (monitor_tracing) {        hprof_free(info->mon);    }    CALL(SetThreadLocalStorage)(env_id,NULL);    hprof_free(info);}static void hprof_bill_frames_cost(hprof_frames_cost_t *fc, JNIEnv *env_id, jmethodID *frames){    jlong self_time = jlong_div(fc->self_time, jint_to_jlong(1000000));/* convert to ms */    jlong cost = jlong_zero;    int num_hits = fc->num_hits;    int bill_it = 0;                if ((timing_format == OLD_PROF_OUTPUT_FORMAT) && (num_hits > 0)) {        env_id = NULL;                   /* no thread info for old prof */	cost = jlong_div(fc->total_time, jint_to_jlong(1000000));    /* convert to ms */	bill_it = 1;    } else if ((timing_format == NEW_PROF_OUTPUT_FORMAT) &&	       CVMlongGt(self_time, jlong_zero)) {        cost = self_time;	bill_it = 1;    }        /* if we are billing */    if (bill_it) {        int i;	int n_frames = fc->num_frames;	hprof_trace_t *trace_tmp = hprof_alloc_tmp_trace(n_frames, env_id);        hprof_trace_t *result;	for (i = 0; i < n_frames; i++) {	    hprof_frame_t *frame = hprof_intern_jvmpi_frame(frames[i],-1);	    if (frame == NULL) {	        fprintf(stderr, 		    "HPROF ERROR: got a NULL frame in bill_frames_cost\n");		hprof_free(trace_tmp);		return;	    } 	    trace_tmp->frames[i] = frame;	}	result = hprof_intern_tmp_trace(trace_tmp);	/* bill the cost and num_hits and zero out the values in frames_cost	 * to prevent them from getting billed more than once */	result->cost = jlong_add(result->cost, cost);	result->num_hits += num_hits;	    	fc->self_time = jlong_zero;	fc->total_time = jlong_zero;	fc->num_hits = 0;    }}void hprof_bill_frames_cost_table(JNIEnv *env_id){    hprof_thread_local_t *info;    int i;    if (!cpu_timing && !monitor_tracing) {	return;    }    info = (hprof_thread_local_t *)(CALL(GetThreadLocalStorage)(env_id));    if (info == NULL) {        fprintf(stderr, 		"HPROF ERROR: thread local table NULL for env_id = %p," 		"cannot bill cost\n", env_id);	return;    }    CALL(RawMonitorEnter)(info->table_lock);    for (i = 0; i < HPROF_FRAMES_TABLE_SIZE; i++) {        hprof_frames_cost_t *fc = info->table[i];	while (fc) {	    hprof_bill_frames_cost(fc, env_id, 				   (info->frames_array + fc->frames_index));	    fc = fc->next;	}    }    CALL(RawMonitorExit)(info->table_lock);}static void *hprof_bill_thread_local_table(void *_thread, void * _arg){    hprof_thread_t *thread = _thread;    JNIEnv *env_id = thread->env_id;    hprof_bill_frames_cost_table(env_id);    return _arg;}    void hprof_bill_all_thread_local_tables(void) {    hprof_hash_iterate(&hprof_thread_table,		       hprof_bill_thread_local_table,		       NULL);}#ifdef HASH_STATSvoidhprof_print_per_thread_hash_stats(FILE *fp, hprof_thread_local_t *info){    unsigned int empties = 0;       /* number of empty slots */    unsigned int i;                 /* scratch index */    unsigned int prev_elems;        /* previous element count */    fprintf(fp, "\nThread Hash Table Statistics for '%s'\n\n",	info->thread_name->name);    fprintf(fp, "parent name='%s'  group name='%s'\n", info->parent_name->name,	info->group_name->name);    if (print_verbose_hash_stats) {	fprintf(fp, "Table Histogram:\n");	fprintf(fp, "'K'-1024 elements, '#'-100 elements, '@'-1 element\n");    }    prev_elems = 0;    /* skip leading empty slots */    for (i = 0; i < HPROF_FRAMES_TABLE_SIZE; i++) {	unsigned int        count;          /* # of markers to print */	unsigned int        elems = 0;      /* # of elements in slot */        hprof_frames_cost_t *fc;            /* element index */	unsigned int        saved_elems;    /* saved elems value */	for (fc = info->table[i]; fc != NULL; fc = fc->next) {	    elems++;	}	if (elems == 0) {    /* nothing in this slot */	    empties++;	    if (prev_elems != 0) {		if (print_verbose_hash_stats) fprintf(fp, "      ::\n");		prev_elems = 0;	    }	    continue;	}	saved_elems = elems;	if (print_verbose_hash_stats) {	    fprintf(fp, "%7u: ", i);	    count = elems / 1024;	    if (count != 0) {		elems -= count * 1024;		for (; count > 0; count--) fputc('K', fp);	    }	    count = elems / 100;	    if (count != 0) {		elems -= count * 100;		for (; count > 0; count--) fputc('#', fp);	    }	    for (; elems > 0; elems--) fputc('@', fp);	    fprintf(fp, " (%u)\n", saved_elems);	}	prev_elems = saved_elems;    }    fprintf(fp,	"#-hits=%u  #-misses=%u  empty-slots=%.2f%%  avg-#-elems=%.2f\n\n",        info->table_hits, info->table_misses,	((float)empties / HPROF_FRAMES_TABLE_SIZE) * 100.0,	(float)info->table_misses / (HPROF_FRAMES_TABLE_SIZE - empties));}void hprof_print_thread_hash_stats(FILE *fp) {    hprof_print_tbl_hash_stats(fp, &hprof_thread_table);}#endif /* HASH_STATS */#ifdef WATCH_ALLOCSstatic void * hprof_free_thread_table_helper(void *_thread, void *_arg){    hprof_thread_t *thread = _thread;    hprof_free_thread_local_info(thread->env_id);    return _arg;}void hprof_free_thread_table(void){    hprof_hash_iterate(&hprof_thread_table, hprof_free_thread_table_helper,	NULL);    hprof_hash_removeall(&hprof_thread_table);    hprof_hash_free(&hprof_thread_table);    /* empty the list of live threads */    {	live_thread_t *t;	for (t = live_thread_list; t != NULL; ) {	    live_thread_t *prev = t;  /* save the one we want to free */	    t = t->next;	    hprof_free(prev);	    num_live_threads--;	}    }}#endif /* WATCH_ALLOCS */

⌨️ 快捷键说明

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