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

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