diff options
author | Gerald Combs <gerald@wireshark.org> | 2017-11-14 15:58:32 -0800 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2017-11-16 06:11:55 +0000 |
commit | ac1d52aff5bdf74600ddc2f8f06ceccf9d2037a6 (patch) | |
tree | f36410bffc6f0a13a2562e5b2b9d548636c67ecf /tools | |
parent | 665eb78729c91b4056b3e58af4407f51df603f55 (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-x | tools/make-dissector-reg.py | 88 |
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", ®ister_all_protocols_worker, NULL); +#else + g_thread_create(®ister_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", ®ister_all_protocol_handoffs_worker, NULL); +#else + g_thread_create(®ister_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": |