|
|
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 |
|