00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "hprof.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static void JNICALL
00063 cpu_loop_function(jvmtiEnv *jvmti, JNIEnv *env, void *p)
00064 {
00065 int loop_trip_counter;
00066 jboolean cpu_loop_running;
00067
00068 loop_trip_counter = 0;
00069
00070 rawMonitorEnter(gdata->cpu_loop_lock); {
00071 gdata->cpu_loop_running = JNI_TRUE;
00072 cpu_loop_running = gdata->cpu_loop_running;
00073
00074 rawMonitorNotifyAll(gdata->cpu_loop_lock);
00075 } rawMonitorExit(gdata->cpu_loop_lock);
00076
00077 rawMonitorEnter(gdata->cpu_sample_lock);
00078
00079 while ( cpu_loop_running ) {
00080
00081 ++loop_trip_counter;
00082
00083 LOG3("cpu_loop()", "iteration", loop_trip_counter);
00084
00085
00086 rawMonitorEnter(gdata->dump_lock); {
00087 if (gdata->dump_in_process) {
00088 gdata->pause_cpu_sampling = JNI_TRUE;
00089 }
00090 } rawMonitorExit(gdata->dump_lock);
00091
00092
00093 if (gdata->pause_cpu_sampling) {
00094
00095
00096
00097
00098
00099
00100 rawMonitorWait(gdata->cpu_sample_lock, 0);
00101
00102 rawMonitorEnter(gdata->cpu_loop_lock); {
00103 cpu_loop_running = gdata->cpu_loop_running;
00104 } rawMonitorExit(gdata->cpu_loop_lock);
00105
00106
00107 continue;
00108 }
00109
00110
00111 rawMonitorWait(gdata->cpu_sample_lock, (jlong)gdata->sample_interval);
00112
00113
00114 rawMonitorEnter(gdata->cpu_loop_lock); {
00115 cpu_loop_running = gdata->cpu_loop_running;
00116 } rawMonitorExit(gdata->cpu_loop_lock);
00117
00118
00119 if ( !cpu_loop_running ) {
00120 break;
00121 }
00122
00123
00124
00125
00126
00127
00128
00129 rawMonitorEnter(gdata->dump_lock); {
00130 if (gdata->dump_in_process) {
00131 gdata->pause_cpu_sampling = JNI_TRUE;
00132 }
00133 } rawMonitorExit(gdata->dump_lock);
00134
00135
00136 if ( !gdata->pause_cpu_sampling) {
00137 tls_sample_all_threads(env);
00138 }
00139
00140
00141 rawMonitorEnter(gdata->cpu_loop_lock); {
00142 cpu_loop_running = gdata->cpu_loop_running;
00143 } rawMonitorExit(gdata->cpu_loop_lock);
00144
00145 }
00146 rawMonitorExit(gdata->cpu_sample_lock);
00147
00148 rawMonitorEnter(gdata->cpu_loop_lock); {
00149
00150 rawMonitorNotifyAll(gdata->cpu_loop_lock);
00151 } rawMonitorExit(gdata->cpu_loop_lock);
00152
00153 LOG2("cpu_loop()", "clean termination");
00154 }
00155
00156
00157
00158 void
00159 cpu_sample_init(JNIEnv *env)
00160 {
00161 gdata->cpu_sampling = JNI_TRUE;
00162
00163
00164 gdata->cpu_loop_lock = createRawMonitor("HPROF cpu loop lock");
00165 gdata->cpu_sample_lock = createRawMonitor("HPROF cpu sample lock");
00166
00167 rawMonitorEnter(gdata->cpu_loop_lock); {
00168 createAgentThread(env, "HPROF cpu sampling thread",
00169 &cpu_loop_function);
00170
00171 rawMonitorWait(gdata->cpu_loop_lock, 0);
00172 } rawMonitorExit(gdata->cpu_loop_lock);
00173 }
00174
00175 void
00176 cpu_sample_off(JNIEnv *env, ObjectIndex object_index)
00177 {
00178 jint count;
00179
00180 count = 1;
00181 if (object_index != 0) {
00182 tls_set_sample_status(object_index, 0);
00183 count = tls_sum_sample_status();
00184 }
00185 if ( count == 0 ) {
00186 gdata->pause_cpu_sampling = JNI_TRUE;
00187 } else {
00188 gdata->pause_cpu_sampling = JNI_FALSE;
00189 }
00190 }
00191
00192 void
00193 cpu_sample_on(JNIEnv *env, ObjectIndex object_index)
00194 {
00195 if ( gdata->cpu_loop_lock == NULL ) {
00196 cpu_sample_init(env);
00197 }
00198
00199 if (object_index == 0) {
00200 gdata->cpu_sampling = JNI_TRUE;
00201 gdata->pause_cpu_sampling = JNI_FALSE;
00202 } else {
00203 jint count;
00204
00205 tls_set_sample_status(object_index, 1);
00206 count = tls_sum_sample_status();
00207 if ( count > 0 ) {
00208 gdata->pause_cpu_sampling = JNI_FALSE;
00209 }
00210 }
00211
00212
00213 rawMonitorEnter(gdata->cpu_sample_lock); {
00214 rawMonitorNotifyAll(gdata->cpu_sample_lock);
00215 } rawMonitorExit(gdata->cpu_sample_lock);
00216
00217 }
00218
00219 void
00220 cpu_sample_term(JNIEnv *env)
00221 {
00222 gdata->pause_cpu_sampling = JNI_FALSE;
00223 rawMonitorEnter(gdata->cpu_sample_lock); {
00224
00225 rawMonitorNotifyAll(gdata->cpu_sample_lock);
00226 } rawMonitorExit(gdata->cpu_sample_lock);
00227 rawMonitorEnter(gdata->cpu_loop_lock); {
00228 if ( gdata->cpu_loop_running ) {
00229 gdata->cpu_loop_running = JNI_FALSE;
00230
00231 rawMonitorWait(gdata->cpu_loop_lock, 0);
00232 }
00233 } rawMonitorExit(gdata->cpu_loop_lock);
00234 }
00235