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

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