aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2017-11-14 15:58:32 -0800
committerAnders Broman <a.broman58@gmail.com>2017-11-16 06:11:55 +0000
commitac1d52aff5bdf74600ddc2f8f06ceccf9d2037a6 (patch)
treef36410bffc6f0a13a2562e5b2b9d548636c67ecf /tools
parent665eb78729c91b4056b3e58af4407f51df603f55 (diff)
Register protocols and handoffs in separate threads.
Instead of interleaving protocol registrations and status callbacks in the main thread, move protocol registrations to a worker thread. Do the same with protocol handoffs. This *should* be safe since the status callbacks only update the UI. This reduces startup time by about 200ms on my laptop: Run OS Thread? Time 1 macOS N 340 ms 2 macOS N 260 ms 3 macOS N 252 ms 4 macOS Y 147 ms 5 macOS Y 146 ms 6 macOS Y 142 ms 7 Win 7 N 80 samples 8 Win 7 N 56 samples 9 Win 7 N 75 samples 10 Win 7 Y 31 samples 11 Win 7 Y 2 samples 12 Win 7 Y 0 samples macOS was sampled using Instruments. Windows 7 was sampled using the Visual Studio 2015 profiler. We should do the same thing with our capture and tap event loops, but that will likely require quite a bit more work. Change-Id: Iac9a81d8f71668f5979b524744a03f6d80aee893 Reviewed-on: https://code.wireshark.org/review/24447 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'tools')
-rwxr-xr-xtools/make-dissector-reg.py88
1 files changed, 82 insertions, 6 deletions
diff --git a/tools/make-dissector-reg.py b/tools/make-dissector-reg.py
index 7b4c2962e6..dadb27b17b 100755
--- a/tools/make-dissector-reg.py
+++ b/tools/make-dissector-reg.py
@@ -211,7 +211,9 @@ WS_DLL_PUBLIC_DEF const gchar plugin_release[] = VERSION_RELEASE;
else:
reg_code += """
#include "register.h"
+#include "ws_attributes.h"
+#include <glib.h>
"""
for symbol in regs['proto_reg']:
@@ -227,19 +229,61 @@ plugin_register (void)
"""
else:
reg_code += """
-#define CALLBACK_REGISTER(proto, data) \\
- if (cb) cb(RA_REGISTER, proto, data)
+static const char *cur_cb_name = NULL;
+//static GMutex register_cb_mtx;
+static GAsyncQueue *register_cb_done_q;
+
+#define CB_WAIT_TIME (150 * 1000) // microseconds
+
+static void set_cb_name(const char *proto) {
+ // g_mutex_lock(register_cb_mtx);
+ cur_cb_name = proto;
+ // g_mutex_unlock(register_cb_mtx);
+}
+
+static void *register_all_protocols_worker(void *arg _U_);
void
register_all_protocols(register_cb cb, gpointer cb_data)
{
+ const char *cb_name;
+ register_cb_done_q = g_async_queue_new();
+ gboolean called_back = FALSE;
+
+#if GLIB_CHECK_VERSION(2,31,0)
+ g_thread_new("register_all_protocols_worker", &register_all_protocols_worker, NULL);
+#else
+ g_thread_create(&register_all_protocols_worker, TRUE, FALSE, NULL);
+#endif
+ while (!g_async_queue_timeout_pop(register_cb_done_q, CB_WAIT_TIME)) {
+ // g_mutex_lock(register_cb_mtx);
+ cb_name = cur_cb_name;
+ // g_mutex_unlock(register_cb_mtx);
+ if (cb && cb_name) {
+ cb(RA_REGISTER, cb_name, cb_data);
+ called_back = TRUE;
+ }
+ }
+ if (cb && !called_back) {
+ cb(RA_REGISTER, "Registration finished", cb_data);
+ }
+}
+
+void
+*register_all_protocols_worker(void *arg _U_)
+{
"""
for symbol in regs['proto_reg']:
if registertype != "plugin" and registertype != "plugin_wtap":
- reg_code += " CALLBACK_REGISTER(\"%s\", cb_data);\n" % (symbol)
+ reg_code += " set_cb_name(\"%s\");\n" % (symbol)
reg_code += " %s();\n" % (symbol)
+if registertype != "plugin" and registertype != "plugin_wtap":
+ reg_code += """
+ g_async_queue_push(register_cb_done_q, GINT_TO_POINTER(TRUE));
+ return NULL;
+"""
reg_code += "}\n\n"
@@ -258,19 +302,51 @@ plugin_reg_handoff(void)
"""
else:
reg_code += """
-#define CALLBACK_HANDOFF(proto, data) \\
- if (cb) cb(RA_HANDOFF, proto, data)
+static void *register_all_protocol_handoffs_worker(void *arg _U_);
void
register_all_protocol_handoffs(register_cb cb, gpointer cb_data)
{
+ cur_cb_name = NULL;
+ const char *cb_name;
+ gboolean called_back = FALSE;
+
+#if GLIB_CHECK_VERSION(2,31,0)
+ g_thread_new("register_all_protocol_hadoffss_worker", &register_all_protocol_handoffs_worker, NULL);
+#else
+ g_thread_create(&register_all_protocol_handoffs_worker, TRUE, FALSE, NULL);
+#endif
+ while (!g_async_queue_timeout_pop(register_cb_done_q, CB_WAIT_TIME)) {
+ // g_mutex_lock(register_cb_mtx);
+ cb_name = cur_cb_name;
+ // g_mutex_unlock(register_cb_mtx);
+ if (cb && cb_name) {
+ cb(RA_HANDOFF, cb_name, cb_data);
+ called_back = TRUE;
+ }
+ }
+ if (cb && !called_back) {
+ cb(RA_HANDOFF, "Registration finished", cb_data);
+ }
+
+ g_async_queue_unref(register_cb_done_q);
+}
+
+void
+*register_all_protocol_handoffs_worker(void *arg _U_)
+{
"""
for symbol in regs['handoff_reg']:
if registertype != "plugin" and registertype != "plugin_wtap":
- reg_code += " CALLBACK_HANDOFF(\"%s\", cb_data);\n" % (symbol)
+ reg_code += " set_cb_name(\"%s\");\n" % (symbol)
reg_code += " %s();\n" % (symbol)
+if registertype != "plugin" and registertype != "plugin_wtap":
+ reg_code += """
+ g_async_queue_push(register_cb_done_q, GINT_TO_POINTER(TRUE));
+ return NULL;
+"""
reg_code += "}\n"
if registertype == "plugin":