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 + -
显示快捷键?