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

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