void hprof_thread_end_event(JNIEnv *env_id)
{
    hprof_thread_t thread_tmp;
    hprof_thread_t *thread;
    
    CALL(RawMonitorEnter)(data_access_lock);
#ifdef XXX_HASH_STATS
{
    /* use the code to get current thread hash stats */
    static int done = 0;

    if (!done) {
	hprof_print_thread_hash_stats(stderr);
	done = 1;
    }
}
#endif /* HASH_STATS */

    {
        /* remove from list of live threads */
        live_thread_t **p;
	p = &live_thread_list;
	while (*p) {
	    live_thread_t *t = *p;
	    if (t->env == env_id) {
	        *p = t->next;
		hprof_free(t);
		break;
	    }
	    p = &(t->next);
	}
	num_live_threads--;
    }
    thread_tmp.env_id = env_id;
    thread = hprof_hash_lookup(&hprof_thread_table, &thread_tmp);
    if (thread == NULL) {
        fprintf(stderr, "HPROF ERROR : unknown thread ID in thread_end\n");
    } else {
        if (output_format == 'b') {
	    hprof_write_header(HPROF_END_THREAD, 4);
	    hprof_write_u4(thread->serial_num);
	} else if ((!cpu_timing) || (timing_format != OLD_PROF_OUTPUT_FORMAT)) {
	    /* we don't want thread info for the old prof output format */
	    hprof_printf("THREAD END (id = %d)\n", thread->serial_num);
	}
	if (cpu_timing) {
	    /* bill the thread local table if method timing is on */
	    hprof_bill_frames_cost_table(env_id);
	}
	if (cpu_timing || monitor_tracing) {
	    /* free the thread local table if we allocated one */
	    hprof_free_thread_local_info(env_id);
	}
	hprof_remove_thread(env_id);
    }
    CALL(RawMonitorExit)(data_access_lock);
}
Exemplo n.º 2
0
/* the callback thread */
static void
hprof_callback(void *p)
{
    while (hprof_is_on) {
        jint          length;
        jint          seq_num;
        unsigned char tag;

        tag = recv_u1();
        if (tag == HPROF_CMD_EOF) {
            /* the cmd socket has closed so the listener thread is done */
            break;
        }
        seq_num = recv_u4();
        length  = recv_u4();

	switch (tag) {
	case HPROF_CMD_GC:
	    CALL(RunGC)();
	    break;
	case HPROF_CMD_DUMP_HEAP: {
	    hprof_get_heap_dump();
	    break;
	}
	case HPROF_CMD_ALLOC_SITES: {
	    unsigned short flags = recv_u2();
	    unsigned int i_tmp = recv_u4();
	    float ratio = *(float *)(&i_tmp);
	    hprof_output_sites(flags, ratio);
	    break;
	}
	case HPROF_CMD_HEAP_SUMMARY: {
	    CALL(RawMonitorEnter)(data_access_lock);
	    hprof_write_header(HPROF_HEAP_SUMMARY, 24);
	    hprof_write_u4(total_live_bytes);
	    hprof_write_u4(total_live_instances);
	    hprof_write_u4(jlong_high(total_alloced_bytes));
	    hprof_write_u4(jlong_low(total_alloced_bytes));
	    hprof_write_u4(jlong_high(total_alloced_instances));
	    hprof_write_u4(jlong_low(total_alloced_instances));
	    CALL(RawMonitorExit)(data_access_lock);
	    break;
	}
	case HPROF_CMD_EXIT:
	    hprof_is_on = FALSE;
	    fprintf(stderr, 
		    "HPROF: received exit event, exiting ...\n");
	    CALL(ProfilerExit)((jint)0);
	case HPROF_CMD_DUMP_TRACES:
	    CALL(RawMonitorEnter)(data_access_lock);
	    hprof_output_unmarked_traces();
	    CALL(RawMonitorExit)(data_access_lock);
	    break;
	case HPROF_CMD_CPU_SAMPLES: {
	    unsigned short flags = recv_u2();
	    unsigned int i_tmp = recv_u4();
	    float ratio = *(float *)(&i_tmp);
	    hprof_output_trace_cost(ratio, CPU_SAMPLES_RECORD_NAME);
	    break;
	}
	case HPROF_CMD_CONTROL: {
	    unsigned short cmd = recv_u2();
	    if (cmd == 0x0001) {
	        CALL(EnableEvent)(JVMPI_EVENT_OBJ_ALLOC, NULL);
	    } else if (cmd == 0x0002) {
	        CALL(DisableEvent)(JVMPI_EVENT_OBJ_ALLOC, NULL);
	    } else if (cmd == 0x0003) {
	        hprof_objmap_t *thread_id = recv_id(); 
		hprof_cpu_sample_on(thread_id);
	    } else if (cmd == 0x0004) {
		hprof_objmap_t *thread_id = recv_id();
		hprof_cpu_sample_off(thread_id);
	    } else if (cmd == 0x0005) {
	        CALL(RawMonitorEnter)(data_access_lock);
	        hprof_clear_trace_cost();
		CALL(RawMonitorExit)(data_access_lock);
	    } else if (cmd == 0x0006) {
	        CALL(RawMonitorEnter)(data_access_lock);
		hprof_clear_site_table();
		CALL(RawMonitorExit)(data_access_lock);
	    } else if (cmd == 0x0007) {
	        max_trace_depth = recv_u2();
	    }
	    break;
	}
	default:
	    if (hprof_is_on) {
		hprof_is_on = FALSE;
	        fprintf(stderr,
			"HPROF ERROR : failed to recognize cmd %d, exiting..\n",
			(int)tag);
	    }
	    CALL(ProfilerExit)((jint)1);
	}
	CALL(RawMonitorEnter)(data_access_lock);
	hprof_flush();
	CALL(RawMonitorExit)(data_access_lock);
    }
}
void hprof_thread_start_event(JNIEnv *env_id,
			      char *t_name,
			      char *g_name,
			      char *p_name,
			      jobjectID thread_id,
			      int requested)
{
    hprof_thread_t *result;
    hprof_name_t *thread_name;
    hprof_name_t *group_name;
    hprof_name_t *parent_name;
    hprof_objmap_t *objmap;
    
    CALL(RawMonitorEnter)(data_access_lock);

    objmap = hprof_fetch_object_info(thread_id);
    
    if (objmap == NULL) {
        fprintf(stderr, "HPROF ERROR: unable to map JVMPI thread ID to hprof "
		"thread ID  in thread_start \n");
	goto threadstart_done;
    }

    result = hprof_intern_thread(env_id);
    if (result->thread_id != NULL) {
	goto threadstart_done;
    }

    {
	live_thread_t *newthread =
	    HPROF_CALLOC(ALLOC_TYPE_LIVE_THREAD, sizeof(live_thread_t));

	/* add to the list of live threads */
	newthread->next = live_thread_list;
	newthread->tid = objmap;
	newthread->env = env_id;
	newthread->cpu_sampled = 1;
	live_thread_list = newthread;
	num_live_threads++;
    }

    result = hprof_intern_thread(env_id);
    if (result->thread_id != NULL) {
        fprintf(stderr, "HPROF ERROR : thread ID already in use\n");
	goto threadstart_done;
    }
    result->thread_id = objmap;
    thread_name = hprof_intern_name(t_name);
    group_name = hprof_intern_name(g_name);
    parent_name = hprof_intern_name(p_name);
#ifdef HASH_STATS
    if (cpu_timing) {
        hprof_thread_local_t *info = 
            (hprof_thread_local_t *)(CALL(GetThreadLocalStorage)(env_id));
	info->thread_name = thread_name;
	info->group_name  = group_name;
	info->parent_name = parent_name;
    }
#endif /* HASH_STATS */
    
    if (output_format == 'b') {
        int trace_num;
	if (requested) {
	    trace_num = 0;
	} else {
	    hprof_trace_t *htrace = hprof_get_trace(env_id, max_trace_depth);
	    if (htrace == NULL) {
	        fprintf(stderr, "HPROF ERROR : got NULL trace in thread_start\n");
		goto threadstart_done;
	    }
	    trace_num = htrace->serial_num;
	}
	hprof_write_header(HPROF_START_THREAD, sizeof(void *) * 4 + 8);
	hprof_write_u4(result->serial_num);
	hprof_write_id(objmap);
	hprof_write_u4(trace_num);
	hprof_write_id(thread_name);
	hprof_write_id(group_name);
	hprof_write_id(parent_name);
    } else if ((!cpu_timing) || (timing_format != OLD_PROF_OUTPUT_FORMAT)) {
        /* we don't want thread info for the old prof output format */
        hprof_printf("THREAD START "
		     "(obj=%x, id = %d, name=\"%s\", group=\"%s\")\n",
		     objmap, result->serial_num,
		     thread_name->name, group_name->name);
    }
 threadstart_done:
    CALL(RawMonitorExit)(data_access_lock); 
}