aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_async.c
diff options
context:
space:
mode:
authorScott Lystig Fritchie <[email protected]>2011-11-17 00:45:50 -0600
committerPatrik Nyblom <[email protected]>2012-03-22 18:16:13 +0100
commit2f532f889a6bd31f74122bd223277d7c609f7bdc (patch)
tree8c0463bf781059147caeb31c2594ed211d4854e6 /erts/emulator/beam/erl_async.c
parent0331c29e0e494d4c1e4fdd05e48a3f88a8caea0b (diff)
downloadotp-2f532f889a6bd31f74122bd223277d7c609f7bdc.tar.gz
otp-2f532f889a6bd31f74122bd223277d7c609f7bdc.tar.bz2
otp-2f532f889a6bd31f74122bd223277d7c609f7bdc.zip
Add DTrace support for OS X, Solaris, and Linux (via SystemTap), 3/4
Add probes to the virtual machine, except (mostly) the efile_drv.c driver and other file I/O-related source files.
Diffstat (limited to 'erts/emulator/beam/erl_async.c')
-rw-r--r--erts/emulator/beam/erl_async.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_async.c b/erts/emulator/beam/erl_async.c
index 8bca9ae582..72dcc99f4f 100644
--- a/erts/emulator/beam/erl_async.c
+++ b/erts/emulator/beam/erl_async.c
@@ -26,6 +26,7 @@
#include "erl_threads.h"
#include "erl_thr_queue.h"
#include "erl_async.h"
+#include "dtrace-wrapper.h"
#define ERTS_MAX_ASYNC_READY_CALLS_IN_SEQ 20
@@ -121,6 +122,14 @@ typedef struct {
#endif
} ErtsAsyncData;
+/*
+ * Some compilers, e.g. GCC 4.2.1 and -O3, will optimize away DTrace
+ * calls if they're the last thing in the function. :-(
+ * Many thanks to Trond Norbye, via:
+ * https://github.com/memcached/memcached/commit/6298b3978687530bc9d219b6ac707a1b681b2a46
+ */
+static unsigned gcc_optimizer_hack = 0;
+
int erts_async_max_threads; /* Initialized by erl_init.c */
int erts_async_thread_suggested_stack_size; /* Initialized by erl_init.c */
@@ -244,6 +253,9 @@ erts_get_async_ready_queue(Uint sched_id)
static ERTS_INLINE void async_add(ErtsAsync *a, ErtsAsyncQ* q)
{
+ /* DTRACE TODO: Get the queue length from erts_thr_q_enqueue() */
+ int len = -1;
+
if (is_internal_port(a->port)) {
#if ERTS_USE_ASYNC_READY_Q
ErtsAsyncReadyQ *arq = async_ready_q(a->sched_id);
@@ -259,6 +271,13 @@ static ERTS_INLINE void async_add(ErtsAsync *a, ErtsAsyncQ* q)
#endif
erts_thr_q_enqueue(&q->thr_q, a);
+ if (DTRACE_ENABLED(aio_pool_add)) {
+ DTRACE_CHARBUF(port_str, 16);
+
+ erts_snprintf(port_str, sizeof(port_str), "%T", a->port);
+ DTRACE2(aio_pool_add, port_str, len);
+ }
+ gcc_optimizer_hack++;
}
static ERTS_INLINE ErtsAsync *async_get(ErtsThrQ_t *q,
@@ -269,6 +288,8 @@ static ERTS_INLINE ErtsAsync *async_get(ErtsThrQ_t *q,
int saved_fin_deq = 0;
ErtsThrQFinDeQ_t fin_deq;
#endif
+ /* DTRACE TODO: Get the queue length from erts_thr_q_dequeue() somehow? */
+ int len = -1;
while (1) {
ErtsAsync *a = (ErtsAsync *) erts_thr_q_dequeue(q);
@@ -280,7 +301,12 @@ static ERTS_INLINE ErtsAsync *async_get(ErtsThrQ_t *q,
if (saved_fin_deq)
erts_thr_q_append_finalize_dequeue_data(&a->q.fin_deq, &fin_deq);
#endif
+ if (DTRACE_ENABLED(aio_pool_get)) {
+ DTRACE_CHARBUF(port_str, 16);
+ erts_snprintf(port_str, sizeof(port_str), "%T", a->port);
+ DTRACE2(aio_pool_get, port_str, len);
+ }
return a;
}