欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

hprof_monitor.c

一个小公司要求给写的很简单的任务管理系统。
C
字号:
/* * @(#)hprof_monitor.c	1.36 05/11/17 *  * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: *  * -Redistribution of source code must retain the above copyright notice, this *  list of conditions and the following disclaimer. *  * -Redistribution in binary form must reproduce the above copyright notice,  *  this list of conditions and the following disclaimer in the documentation *  and/or other materials provided with the distribution. *  * Neither the name of Sun Microsystems, Inc. or the names of contributors may  * be used to endorse or promote products derived from this software without  * specific prior written permission. *  * This software is provided "AS IS," without a warranty of any kind. ALL  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. *  * You acknowledge that this software is not designed, licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. *//* Monitor contention tracking and monitor wait handling. *//* * Monitor's under contention are unique per trace and signature. *  Two monitors with the same trace and signature will be treated *  the same as far as accumulated contention time. * * The tls table (or thread table) will be used to store the monitor in *   contention or being waited on. * * Monitor wait activity is emitted as it happens. * * Monitor contention is tabulated and summarized at dump time. * */#include "hprof.h"typedef struct MonitorKey {    TraceIndex   trace_index;    StringIndex  sig_index;} MonitorKey;typedef struct MonitorInfo {    jint         num_hits;    jlong        contended_time;} MonitorInfo;typedef struct IterateInfo {    MonitorIndex *monitors;    int           count;    jlong         total_contended_time;} IterateInfo;/* Private internal functions. */static MonitorKey*get_pkey(MonitorIndex index){    void * key_ptr;    int    key_len;    table_get_key(gdata->monitor_table, index, &key_ptr, &key_len);    HPROF_ASSERT(key_len==sizeof(MonitorKey));    HPROF_ASSERT(key_ptr!=NULL);    return (MonitorKey*)key_ptr;}static MonitorInfo *get_info(MonitorIndex index){    MonitorInfo *       info;    HPROF_ASSERT(index!=0);    info = (MonitorInfo*)table_get_info(gdata->monitor_table, index);    HPROF_ASSERT(info!=NULL);    return info;}static MonitorIndexfind_or_create_entry(JNIEnv *env, TraceIndex trace_index, jobject object){    static MonitorKey empty_key;    MonitorKey   key;    MonitorIndex index;    char        *sig;    HPROF_ASSERT(object!=NULL);    WITH_LOCAL_REFS(env, 1) {	jclass clazz;		clazz = getObjectClass(env, object);	getClassSignature(clazz, &sig, NULL);    } END_WITH_LOCAL_REFS;        key                    = empty_key;    key.trace_index        = trace_index;    key.sig_index = string_find_or_create(sig);    jvmtiDeallocate(sig);    index = table_find_or_create_entry(gdata->monitor_table, &key, 			(int)sizeof(key), NULL, NULL);    return index;}static voidcleanup_item(MonitorIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg){}static voidlist_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg){    MonitorInfo *info;    MonitorKey  *pkey;    HPROF_ASSERT(key_len==sizeof(MonitorKey));    HPROF_ASSERT(key_ptr!=NULL);    HPROF_ASSERT(info_ptr!=NULL);    pkey = (MonitorKey*)key_ptr;    info = (MonitorInfo *)info_ptr;    debug_message(                 "Monitor 0x%08x: trace=0x%08x, sig=0x%08x, "		"num_hits=%d, contended_time=(%d,%d)\n",                 index,                  pkey->trace_index,                  pkey->sig_index,                  info->num_hits,                 jlong_high(info->contended_time),                 jlong_low(info->contended_time));}static voidcollect_iterator(MonitorIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg){    MonitorInfo *info;    IterateInfo *iterate;    HPROF_ASSERT(key_len==sizeof(MonitorKey));    HPROF_ASSERT(info_ptr!=NULL);    HPROF_ASSERT(arg!=NULL);    iterate = (IterateInfo *)arg;    info = (MonitorInfo *)info_ptr;    iterate->monitors[iterate->count++] = index;    iterate->total_contended_time += info->contended_time;}static int qsort_compare(const void *p_monitor1, const void *p_monitor2){    MonitorInfo * info1;    MonitorInfo * info2;    MonitorIndex  monitor1;    MonitorIndex  monitor2;    jlong         result;        HPROF_ASSERT(p_monitor1!=NULL);    HPROF_ASSERT(p_monitor2!=NULL);    monitor1 = *(MonitorIndex *)p_monitor1;    monitor2 = *(MonitorIndex *)p_monitor2;    info1 = get_info(monitor1);    info2 = get_info(monitor2);    result = info2->contended_time - info1->contended_time;    if (result < (jlong)0) {        return -1;    } else if ( result > (jlong)0 ) {        return 1;    }    return info2->num_hits - info1->num_hits;}static voidclear_item(MonitorIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg){    MonitorInfo *info;    HPROF_ASSERT(key_len==sizeof(MonitorKey));    HPROF_ASSERT(info_ptr!=NULL);    info = (MonitorInfo *)info_ptr;    info->contended_time = 0;}static TraceIndexget_trace(TlsIndex tls_index, JNIEnv *env){    TraceIndex trace_index;        trace_index = tls_get_trace(tls_index, env, gdata->max_trace_depth, JNI_FALSE);    return trace_index;}/* External functions (called from hprof_init.c) */voidmonitor_init(void){    gdata->monitor_table = table_initialize("Monitor",                            32, 32, 31, (int)sizeof(MonitorInfo));}voidmonitor_list(void){    debug_message(         "------------------- Monitor Table ------------------------\n");    table_walk_items(gdata->monitor_table, &list_item, NULL);    debug_message(        "----------------------------------------------------------\n");}voidmonitor_cleanup(void){    table_cleanup(gdata->monitor_table, &cleanup_item, (void*)NULL);    gdata->monitor_table = NULL;}void monitor_clear(void){    table_walk_items(gdata->monitor_table, &clear_item, NULL);}/* Contended monitor output */void monitor_write_contended_time(JNIEnv *env, double cutoff){    int n_entries;    n_entries = table_element_count(gdata->monitor_table);    if ( n_entries == 0 ) {	return;    }    rawMonitorEnter(gdata->data_access_lock); {	IterateInfo iterate;	int i;	int n_items;        jlong total_contended_time;		/* First write all trace we might refer to. */	trace_output_unmarked(env);	/* Looking for an array of monitor index values of interest */	iterate.monitors = HPROF_MALLOC(n_entries*(int)sizeof(MonitorIndex));	(void)memset(iterate.monitors, 0, n_entries*(int)sizeof(MonitorIndex));	/* Get a combined total and an array of monitor index numbers */	iterate.total_contended_time = 0;	iterate.count = 0;	table_walk_items(gdata->monitor_table, &collect_iterator, &iterate);	/* Sort that list */	n_entries = iterate.count;	if ( n_entries > 0 ) {	    qsort(iterate.monitors, n_entries, sizeof(MonitorIndex), 			&qsort_compare);        }	/* Apply the cutoff */	n_items = 0;	for (i = 0; i < n_entries; i++) {	    MonitorIndex index;	    MonitorInfo *info;	    double percent;	    index = iterate.monitors[i];	    info = get_info(index);	    percent = (double)info->contended_time / 		      (double)iterate.total_contended_time;	    if (percent < cutoff) {		break;	    }	    iterate.monitors[n_items++] = index;	}	/* Output the items that make sense */	total_contended_time = iterate.total_contended_time / 1000000;        	if ( n_items > 0 && total_contended_time > 0 ) {            double accum;	    	    /* Output the info on this monitor enter site */	    io_write_monitor_header(total_contended_time);	    	    accum = 0.0;	    for (i = 0; i < n_items; i++) {		MonitorIndex index;		MonitorInfo *info;		MonitorKey *pkey;	        double percent;		char *sig;		index = iterate.monitors[i];		pkey = get_pkey(index);		info = get_info(index);                		sig = string_get(pkey->sig_index);		percent = (double)info->contended_time / 			  (double)iterate.total_contended_time * 100.0;		accum += percent;		io_write_monitor_elem(i + 1, percent, accum, 			            info->num_hits,				    trace_get_serial_number(pkey->trace_index), 				    sig);	    }	    io_write_monitor_footer();	}	HPROF_FREE(iterate.monitors);    } rawMonitorExit(gdata->data_access_lock);}void monitor_contended_enter_event(JNIEnv *env, jthread thread, jobject object){    TlsIndex     tls_index;    MonitorIndex index;    TraceIndex   trace_index;    HPROF_ASSERT(env!=NULL);    HPROF_ASSERT(thread!=NULL);    HPROF_ASSERT(object!=NULL);        tls_index =  tls_find_or_create(env, thread);    HPROF_ASSERT(tls_get_monitor(tls_index)==0);    trace_index = get_trace(tls_index, env);    index = find_or_create_entry(env, trace_index, object);    tls_monitor_start_timer(tls_index);    tls_set_monitor(tls_index, index);}void monitor_contended_entered_event(JNIEnv* env, jthread thread, jobject object){    TlsIndex     tls_index;    MonitorInfo *info;    MonitorIndex index;    HPROF_ASSERT(env!=NULL);    HPROF_ASSERT(object!=NULL);    HPROF_ASSERT(thread!=NULL);        tls_index = tls_find_or_create(env, thread);    HPROF_ASSERT(tls_index!=0);    index     = tls_get_monitor(tls_index);    HPROF_ASSERT(index!=0);    info      = get_info(index);    info->contended_time += tls_monitor_stop_timer(tls_index);    info->num_hits++;    tls_set_monitor(tls_index, 0);}    voidmonitor_wait_event(JNIEnv *env, jthread thread, jobject object, jlong timeout){    TlsIndex     tls_index;    MonitorKey  *pkey;    MonitorIndex index;    TraceIndex   trace_index;    HPROF_ASSERT(env!=NULL);    HPROF_ASSERT(object!=NULL);    HPROF_ASSERT(thread!=NULL);        tls_index =  tls_find_or_create(env, thread);    HPROF_ASSERT(tls_index!=0);    HPROF_ASSERT(tls_get_monitor(tls_index)==0);    trace_index = get_trace(tls_index, env);    index = find_or_create_entry(env, trace_index, object);    pkey = get_pkey(index);    tls_monitor_start_timer(tls_index);    tls_set_monitor(tls_index, index);    rawMonitorEnter(gdata->data_access_lock); {        io_write_monitor_wait(string_get(pkey->sig_index), timeout, 			    tls_get_thread_serial_number(tls_index));    } rawMonitorExit(gdata->data_access_lock);}voidmonitor_waited_event(JNIEnv *env, jthread thread,                                 jobject object, jboolean timed_out){    TlsIndex     tls_index;    MonitorIndex index;    jlong        time_waited;    tls_index =  tls_find_or_create(env, thread);    HPROF_ASSERT(tls_index!=0);    time_waited = tls_monitor_stop_timer(tls_index);    index = tls_get_monitor(tls_index);    if ( index ==0 ) {	/* As best as I can tell, on Solaris X86 (not SPARC) I sometimes	 *    get a "waited" event on a thread that I have never seen before	 *    at all, so how did I get a WAITED event? Perhaps when I	 *    did the VM_INIT handling, a thread I've never seen had already	 *    done the WAIT (which I never saw?), and now I see this thread	 *    for the first time, and also as it finishes it's WAIT?	 *    Only happening on faster processors?	 */        tls_set_monitor(tls_index, 0);	return;    }    HPROF_ASSERT(index!=0);    tls_set_monitor(tls_index, 0);    if (object == NULL) {	rawMonitorEnter(gdata->data_access_lock); {	    io_write_monitor_sleep(time_waited, 			tls_get_thread_serial_number(tls_index));	} rawMonitorExit(gdata->data_access_lock);    } else {	MonitorKey *pkey;		pkey = get_pkey(index);	rawMonitorEnter(gdata->data_access_lock); {	    io_write_monitor_waited(string_get(pkey->sig_index), time_waited, 		tls_get_thread_serial_number(tls_index));	} rawMonitorExit(gdata->data_access_lock);    }}

⌨️ 快捷键说明

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