hprof_cpu.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 223 行

C
223
字号
/* * @(#)hprof_cpu.c	1.16 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */#include "jvmpi.h"#include "hprof.h"static JVMPI_RawMonitor hprof_cpu_lock;voidhprof_cpu_sample_off(hprof_objmap_t *thread_id){    cpu_sampling = FALSE;    if (thread_id != NULL) {        if (live_thread_list != NULL) {	    live_thread_t *list;	    CALL(RawMonitorEnter)(data_access_lock);	    for(list = live_thread_list; list; list = list->next) {	        if (list->tid == thread_id) {		    list->cpu_sampled = 0;		}		if (list->cpu_sampled) {		    cpu_sampling = TRUE;		}	    }	    CALL(RawMonitorExit)(data_access_lock);	}    }}/* handler for enabling cpu sampling */voidhprof_cpu_sample_on(hprof_objmap_t *thread_id){    hprof_start_cpu_sampling_thread();    if (thread_id == NULL) {        cpu_sampling = TRUE;    } else {        /* turn on cpu sampling for the specified thread */        if (live_thread_list) {	    live_thread_t *list;	    CALL(RawMonitorEnter)(data_access_lock);	    for(list = live_thread_list; list; list = list->next) {	        if (list->tid == thread_id) {		    list->cpu_sampled = 1;		    cpu_sampling = TRUE;		}	    }	    CALL(RawMonitorExit)(data_access_lock);	}    }    if (hprof_cpu_lock) {        /* notify the CPU sampling thread */        CALL(RawMonitorEnter)(hprof_cpu_lock);	CALL(RawMonitorNotifyAll)(hprof_cpu_lock);	CALL(RawMonitorExit)(hprof_cpu_lock);    }}static voidhprof_cpu_loop(void *p){    float avg_sample_time = 1;    int last_sample_time = 1;    int pause_time = 1;    JNIEnv *my_env;        (*jvm)->GetEnv(jvm, (void **)(void *)&my_env, JNI_VERSION_1_2);        hprof_cpu_lock = CALL(RawMonitorCreate)("_Hprof CPU sampling lock");    CALL(RawMonitorEnter)(hprof_cpu_lock);    while (1) {	avg_sample_time = last_sample_time * 0.1 + avg_sample_time * 0.9;        if (cpu_sampling) {	    /* Adjust the sampling interval according to the cost of	     * each sample.	     */	    int avg_time = (int)(avg_sample_time);	    if (avg_time == 0) {	        avg_time = 1;	    }	    if (avg_time > pause_time * 2) {	        pause_time = avg_time;	    }	    if (pause_time > 1 && avg_time < pause_time) {	        pause_time = avg_time;	    }	    CALL(RawMonitorWait)(hprof_cpu_lock, jint_to_jlong(pause_time));	} else {	    /* If cpu profiling has been turned off, wait forever	     * on the lock.	     */	    CALL(RawMonitorWait)(hprof_cpu_lock, jlong_zero);	    continue;	}	CALL(DisableGC)();	CALL(RawMonitorEnter)(hprof_dump_lock);	CALL(RawMonitorEnter)(data_access_lock);		last_sample_time = hprof_get_milliticks();		{	    live_thread_t *list;	    live_thread_t *suspended_list = NULL;	    int n_traces = 0;            int i;	    JVMPI_CallTrace *traces;	    	    /* Allocate space for all the traces we might collect, maximum	       value is number of live threads */	    traces = HPROF_CALLOC(ALLOC_TYPE_CALLTRACE,		num_live_threads * sizeof(JVMPI_CallTrace));	    for (i = 0; i < num_live_threads; i++) {	        traces[i].frames = HPROF_CALLOC(ALLOC_TYPE_CALLFRAME,		    max_trace_depth * sizeof(JVMPI_CallFrame));	    }	    	    /* suspend all the runnable threads */	    for (list = live_thread_list; list; list = list->next) {	        if (list->cpu_sampled && 		    list->env != my_env &&		    ((CALL(GetThreadStatus)(list->env) & 		      (~JVMPI_THREAD_INTERRUPTED)) == JVMPI_THREAD_RUNNABLE)) {		    CALL(SuspendThread)(list->env);		    list->nextSuspended = suspended_list;		    suspended_list = list;		}	    }	    	    /* get traces for all the threads that were actually running */	    for (list = suspended_list; list; list = list->nextSuspended) {		if (CALL(ThreadHasRun)(list->env)) {		    traces[n_traces].env_id = list->env;		    CALL(GetCallTrace)(&(traces[n_traces]),				       max_trace_depth);		    if (traces[n_traces].num_frames > 0) {		        n_traces++;		    }		}	    }       	    	    /* resume all the suspended threads */	    for (list = suspended_list; list; list = list->nextSuspended) {	        CALL(ResumeThread)(list->env);	    }	    	    /* record all the traces */	    if (n_traces > 0) {		for (i = 0; i < n_traces; i++) {		    JVMPI_CallTrace *jtrace = &(traces[i]);		    hprof_trace_t *htrace = 		        hprof_intern_jvmpi_trace(jtrace->frames, 						 jtrace->num_frames, 						 jtrace->env_id);		    if (htrace == NULL) {		        fprintf(stderr,				"HPROF ERROR: NULL trace in cpu_sample\n");		    } else {		        htrace->num_hits++;			htrace->cost =			    jlong_add(htrace->cost, jint_to_jlong(1));		    }		}	    }	    /* free up the space allocated to collect traces */	    for(i = 0; i < num_live_threads; i++) {	        hprof_free(traces[i].frames);	    }	    hprof_free(traces);	}			last_sample_time = hprof_get_milliticks() - last_sample_time;	CALL(RawMonitorExit)(data_access_lock);	CALL(RawMonitorExit)(hprof_dump_lock);	CALL(EnableGC)();    }    /* never reached */}void hprof_start_cpu_sampling_thread(void){    static int started = FALSE;    if (started || cpu_sampling == FALSE)        return;    started = TRUE;    /* start the cpu sampling thread */    if (CALL(CreateSystemThread)("HPROF CPU profiler",				 JVMPI_MAXIMUM_PRIORITY,				 hprof_cpu_loop) < 0) {        fprintf(stderr, "HPROF ERROR: unable to create CPU sampling thread\n");    }}

⌨️ 快捷键说明

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