Blob Blame Raw
From 2ccddc0329fb7103663f5d4c2347a3f8957ebe4b Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Fri, 17 Jan 2014 20:09:05 +0100
Subject: [PATCH 29/39] Speed up ExceptionCatch event callback

Return from the callback immediately when there is no uncaught exception
to be checked. I suppose that the majority of ExceptionCatch events
occur in normal state of execution. The current solution needs to get
TID of the current thread just to find out that the uncaught exceptions
map is empty. This is not necessary because the map can provide such
information by counting the stored items. If the size of the map is
zero, we can safely return from the exception callback without other
processing.

Related to rhbz#1051198
---
 src/abrt-checker.c | 13 ++++++++-----
 src/jthread_map.c  |  7 +++++++
 src/jthread_map.h  | 10 ++++++++++
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/src/abrt-checker.c b/src/abrt-checker.c
index b6f11e8..1f91cb7 100644
--- a/src/abrt-checker.c
+++ b/src/abrt-checker.c
@@ -2251,11 +2251,8 @@ static void JNICALL callback_on_exception_catch(
             jlocation location __UNUSED_VAR,
             jobject   exception_object)
 {
-    jvmtiError error_code;
-
-    char *method_name_ptr = NULL;
-    char *method_signature_ptr = NULL;
-    char *class_signature_ptr = NULL;
+    if (jthread_map_empty(uncaughtExceptionMap))
+        return;
 
     /* all operations should be processed in critical section */
     enter_critical_section(jvmti_env, shared_lock);
@@ -2325,6 +2322,12 @@ static void JNICALL callback_on_exception_catch(
 
         if (NULL == threads_exc_buf || NULL == jthrowable_circular_buf_find(threads_exc_buf, rpt->exception_object))
         {
+            char *method_name_ptr = NULL;
+            char *method_signature_ptr = NULL;
+            char *class_signature_ptr = NULL;
+
+            jvmtiError error_code;
+
             /* retrieve all required informations */
             error_code = (*jvmti_env)->GetMethodName(jvmti_env, method, &method_name_ptr, &method_signature_ptr, NULL);
             if (check_jvmti_error(jvmti_env, error_code, __FILE__ ":" STRINGIZE(__LINE__)))
diff --git a/src/jthread_map.c b/src/jthread_map.c
index cd5ca52..e9d60e9 100644
--- a/src/jthread_map.c
+++ b/src/jthread_map.c
@@ -44,6 +44,7 @@ typedef struct jthread_map_item {
 struct jthread_map {
     T_jthreadMapItem *items[MAP_SIZE]; ///< map elements
     pthread_mutex_t mutex;
+    size_t size;
 };
 
 
@@ -75,6 +76,10 @@ void jthread_map_free(T_jthreadMap *map)
 }
 
 
+int jthread_map_empty(T_jthreadMap *map)
+{
+    return 0 == map->size;
+}
 
 static T_jthreadMapItem *jthrowable_map_item_new(long tid, void *item)
 {
@@ -110,6 +115,7 @@ void jthread_map_push(T_jthreadMap *map, jlong tid, void *item)
     assert(NULL != map);
 
     pthread_mutex_lock(&map->mutex);
+    ++map->size;
 
     const long index = tid % MAP_SIZE;
     T_jthreadMapItem *last = NULL;
@@ -168,6 +174,7 @@ void *jthread_map_pop(T_jthreadMap *map, jlong tid)
     assert(NULL != map);
 
     pthread_mutex_lock(&map->mutex);
+    --map->size;
 
     const size_t index = tid % MAP_SIZE;
     void *data = NULL;
diff --git a/src/jthread_map.h b/src/jthread_map.h
index 52d2832..4284a1b 100644
--- a/src/jthread_map.h
+++ b/src/jthread_map.h
@@ -50,6 +50,16 @@ void jthread_map_free(T_jthreadMap *map);
 
 
 /*
+ * Checks whether the map is empty
+ *
+ * @param mam Pointer to @jthread_map
+ * @returns true if the map is empty, false otherwise
+ */
+int jthread_map_empty(T_jthreadMap *map);
+
+
+
+/*
  * Adds a new map item identified by @tid with value @item
  *
  * Does nothing if item with same @tid already exists in @map
-- 
1.8.3.1