X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=ltt%2Fjni_interface.c;h=c25555f2d57a2686fcd9ee152b624ae8e34eafa1;hb=472656e5685fe5d720c1db235ae5dca27a456205;hp=ee7122f812b69730b09dd2a885dcc2980450aaee;hpb=f024106895c1709ae029285835320085e4494582;p=lttv.git diff --git a/ltt/jni_interface.c b/ltt/jni_interface.c index ee7122f8..c25555f2 100644 --- a/ltt/jni_interface.c +++ b/ltt/jni_interface.c @@ -49,6 +49,7 @@ struct java_calling_data }; // *** TODO ** +// All these struct are used to call g_datalist_foreach() // Find a better way! This is ugly! struct addMarkersArgs { @@ -56,15 +57,35 @@ struct addMarkersArgs struct marker_data* mdata; }; +struct saveTimeArgs +{ + GArray* saveTimeArray; +}; + +struct saveTimeAndTracefile +{ + LttTime time; + LttTracefile* tracefile; +}; + // ### COMMON Methods ### // # +// Empty method to turn off the debug (debug waste time while printing) +void ignore_and_drop_message(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) +{ +} + + // JNI method to call printf from the java side JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_Jni_1C_1Common_ltt_1printC(JNIEnv* env, jobject jobj, jstring new_string) { - printf("%s", (*env)->GetStringUTFChars(env, new_string, 0) ); + const char* c_msg = (*env)->GetStringUTFChars(env, new_string, 0); + + printf("%s", c_msg ); + + (*env)->ReleaseStringUTFChars(env, new_string, c_msg); } - // # // #### @@ -73,7 +94,14 @@ JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_Jni_1C_1Common_ltt_ // ### TRACE methods ### // # // JNI mapping of < LttTrace *ltt_trace_open(const gchar *pathname) > (trace.h) -JNIEXPORT jlong JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTrace_ltt_1openTrace(JNIEnv* env, jobject jobj, jstring pathname) { +JNIEXPORT jlong JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTrace_ltt_1openTrace(JNIEnv* env, jobject jobj, jstring pathname, jboolean show_debug) { + + if ( !show_debug) { + // Make sure we don't use any debug (speed up the read) + g_log_set_handler(NULL, G_LOG_LEVEL_INFO, ignore_and_drop_message, NULL); + g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, ignore_and_drop_message, NULL); + } + const char* c_pathname = (*env)->GetStringUTFChars(env, pathname, 0); LttTrace* newPtr = ltt_trace_open( c_pathname ); @@ -209,13 +237,13 @@ void g_datalist_foreach_addTracefilesOfTrace(GQuark name, gpointer data, gpointe jclass accessClass = (*args->env)->GetObjectClass(args->env, args->jobj); jmethodID accessFunction = (*args->env)->GetMethodID(args->env, accessClass, "addTracefileFromC", "(Ljava/lang/String;J)V"); - GArray* group = (GArray*)data; + GArray* tracefile_array = (GArray*)data; LttTracefile* tracefile; jlong newPtr; unsigned int i; - for (i=0; ilen; i++) { - tracefile = &g_array_index(group, LttTracefile, i); + for (i=0; ilen; i++) { + tracefile = &g_array_index(tracefile_array, LttTracefile, i); newPtr = CONVERT_PTR_TO_JLONG(tracefile); @@ -224,7 +252,7 @@ void g_datalist_foreach_addTracefilesOfTrace(GQuark name, gpointer data, gpointe } // Function to fill up the java map with the event type found in tracefile (the name) -JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTrace_ltt_1getAllTracefiles(JNIEnv* env, jobject jobj, jlong trace_ptr) { +JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTrace_ltt_1feedAllTracefiles(JNIEnv* env, jobject jobj, jlong trace_ptr) { LttTrace* newPtr = (LttTrace*)CONVERT_JLONG_TO_PTR(trace_ptr); struct java_calling_data args = { env, jobj }; @@ -233,7 +261,81 @@ JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTrace_ltt_1getAl } -// Function to print the content of a tracefile +// g_list_data function for the "for_each" call in Java_org_eclipse_linuxtools_lttng_jni_JniTrace_ltt_1feedTracefileTimeRange +// used to save the current timestamp for each tracefile +void g_datalist_foreach_saveTracefilesTime(GQuark name, gpointer data, gpointer user_data) { + struct saveTimeArgs* args = (struct saveTimeArgs*)user_data; + + GArray* tracefile_array = (GArray*)data; + GArray* save_array = args->saveTimeArray; + + LttTracefile* tracefile; + struct saveTimeAndTracefile* savedData; + + unsigned int i; + for (i=0; ilen; i++) { + tracefile = &g_array_index(tracefile_array, LttTracefile, i); + + // Allocate a new LttTime for each tracefile (so it won't change if the tracefile seek somewhere else) + savedData = (struct saveTimeAndTracefile*)malloc( sizeof(struct saveTimeAndTracefile) ); + savedData->time.tv_sec = tracefile->event.event_time.tv_sec; + savedData->time.tv_nsec = tracefile->event.event_time.tv_nsec; + savedData->tracefile = tracefile; + // Append the saved data to the array + g_array_append_val(save_array, savedData); + } +} + + +// Obtain the range of the trace (i.e. "start time" and "end time") +// +// Note : This function, unlike ltt_trace_time_span_get, is assured to return all tracefiles to their correct position after operation +// NOTE : this method is quite heavy to use!!! +JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTrace_ltt_1feedTracefileTimeRange(JNIEnv* env, jobject jobj, jlong trace_ptr, jobject jstart_time, jobject jend_time) { + LttTrace* newPtr = (LttTrace*)CONVERT_JLONG_TO_PTR(trace_ptr); + + // Allocate ourself a new array to save the data in + GArray* savedDataArray = g_array_new(FALSE, FALSE, sizeof(struct saveTimeAndTracefile*) ); + struct saveTimeArgs args = { savedDataArray }; + // Call g_datalist_foreach_saveTracefilesTime for each element in the GData to save the time + g_datalist_foreach(&newPtr->tracefiles, &g_datalist_foreach_saveTracefilesTime, &args); + + // Call to ltt_trace_time_span_get to find the current start and end time + // NOTE : This WILL change the current block of the tracefile (i.e. its timestamp) + LttTime tmpStartTime = { 0, 0 }; + LttTime tmpEndTime = { 0, 0 }; + ltt_trace_time_span_get(newPtr, &tmpStartTime, &tmpEndTime); + + // Seek back to the correct time for each tracefile and free the allocated memory + struct saveTimeAndTracefile* savedData; + unsigned int i; + for (i=0; ilen; i++) { + savedData = g_array_index(savedDataArray, struct saveTimeAndTracefile*, i); + // Seek back to the correct time + // Some time will not be consistent here (i.e. unitialized data) + // but the seek should work just fine with that + ltt_tracefile_seek_time(savedData->tracefile, savedData->time); + + // Free the memory allocated for this saveTimeAndTracefile entry + free( savedData ); + } + // Free the memory allocated for the GArray + g_array_free(savedDataArray, TRUE); + + // Send the start and end time back to the java + // We do it last to make sure a problem won't leave us with unfred memory + jclass startAccessClass = (*env)->GetObjectClass(env, jstart_time); + jmethodID startAccessFunction = (*env)->GetMethodID(env, startAccessClass, "setTimeFromC", "(J)V"); + jlong startTime = (CONVERT_UINT64_TO_JLONG(tmpStartTime.tv_sec)*BILLION) + CONVERT_UINT64_TO_JLONG(tmpStartTime.tv_nsec); + (*env)->CallVoidMethod(env, jstart_time, startAccessFunction, startTime); + + jclass endAccessClass = (*env)->GetObjectClass(env, jend_time); + jmethodID endAccessFunction = (*env)->GetMethodID(env, endAccessClass, "setTimeFromC", "(J)V"); + jlong endTime = (CONVERT_UINT64_TO_JLONG(tmpEndTime.tv_sec)*BILLION) + CONVERT_UINT64_TO_JLONG(tmpEndTime.tv_nsec); + (*env)->CallVoidMethod(env, jend_time, endAccessFunction, endTime); +} + +// Function to print the content of a trace JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTrace_ltt_1printTrace(JNIEnv* env, jobject jobj, jlong trace_ptr) { LttTrace* newPtr = (LttTrace*)CONVERT_JLONG_TO_PTR(trace_ptr); @@ -267,6 +369,7 @@ JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTrace_ltt_1print // ### TRACEFILE methods ### // # + // Get of cpu_online JNIEXPORT jboolean JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTracefile_ltt_1getIsCpuOnline(JNIEnv* env, jobject jobj, jlong tracefile_ptr) { LttTracefile* newPtr = (LttTracefile*)CONVERT_JLONG_TO_PTR(tracefile_ptr); @@ -461,7 +564,7 @@ void g_hash_table_foreach_addMarkersOfTracefile(gpointer key, gpointer data, gpo } // Function to fill up the java map with the event type found in tracefile (the name) -JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTracefile_ltt_1getAllMarkers(JNIEnv* env, jobject jobj, jlong tracefile_ptr) { +JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTracefile_ltt_1feedAllMarkers(JNIEnv* env, jobject jobj, jlong tracefile_ptr) { LttTracefile* newPtr = (LttTracefile*)CONVERT_JLONG_TO_PTR(tracefile_ptr); // *** TODO *** @@ -501,7 +604,6 @@ JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniTracefile_ltt_1p printf("subbuf_corrupt : %u\n" ,(unsigned int)newPtr->subbuf_corrupt); printf("event ptr : %p\n" ,&newPtr->event); printf("buffer ptr : %p\n" ,&newPtr->buffer); - printf("buf_size : %i\n" ,(unsigned int)newPtr->buf_size); printf("\n"); } // # @@ -554,7 +656,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniEvent_ltt_1readN int returnedValue = ltt_tracefile_read(newPtr); - // According to Ltt documentation, we need to get back to beginning after an error + // We need to get back to previous after an error to keep a sane state if ( returnedValue != 0 ) { ltt_tracefile_seek_time(newPtr, lastTime); } @@ -634,7 +736,14 @@ JNIEXPORT jint JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniEvent_ltt_1getEv return (jint)newPtr->event_id; } -// Get of event_time +// Get time in nanoseconds +JNIEXPORT jlong JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniEvent_ltt_1getNanosencondsTime(JNIEnv* env, jobject jobj, jlong event_ptr) { + LttEvent* newPtr = (LttEvent*)CONVERT_JLONG_TO_PTR(event_ptr); + + return (CONVERT_UINT64_TO_JLONG(newPtr->event_time.tv_sec)*BILLION) + CONVERT_UINT64_TO_JLONG(newPtr->event_time.tv_nsec); +} + +// Fill event_time into an object JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniEvent_ltt_1feedEventTime(JNIEnv* env, jobject jobj, jlong event_ptr, jobject time_jobj) { LttEvent* newPtr = (LttEvent*)CONVERT_JLONG_TO_PTR(event_ptr); @@ -927,83 +1036,72 @@ JNIEXPORT void JNICALL Java_org_eclipse_linuxtools_lttng_jni_JniParser_ltt_1getP // We will do an extra check on type "LTT_TYPE_UNSIGNED_INT" to check if the marker_field->format is hint of a pointer switch ( newMarkerFieldPtr->type ) { case LTT_TYPE_SIGNED_INT : - accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addLongToParsingFromC", "(Ljava/lang/Object;Ljava/lang/String;J)V"); + accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addLongToParsingFromC", "(Ljava/lang/Object;J)V"); (*env)->CallStaticVoidMethod( env, accessClass, accessFunction, javaObj, - (*env)->NewStringUTF(env, g_quark_to_string(newMarkerFieldPtr->name) ), - ltt_event_get_long_int(&newEventPtr, newMarkerFieldPtr), - (*env)->NewStringUTF(env, newMarkerFieldPtr->fmt->str ) + ltt_event_get_long_int(&newEventPtr, newMarkerFieldPtr) ); break; case LTT_TYPE_UNSIGNED_INT : - // If the format seems to be a pointer, add it as a pointer if ( (strncmp(newMarkerFieldPtr->fmt->str, "0x%llX", newMarkerFieldPtr->fmt->len) == 0 ) || (strncmp(newMarkerFieldPtr->fmt->str, "%llX", newMarkerFieldPtr->fmt->len) == 0 ) ) { - #if ARCHITECTURE_IS_64BITS == 0 - accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addIntPointerToParsingFromC", "(Ljava/lang/Object;Ljava/lang/String;J)V"); + #if __WORDSIZE == 64 + accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addLongPointerToParsingFromC", "(Ljava/lang/Object;J)V"); #else - accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addLongPointerToParsingFromC", "(Ljava/lang/Object;Ljava/lang/String;J)V"); + accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addIntPointerToParsingFromC", "(Ljava/lang/Object;J)V"); #endif (*env)->CallStaticVoidMethod( env, accessClass, accessFunction, javaObj, - (*env)->NewStringUTF(env, g_quark_to_string(newMarkerFieldPtr->name) ), - CONVERT_PTR_TO_JLONG(ltt_event_get_long_unsigned(&newEventPtr, newMarkerFieldPtr) ), - (*env)->NewStringUTF(env, newMarkerFieldPtr->fmt->str ) + CONVERT_PTR_TO_JLONG(ltt_event_get_long_unsigned(&newEventPtr, newMarkerFieldPtr) ) ); } // Otherwise, add it as a number else { - accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addLongToParsingFromC", "(Ljava/lang/Object;Ljava/lang/String;J)V"); + accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addLongToParsingFromC", "(Ljava/lang/Object;J)V"); (*env)->CallStaticVoidMethod( env, accessClass, accessFunction, javaObj, - (*env)->NewStringUTF(env, g_quark_to_string(newMarkerFieldPtr->name) ), - ltt_event_get_long_unsigned(&newEventPtr, newMarkerFieldPtr), - (*env)->NewStringUTF(env, newMarkerFieldPtr->fmt->str ) + ltt_event_get_long_unsigned(&newEventPtr, newMarkerFieldPtr) ); } break; case LTT_TYPE_POINTER : - #if ARCHITECTURE_IS_64BITS == 0 - accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addIntPointerToParsingFromC", "(Ljava/lang/Object;Ljava/lang/String;J)V"); + #if __WORDSIZE == 64 + accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addLongPointerToParsingFromC", "(Ljava/lang/Object;J)V"); #else - accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addLongPointerToParsingFromC", "(Ljava/lang/Object;Ljava/lang/String;J)V"); + accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addIntPointerToParsingFromC", "(Ljava/lang/Object;J)V"); #endif (*env)->CallStaticVoidMethod( env, accessClass, accessFunction, javaObj, - (*env)->NewStringUTF(env, g_quark_to_string(newMarkerFieldPtr->name) ), - CONVERT_PTR_TO_JLONG(*(GINT_TYPE_FOR_PTR*)(newEventPtr.data + newMarkerFieldPtr->offset)), - (*env)->NewStringUTF(env, newMarkerFieldPtr->fmt->str ) + CONVERT_PTR_TO_JLONG(*(GINT_TYPE_FOR_PTR*)(newEventPtr.data + newMarkerFieldPtr->offset)) ); break; case LTT_TYPE_STRING : - accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addStringToParsingFromC", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V"); + accessFunction = (*env)->GetStaticMethodID(env, accessClass, "addStringToParsingFromC", "(Ljava/lang/Object;Ljava/lang/String;)V"); (*env)->CallStaticVoidMethod( env, accessClass, accessFunction, javaObj, - (*env)->NewStringUTF(env, g_quark_to_string(newMarkerFieldPtr->name) ), - (*env)->NewStringUTF(env, ltt_event_get_string(&newEventPtr, newMarkerFieldPtr) ), - (*env)->NewStringUTF(env, newMarkerFieldPtr->fmt->str ) + (*env)->NewStringUTF(env, ltt_event_get_string(&newEventPtr, newMarkerFieldPtr) ) ); break; case LTT_TYPE_COMPACT : case LTT_TYPE_NONE : default : - printf("Warning : Unrecognized format type! Skipping! (Java_org_eclipse_linuxtools_lttng_jni_JniParser_ltt_1fillParseArray)"); + printf("Warning : Unrecognized format type! Skipping! (Java_org_eclipse_linuxtools_lttng_jni_JniParser_ltt_1getParsedData)"); break; }