diff --git a/config-unix.mk b/config-unix.mk index f9f2c15e..c6b34a12 100644 --- a/config-unix.mk +++ b/config-unix.mk @@ -33,6 +33,10 @@ RUNNER_SRC=test/runner-unix.c RUNNER_CFLAGS=$(CFLAGS) -I$(SRCDIR)/test RUNNER_LDFLAGS=-L"$(CURDIR)" -luv -Xlinker -rpath -Xlinker "$(CURDIR)" +HAVE_DTRACE= +DTRACE_OBJS= +DTRACE_HEADER= + OBJS += src/unix/async.o OBJS += src/unix/core.o OBJS += src/unix/dl.o @@ -58,11 +62,14 @@ OBJS += src/inet.o OBJS += src/version.o ifeq (sunos,$(PLATFORM)) +HAVE_DTRACE=1 CPPFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500 LDFLAGS+=-lkstat -lnsl -lsendfile -lsocket # Library dependencies are not transitive. RUNNER_LDFLAGS += $(LDFLAGS) OBJS += src/unix/sunos.o +OBJS += src/unix/dtrace.o +DTRACE_OBJS += src/unix/core.o endif ifeq (aix,$(PLATFORM)) @@ -72,6 +79,7 @@ OBJS += src/unix/aix.o endif ifeq (darwin,$(PLATFORM)) +HAVE_DTRACE=1 CPPFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 LDFLAGS += -framework Foundation \ -framework CoreServices \ @@ -96,6 +104,7 @@ OBJS += src/unix/linux-core.o \ endif ifeq (freebsd,$(PLATFORM)) +HAVE_DTRACE=1 LDFLAGS+=-lkvm OBJS += src/unix/freebsd.o OBJS += src/unix/kqueue.o @@ -132,6 +141,11 @@ else RUNNER_LDFLAGS += -pthread endif +ifeq ($(HAVE_DTRACE), 1) +DTRACE_HEADER=src/unix/uv-dtrace.h +CFLAGS += -DHAVE_DTRACE +endif + libuv.a: $(OBJS) $(AR) rcs $@ $^ @@ -151,7 +165,7 @@ src/.buildstamp src/unix/.buildstamp test/.buildstamp: mkdir -p $(@D) touch $@ -src/unix/%.o src/unix/%.pic.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h src/unix/.buildstamp +src/unix/%.o src/unix/%.pic.o: src/unix/%.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h src/unix/.buildstamp $(DTRACE_HEADER) $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ src/%.o src/%.pic.o: src/%.c include/uv.h include/uv-private/uv-unix.h src/.buildstamp @@ -161,7 +175,16 @@ test/%.o: test/%.c include/uv.h test/.buildstamp $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ clean-platform: - $(RM) test/run-{tests,benchmarks}.dSYM $(OBJS) $(OBJS:%.o=%.pic.o) + $(RM) test/run-{tests,benchmarks}.dSYM $(OBJS) $(OBJS:%.o=%.pic.o) src/unix/uv-dtrace.h %.pic.o %.o: %.m $(OBJC) $(CPPFLAGS) $(CFLAGS) -c $^ -o $@ + +src/unix/uv-dtrace.h: src/unix/uv-dtrace.d + dtrace -h -xnolibs -s src/unix/uv-dtrace.d -o $@ + +src/unix/dtrace.o: src/unix/uv-dtrace.d $(DTRACE_OBJS) + dtrace -G -s $^ -o $@ + +src/unix/dtrace.pic.o: src/unix/uv-dtrace.d $(DTRACE_OBJS:%.o=%.pic.o) + dtrace -G -s $^ -o $@ diff --git a/src/unix/core.c b/src/unix/core.c index 9b471ec7..b8bae48a 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -299,6 +299,8 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) { r = uv__loop_alive(loop); while (r != 0 && loop->stop_flag == 0) { + UV_TICK_START(loop, mode); + uv__update_time(loop); uv__run_timers(loop); uv__run_idle(loop); @@ -314,6 +316,8 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) { uv__run_closing_handles(loop); r = uv__loop_alive(loop); + UV_TICK_STOP(loop, mode); + if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT)) break; } diff --git a/src/unix/internal.h b/src/unix/internal.h index 4053d424..899c972b 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -256,4 +256,11 @@ static void uv__update_time(uv_loop_t* loop) { loop->time = uv__hrtime() / 1000000; } +#ifdef HAVE_DTRACE +#include "uv-dtrace.h" +#else +#define UV_TICK_START(arg0, arg1) +#define UV_TICK_STOP(arg0, arg1) +#endif + #endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/src/unix/uv-dtrace.d b/src/unix/uv-dtrace.d new file mode 100644 index 00000000..7848450c --- /dev/null +++ b/src/unix/uv-dtrace.d @@ -0,0 +1,25 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +provider uv { + probe tick__start(void* loop, int mode); + probe tick__stop(void* loop, int mode); +}; diff --git a/uv.gyp b/uv.gyp index db90ee90..7824819a 100644 --- a/uv.gyp +++ b/uv.gyp @@ -1,4 +1,13 @@ { + 'variables': { + 'uv_use_dtrace%': 'false', + # uv_parent_path is the relative path to libuv in the parent project + # this is only relevant when dtrace is enabled and libuv is a child project + # as it's necessary to correctly locate the object files for post + # processing. + 'uv_parent_path': '', + }, + 'target_defaults': { 'conditions': [ ['OS != "win"', { @@ -248,7 +257,17 @@ }], ['library=="shared_library"', { 'defines': [ 'BUILDING_UV_SHARED=1' ] - }] + }], + ['uv_use_dtrace=="true"', { + 'defines': [ 'HAVE_DTRACE=1' ], + 'dependencies': [ 'uv_dtrace_header' ], + 'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ], + 'conditions': [ + ['OS != "mac"', { + 'sources': ['src/unix/dtrace.c' ], + }], + ], + }], ] }, @@ -426,6 +445,48 @@ 'SubSystem': 1, # /subsystem:console }, }, - } + }, + + { + 'target_name': 'uv_dtrace_header', + 'type': 'none', + 'conditions': [ + [ 'uv_use_dtrace=="true"', { + 'actions': [ + { + 'action_name': 'uv_dtrace_header', + 'inputs': [ 'src/unix/uv-dtrace.d' ], + 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/uv-dtrace.h' ], + 'action': [ 'dtrace', '-h', '-xnolibs', '-s', '<@(_inputs)', + '-o', '<@(_outputs)' ], + }, + ], + }], + ], + }, + + { + 'target_name': 'uv_dtrace_provider', + 'type': 'none', + 'conditions': [ + [ 'uv_use_dtrace=="true" and OS!="mac"', { + 'actions': [ + { + 'action_name': 'uv_dtrace_o', + 'inputs': [ + 'src/unix/uv-dtrace.d', + '<(PRODUCT_DIR)/obj.target/libuv/<(uv_parent_path)/src/unix/core.o', + ], + 'outputs': [ + '<(PRODUCT_DIR)/obj.target/libuv/<(uv_parent_path)/src/unix/dtrace.o', + ], + 'action': [ 'dtrace', '-G', '-xnolibs', '-s', '<@(_inputs)', + '-o', '<@(_outputs)' ] + } + ] + } ] + ] + }, + ] }