Blame SOURCES/0038-Speed-up-thread-start-end-processing.patch

b35d98
From 45bb10da0dd06e9e753f5080de5f863614779c2b Mon Sep 17 00:00:00 2001
b35d98
From: Jakub Filak <jfilak@redhat.com>
b35d98
Date: Tue, 21 Jan 2014 10:21:37 +0100
b35d98
Subject: [PATCH 38/39] Speed up thread start/end processing
b35d98
b35d98
It is not necessary to initialize any thread related data until an
b35d98
exception occurs, and then we can skip calling getTid() in the thread end
b35d98
callback.
b35d98
b35d98
Related to rhbz#1051198
b35d98
---
b35d98
 src/abrt-checker.c | 102 +++++++++++++++++++++++------------------------------
b35d98
 src/jthread_map.c  |   7 ++--
b35d98
 2 files changed, 49 insertions(+), 60 deletions(-)
b35d98
b35d98
diff --git a/src/abrt-checker.c b/src/abrt-checker.c
b35d98
index 1f91cb7..91485e0 100644
b35d98
--- a/src/abrt-checker.c
b35d98
+++ b/src/abrt-checker.c
b35d98
@@ -591,8 +591,7 @@ static void register_abrt_event(
b35d98
 static void report_stacktrace(
b35d98
         const char *executable,
b35d98
         const char *message,
b35d98
-        const char *stacktrace,
b35d98
-        int sure_unique)
b35d98
+        const char *stacktrace)
b35d98
 {
b35d98
     if (reportErrosTo & ED_SYSLOG)
b35d98
     {
b35d98
@@ -621,7 +620,7 @@ static void report_stacktrace(
b35d98
         log_print("executable: %s\n", executable);
b35d98
     }
b35d98
 
b35d98
-    if (NULL != stacktrace && sure_unique)
b35d98
+    if (NULL != stacktrace)
b35d98
     {
b35d98
         VERBOSE_PRINT("Reporting stack trace to ABRT");
b35d98
         register_abrt_event(executable, message, stacktrace);
b35d98
@@ -1269,35 +1268,24 @@ static void JNICALL callback_on_vm_death(
b35d98
 
b35d98
 
b35d98
 /*
b35d98
- * Called before thread end.
b35d98
+ * Former callback_on_thread_start but it is not necessary to create an empty
b35d98
+ * structures and waste CPU time because it is more likely that no exception
b35d98
+ * will occur during the thread's lifetime. So, we converted the callback to a
b35d98
+ * function which can be used for initialization of the internal structures.
b35d98
  */
b35d98
-static void JNICALL callback_on_thread_start(
b35d98
-            jvmtiEnv *jvmti_env __UNUSED_VAR,
b35d98
+static T_jthrowableCircularBuf *create_exception_buf_for_thread(
b35d98
             JNIEnv   *jni_env,
b35d98
-            jthread  thread)
b35d98
+            jlong tid)
b35d98
 {
b35d98
-    INFO_PRINT("ThreadStart\n");
b35d98
-    if (NULL == threadMap)
b35d98
-    {
b35d98
-        return;
b35d98
-    }
b35d98
-
b35d98
-    jlong tid = 0;
b35d98
-
b35d98
-    if (get_tid(jni_env, thread, &tid))
b35d98
-    {
b35d98
-        VERBOSE_PRINT("Cannot malloc thread's exception buffer because cannot get TID");
b35d98
-        return;
b35d98
-    }
b35d98
-
b35d98
     T_jthrowableCircularBuf *threads_exc_buf = jthrowable_circular_buf_new(jni_env, REPORTED_EXCEPTION_STACK_CAPACITY);
b35d98
     if (NULL == threads_exc_buf)
b35d98
     {
b35d98
         fprintf(stderr, "Cannot enable check for already reported exceptions. Disabling reporting to ABRT in current thread!");
b35d98
-        return;
b35d98
+        return NULL;
b35d98
     }
b35d98
 
b35d98
     jthread_map_push(threadMap, tid, (void *)threads_exc_buf);
b35d98
+    return threads_exc_buf;
b35d98
 }
b35d98
 
b35d98
 
b35d98
@@ -1316,36 +1304,38 @@ static void JNICALL callback_on_thread_end(
b35d98
         return;
b35d98
     }
b35d98
 
b35d98
-    jlong tid = 0;
b35d98
-
b35d98
-    if (get_tid(jni_env, thread, &tid))
b35d98
+    if (!jthread_map_empty(threadMap) || !jthread_map_empty(uncaughtExceptionMap))
b35d98
     {
b35d98
-        VERBOSE_PRINT("Cannot free thread's exception buffer because cannot get TID");
b35d98
-        return;
b35d98
-    }
b35d98
-
b35d98
-    T_exceptionReport *rpt = (T_exceptionReport *)jthread_map_pop(uncaughtExceptionMap, tid);
b35d98
-    T_jthrowableCircularBuf *threads_exc_buf = (T_jthrowableCircularBuf *)jthread_map_pop(threadMap, tid);
b35d98
+        jlong tid = 0;
b35d98
 
b35d98
-    if (NULL != rpt)
b35d98
-    {
b35d98
-        if (NULL == threads_exc_buf || NULL == jthrowable_circular_buf_find(threads_exc_buf, rpt->exception_object))
b35d98
+        if (get_tid(jni_env, thread, &tid))
b35d98
         {
b35d98
-            report_stacktrace(NULL != rpt->executable ? rpt->executable : processProperties.main_class,
b35d98
-                              NULL != rpt->message ? rpt->message : "Uncaught exception",
b35d98
-                              rpt->stacktrace,
b35d98
-                              NULL != threads_exc_buf);
b35d98
+            VERBOSE_PRINT("Cannot free thread's exception buffer because cannot get TID");
b35d98
+            return;
b35d98
         }
b35d98
 
b35d98
-        free(rpt->message);
b35d98
-        free(rpt->stacktrace);
b35d98
-        free(rpt->executable);
b35d98
-        free(rpt->exception_type_name);
b35d98
-    }
b35d98
+        T_exceptionReport *rpt = (T_exceptionReport *)jthread_map_pop(uncaughtExceptionMap, tid);
b35d98
+        T_jthrowableCircularBuf *threads_exc_buf = (T_jthrowableCircularBuf *)jthread_map_pop(threadMap, tid);
b35d98
 
b35d98
-    if (threads_exc_buf != NULL)
b35d98
-    {
b35d98
-        jthrowable_circular_buf_free(threads_exc_buf);
b35d98
+        if (NULL != rpt)
b35d98
+        {
b35d98
+            if (NULL == threads_exc_buf || NULL == jthrowable_circular_buf_find(threads_exc_buf, rpt->exception_object))
b35d98
+            {
b35d98
+                report_stacktrace(NULL != rpt->executable ? rpt->executable : processProperties.main_class,
b35d98
+                                  NULL != rpt->message ? rpt->message : "Uncaught exception",
b35d98
+                                  rpt->stacktrace);
b35d98
+            }
b35d98
+
b35d98
+            free(rpt->message);
b35d98
+            free(rpt->stacktrace);
b35d98
+            free(rpt->executable);
b35d98
+            free(rpt->exception_type_name);
b35d98
+        }
b35d98
+
b35d98
+        if (threads_exc_buf != NULL)
b35d98
+        {
b35d98
+            jthrowable_circular_buf_free(threads_exc_buf);
b35d98
+        }
b35d98
     }
b35d98
 }
b35d98
 
b35d98
@@ -2193,8 +2183,10 @@ static void JNICALL callback_on_exception(
b35d98
             {
b35d98
                 report_stacktrace(NULL != executable ? executable : processProperties.main_class,
b35d98
                         report_message,
b35d98
-                        stack_trace_str,
b35d98
-                        NULL != threads_exc_buf);
b35d98
+                        stack_trace_str);
b35d98
+
b35d98
+                if (NULL == threads_exc_buf)
b35d98
+                    threads_exc_buf = create_exception_buf_for_thread(jni_env, tid);
b35d98
 
b35d98
                 if (NULL != threads_exc_buf)
b35d98
                 {
b35d98
@@ -2346,8 +2338,10 @@ static void JNICALL callback_on_exception_catch(
b35d98
             char *message = format_exception_reason_message(/*caught*/1, rpt->exception_type_name,  class_name_ptr, method_name_ptr);
b35d98
             report_stacktrace(NULL != rpt->executable ? rpt->executable : processProperties.main_class,
b35d98
                               NULL != message ? message : "Caught exception",
b35d98
-                              rpt->stacktrace,
b35d98
-                              NULL != threads_exc_buf);
b35d98
+                              rpt->stacktrace);
b35d98
+
b35d98
+            if (NULL == threads_exc_buf)
b35d98
+                threads_exc_buf = create_exception_buf_for_thread(jni_env, tid);
b35d98
 
b35d98
             if (NULL != threads_exc_buf)
b35d98
             {
b35d98
@@ -2584,9 +2578,6 @@ jvmtiError register_all_callback_functions(jvmtiEnv *jvmti_env)
b35d98
     callbacks.VMDeath = &callback_on_vm_death;
b35d98
 #endif /* ABRT_VM_DEATH_CHECK */
b35d98
 
b35d98
-    /* JVMTI_EVENT_THREAD_START */
b35d98
-    callbacks.ThreadStart = &callback_on_thread_start;
b35d98
-
b35d98
     /* JVMTI_EVENT_THREAD_END */
b35d98
     callbacks.ThreadEnd = &callback_on_thread_end;
b35d98
 
b35d98
@@ -2659,11 +2650,6 @@ jvmtiError set_event_notification_modes(jvmtiEnv* jvmti_env)
b35d98
     }
b35d98
 #endif /* ABRT_VM_DEATH_CHECK */
b35d98
 
b35d98
-    if ((error_code = set_event_notification_mode(jvmti_env, JVMTI_EVENT_THREAD_START)) != JNI_OK)
b35d98
-    {
b35d98
-        return error_code;
b35d98
-    }
b35d98
-
b35d98
     if ((error_code = set_event_notification_mode(jvmti_env, JVMTI_EVENT_THREAD_END)) != JNI_OK)
b35d98
     {
b35d98
         return error_code;
b35d98
diff --git a/src/jthread_map.c b/src/jthread_map.c
b35d98
index e9d60e9..4517398 100644
b35d98
--- a/src/jthread_map.c
b35d98
+++ b/src/jthread_map.c
b35d98
@@ -115,7 +115,6 @@ void jthread_map_push(T_jthreadMap *map, jlong tid, void *item)
b35d98
     assert(NULL != map);
b35d98
 
b35d98
     pthread_mutex_lock(&map->mutex);
b35d98
-    ++map->size;
b35d98
 
b35d98
     const long index = tid % MAP_SIZE;
b35d98
     T_jthreadMapItem *last = NULL;
b35d98
@@ -128,6 +127,8 @@ void jthread_map_push(T_jthreadMap *map, jlong tid, void *item)
b35d98
 
b35d98
     if (NULL == itm)
b35d98
     {
b35d98
+        ++map->size;
b35d98
+
b35d98
         T_jthreadMapItem *new = jthrowable_map_item_new(tid, item);
b35d98
         if (last == NULL)
b35d98
         {
b35d98
@@ -174,7 +175,6 @@ void *jthread_map_pop(T_jthreadMap *map, jlong tid)
b35d98
     assert(NULL != map);
b35d98
 
b35d98
     pthread_mutex_lock(&map->mutex);
b35d98
-    --map->size;
b35d98
 
b35d98
     const size_t index = tid % MAP_SIZE;
b35d98
     void *data = NULL;
b35d98
@@ -205,6 +205,9 @@ void *jthread_map_pop(T_jthreadMap *map, jlong tid)
b35d98
         }
b35d98
     }
b35d98
 
b35d98
+    if (NULL != data)
b35d98
+        --map->size;
b35d98
+
b35d98
     pthread_mutex_unlock(&map->mutex);
b35d98
 
b35d98
     return data;
b35d98
-- 
b35d98
1.8.3.1
b35d98