hprof_tls.c

来自「一个小公司要求给写的很简单的任务管理系统。」· C语言 代码 · 共 1,187 行 · 第 1/3 页

C
1,187
字号
    if ( total_time > 0 && parent != NULL ) {  /* if a caller exists */	parent->time_in_callees += total_time;    }    trace_increment_cost(trace_index, 1, self_time, total_time);}static voidpush_method(Stack *stack, jlong method_start_time, jmethodID method){    StackElement new_element;    FrameIndex   frame_index;        HPROF_ASSERT(method!=NULL);    HPROF_ASSERT(stack!=NULL);    frame_index                  = frame_find_or_create(method, -1);    HPROF_ASSERT(frame_index != 0);    new_element.frame_index      = frame_index;    new_element.method           = method;    new_element.method_start_time= method_start_time;    new_element.time_in_callees  = (jlong)0;    stack_push(stack, &new_element);}  static Stack *insure_method_on_stack(jthread thread, TlsInfo *info, jlong current_time,		FrameIndex frame_index, jmethodID method){    StackElement  element;    void         *p;    int           depth;    int           count;    int           fcount;    int           i;    Stack         *new_stack;    Stack         *stack;    stack = info->stack;    HPROF_ASSERT(method!=NULL);       /* If this method is on the stack, just return */    depth   = stack_depth(stack);    p = stack_top(stack);    if ( p != NULL ) {        element = *(StackElement*)p;	if ( element.frame_index == frame_index ) {	    return stack;        }    }    for ( i = 0 ; i < depth ; i++ ) {        p = stack_element(stack, i);        element = *(StackElement*)p;	if ( element.frame_index == frame_index ) {	    return stack;	}    }    /* It wasn't found, create a new stack */    getFrameCount(thread, &count);    if ( count <= 0 ) {        HPROF_ERROR(JNI_FALSE, "no frames, method can't be on stack");    }    setup_trace_buffers(info, count);    getStackTrace(thread, info->jframes_buffer, count, &fcount);    HPROF_ASSERT(count==fcount);    /* Create a new stack */    new_stack = stack_init(INITIAL_THREAD_STACK_LIMIT, 			    INITIAL_THREAD_STACK_LIMIT,			    (int)sizeof(StackElement));    for ( i = count-1; i >= 0 ; i-- ) {	push_method(new_stack, current_time, info->jframes_buffer[i].method);    }    if ( depth > 0 ) {	for ( i = depth-1 ; i >= 0; i-- ) {	    stack_push(new_stack, stack_element(stack, i));	}    }    stack_term(stack);    return new_stack;}static voidpop_method(TlsIndex index, jlong current_time, jmethodID method, FrameIndex frame_index){    SerialNumber  thread_serial_num;    TlsInfo  *    info;    StackElement  element;    void         *p;    int           depth;    int           trace_depth;    jlong         total_time;    jlong         self_time;    int           i;    TraceIndex    trace_index;    HPROF_ASSERT(method!=NULL);    HPROF_ASSERT(frame_index!=0);        thread_serial_num  = get_key(index);    info               = get_info(index);    HPROF_ASSERT(info!=NULL);    HPROF_ASSERT(info->stack!=NULL);    depth   = stack_depth(info->stack);    p = stack_pop(info->stack);    if (p == NULL) {        HPROF_ERROR(JNI_FALSE, "method return tracked, but stack is empty");	return;    }    element = *(StackElement*)p;    HPROF_ASSERT(element.frame_index!=0);    /* The depth of frames we should keep track for reporting */    if (gdata->prof_trace_depth > depth) {	trace_depth = depth;    } else {	trace_depth = gdata->prof_trace_depth;    }        /* Create a trace entry */    HPROF_ASSERT(info->frames_buffer!=NULL);    HPROF_ASSERT(info->jframes_buffer!=NULL);    setup_trace_buffers(info, trace_depth);    info->frames_buffer[0] = element.frame_index;    for (i = 1; i < trace_depth; i++) {	StackElement e;		e = *(StackElement*)stack_element(info->stack, (depth - i) - 1);	info->frames_buffer[i] = e.frame_index;	HPROF_ASSERT(e.frame_index!=0);    }    trace_index = trace_find_or_create(thread_serial_num,		    trace_depth, info->frames_buffer, info->jframes_buffer);       /* Calculate time spent */    total_time = current_time - element.method_start_time;    if ( total_time < 0 ) {	total_time = 0;        self_time = 0;    } else {        self_time = total_time - element.time_in_callees;    }    /* Update stats */    p = stack_top(info->stack);    if ( p != NULL ) {        adjust_stats(total_time, self_time, trace_index, (StackElement*)p);    } else {        adjust_stats(total_time, self_time, trace_index, NULL);    }}static voiddump_thread_state(TlsIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg){    SerialNumber thread_serial_num;    TlsInfo     *info;    jthread      thread;    JNIEnv      *env;        HPROF_ASSERT(key_ptr!=NULL);    HPROF_ASSERT(info_ptr!=NULL);    env                  = (JNIEnv*)arg;    thread_serial_num    = *(SerialNumber*)key_ptr;    info                 = (TlsInfo*)info_ptr;    thread               = newLocalReference(env, info->globalref);    if ( thread != NULL ) {	jint         threadState;	SerialNumber trace_serial_num;		getThreadState(thread, &threadState);	/* A 0 trace at this time means the thread is in unknown territory.	 *   The trace serial number MUST be a valid serial number, so we use	 *   the system trace (empty) just so it has a valid trace.	 */	if ( info->last_trace == 0 ) {	    trace_serial_num = trace_get_serial_number(gdata->system_trace_index);	} else {	    trace_serial_num = trace_get_serial_number(info->last_trace);	}	io_write_monitor_dump_thread_state(thread_serial_num,		       trace_serial_num, threadState);	deleteLocalReference(env, thread);    }}static SerialNumberget_serial_number(JNIEnv *env, jthread thread){    TlsIndex     index;        if ( thread == NULL ) {	return gdata->unknown_thread_serial_num;    }    HPROF_ASSERT(env!=NULL);    index = tls_find_or_create(env, thread);    return get_key(index);}static voiddump_monitor_state(TlsIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg){    TlsInfo *info;    jthread  thread;    JNIEnv  *env;        HPROF_ASSERT(info_ptr!=NULL);    env = (JNIEnv*)arg;    info = (TlsInfo*)info_ptr;    thread = newLocalReference(env, info->globalref);    if ( thread != NULL ) {	jobject *objects;	jint     ocount;	int      i;		getOwnedMonitorInfo(thread, &objects, &ocount);	if ( ocount > 0 ) {	    for ( i = 0 ; i < ocount ; i++ ) {		jvmtiMonitorUsage usage;		SerialNumber *waiter_nums;		SerialNumber *notify_waiter_nums;		int           t;		char *        sig;		WITH_LOCAL_REFS(env, 1) {		    jclass clazz;		    clazz = getObjectClass(env, objects[i]);		    getClassSignature(clazz, &sig, NULL);		} END_WITH_LOCAL_REFS;				getObjectMonitorUsage(objects[i], &usage);		waiter_nums = HPROF_MALLOC(usage.waiter_count*					(int)sizeof(SerialNumber)+1);                for ( t = 0 ; t < usage.waiter_count ; t++ ) {		    waiter_nums[t] = 			get_serial_number(env, usage.waiters[t]);		}		notify_waiter_nums = HPROF_MALLOC(usage.notify_waiter_count*					(int)sizeof(SerialNumber)+1);                for ( t = 0 ; t < usage.notify_waiter_count ; t++ ) {		    notify_waiter_nums[t] = 			get_serial_number(env, usage.notify_waiters[t]);		}		io_write_monitor_dump_state(sig,		       get_serial_number(env, usage.owner), 		       usage.entry_count,		       waiter_nums, usage.waiter_count,		       notify_waiter_nums, usage.notify_waiter_count);		jvmtiDeallocate(sig);		jvmtiDeallocate(usage.waiters);		jvmtiDeallocate(usage.notify_waiters);		HPROF_FREE(waiter_nums);		HPROF_FREE(notify_waiter_nums);	    }	}	jvmtiDeallocate(objects);	deleteLocalReference(env, thread);    }}static jlongmonitor_time(void){    jlong mtime;    mtime = md_get_timemillis(); /* gettimeofday() */    return mtime;}static jlongmethod_time(void){    jlong method_time;    method_time = md_get_thread_cpu_timemillis(); /* thread CPU time */    return method_time;}/* External interfaces */TlsIndextls_find_or_create(JNIEnv *env, jthread thread){    SerialNumber    thread_serial_num;    static TlsInfo  empty_info;    TlsInfo         info;    TlsIndex        index;    HPROF_ASSERT(env!=NULL);    HPROF_ASSERT(thread!=NULL);        /*LINTED*/    index = (TlsIndex)(ptrdiff_t)getThreadLocalStorage(thread);    if ( index != 0 ) {	HPROF_ASSERT(isSameObject(env, thread, get_info(index)->globalref));	return index;    }    index = search(env, thread);    if ( index != 0 ) {	setThreadLocalStorage(thread, (void*)(ptrdiff_t)index);	return index;    }    thread_serial_num      = gdata->thread_serial_number_counter++;    info                   = empty_info;    info.monitor_index     = 0;    info.sample_status     = 1;    info.agent_thread      = JNI_FALSE;    info.stack             = stack_init(INITIAL_THREAD_STACK_LIMIT, 				INITIAL_THREAD_STACK_LIMIT,				(int)sizeof(StackElement));    setup_trace_buffers(&info, gdata->max_trace_depth);    info.globalref = newWeakGlobalReference(env, thread);    index = table_create_entry(gdata->tls_table, &thread_serial_num, (int)sizeof(SerialNumber), (void*)&info);    setThreadLocalStorage(thread, (void*)(ptrdiff_t)index);    HPROF_ASSERT(search(env,thread)==index);    return index;}/* Mark a new or existing entry as being an agent thread */voidtls_agent_thread(JNIEnv *env, jthread thread){    TlsIndex  index;    TlsInfo  *info;    index              = tls_find_or_create(env, thread);    info               = get_info(index);    info->agent_thread = JNI_TRUE;}voidtls_init(void){    gdata->tls_table = table_initialize("TLS",                            16, 16, 16, (int)sizeof(TlsInfo));}voidtls_list(void){    debug_message(         "--------------------- TLS Table ------------------------\n");    table_walk_items(gdata->tls_table, &list_item, NULL);    debug_message(        "----------------------------------------------------------\n");}jinttls_sum_sample_status(void){    jint sample_status_total;        sample_status_total = 0;    table_walk_items(gdata->tls_table, &sum_sample_status_item, (void*)&sample_status_total);    return sample_status_total;}voidtls_set_sample_status(ObjectIndex object_index, jint sample_status){    SampleData  data;    data.thread_object_index = object_index;    data.sample_status       = sample_status;    table_walk_items(gdata->tls_table, &sample_setter, (void*)&data);}jinttls_get_tracker_status(JNIEnv *env, jthread thread, jboolean skip_init,	jint **ppstatus, TlsIndex* pindex,	SerialNumber *pthread_serial_num, TraceIndex *ptrace_index){    TlsInfo      *info;    TlsIndex      index;    SerialNumber  thread_serial_num;    jint          status;      index             = tls_find_or_create(env, thread);    info              = get_info(index);    *ppstatus         = &(info->tracker_status);    status            = **ppstatus;    thread_serial_num = get_key(index);        if ( pindex != NULL ) {	*pindex = index;    }    if ( status != 0 ) {	return status;    }    if ( ptrace_index != NULL ) {	setup_trace_buffers(info, gdata->max_trace_depth);	*ptrace_index = get_trace(thread, thread_serial_num, 			    gdata->max_trace_depth, skip_init,			    info->frames_buffer, info->jframes_buffer);

⌨️ 快捷键说明

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