Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Commit

Permalink
Introduce auto thread naming.
Browse files Browse the repository at this point in the history
  • Loading branch information
Stella Laurenzo committed Jan 12, 2017
1 parent e08860e commit 7b3567a
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 18 deletions.
20 changes: 15 additions & 5 deletions bindings/cpp/Makefile
Expand Up @@ -7,9 +7,16 @@
# Installs headers and libraies to PREFIX
# make clean
# Cleans all generated files.
#
# Note that the threading library can be defined via:
# THREADING=pthread|std|single
# It defaults to pthread, which is lowest-common-denominator for non Windows.
# In theory on platforms that implement it well, std can be more efficient.
# However, many platforms silently don't implement std threading or support
# it badly (cough. Android).

# Flag defaults. Can be overriden.
THREADING = multi
THREADING ?= pthread
CXXFLAGS = -std=c++11 -Wall -Werror -O3 -fPIC
LDLIBS =
SOEXT = so
Expand All @@ -19,15 +26,18 @@ PREFIX=/usr/local
INSTALL=install

# Threading customizations.
ifeq "$(THREADING)" "multi"
ifeq "$(THREADING)" "pthread"
override CPPFLAGS += -DGTEST_HAS_PTHREAD=1 -DWTF_PTHREAD_THREADED
override LDLIBS += -pthread
else ifeq "$(THREADING)" "std"
override CPPFLAGS += -DGTEST_HAS_PTHREAD=1
override LDLIBS += -pthread
else ifeq "$(THREADING)" "single"
override CPPFLAGS += -DGTEST_HAS_PTHREAD=0
override CPPFLAGS += -DWTF_SINGLE_THREADED
.PHONY: threaded_torture_test
else
$(error Expected value of THREADING to be "single" or "multi")
$(error Expected value of THREADING to be single/pthread/std)
endif

# Required flag customizations.
Expand Down Expand Up @@ -104,7 +114,7 @@ test: buffer_test macros_test runtime_test threaded_torture_test
./macros_test
@echo "Running runtime_test"
./runtime_test
ifeq "$(THREADING)" "multi"
ifneq "$(THREADING)" "single"
@echo "Running threaded_torture_test"
time ./threaded_torture_test
endif
Expand All @@ -123,7 +133,7 @@ runtime_test: runtime_test.o gtest.o libwtf.a
$(CXX) -o $@ $+ $(LDLIBS)

### THREADED TORTURE TEST
ifeq "$(THREADING)" "multi"
ifneq "$(THREADING)" "single"
threaded_torture_test: threaded_torture_test.o libwtf.a
$(CXX) -o $@ $+ $(LDLIBS)
endif
Expand Down
4 changes: 2 additions & 2 deletions bindings/cpp/README.md
Expand Up @@ -115,14 +115,14 @@ TODO: Automate more of this.
#### Linux/GCC:

```
make clean && make test THREADING=multi CXX=g++
make clean && make test THREADING=pthread CXX=g++
make clean && make test THREADING=single CXX=g++
```

#### Linux/clang:

```
make clean && make test THREADING=multi CXX=clang++
make clean && make test THREADING=pthread CXX=clang++
make clean && make test THREADING=single CXX=clang++
```

Expand Down
19 changes: 17 additions & 2 deletions bindings/cpp/include/wtf/macros.h
Expand Up @@ -31,10 +31,14 @@
#define WTF_NAMESPACE_DISABLE() \
static constexpr bool kWtfEnabledForNamespace = false

// Enables WTF tracing for a thread based on a condition.
// Enables WTF tracing for a thread based on a condition. If the thread
// is already enabled for WTF, then this is a no-op. Enabling multiple
// threads with the same name will cause different WTF zones with a machine
// generated suffix to be produced.
// Allowed Scopes: Within a function.
#define WTF_THREAD_ENABLE_IF(condition, name) \
if (condition) { \
if (condition && \
!__INTERNAL_WTF_NAMESPACE::PlatformGetThreadLocalEventBuffer()) { \
__INTERNAL_WTF_NAMESPACE::Runtime::GetInstance()->EnableCurrentThread( \
name, nullptr, __FILE__); \
}
Expand All @@ -44,6 +48,17 @@
#define WTF_THREAD_ENABLE(name) \
WTF_THREAD_ENABLE_IF(kWtfEnabledForNamespace, name)

// Same as WTF_THREAD_ENABLE_IF but uses a platform specific mechanism for
// deriving the thread name for the current thread.
#define WTF_AUTO_THREAD_ENABLE_IF(condition) \
WTF_THREAD_ENABLE_IF( \
condition, __INTERNAL_WTF_NAMESPACE::PlatformGetThreadName().c_str())

// Same as WTF_THREAD_ENABLE_IF conditioned on whether the current namespace
// is enabled.
#define WTF_AUTO_THREAD_ENABLE() \
WTF_AUTO_THREAD_ENABLE_IF(kWtfEnabledForNamespace)

// Shortcut to trace a no-arg event.
// Allowed Scopes: Within a function.
// This creates an anonymous event anchored to the specific location in the
Expand Down
16 changes: 11 additions & 5 deletions bindings/cpp/include/wtf/platform.h
Expand Up @@ -4,6 +4,8 @@

#include <stdint.h>

#include <string>

namespace wtf {

// Forward declare the event buffer.
Expand All @@ -28,6 +30,10 @@ EventBuffer* PlatformGetThreadLocalEventBuffer();
// true because EventBuffers are never deleted.
void PlatformSetThreadLocalEventBuffer(EventBuffer* event_buffer);

// Uses platform specific means to get a thread name for the current thread.
// Depending on platform, this name may be synthetic or completely non-unique.
std::string PlatformGetThreadName();

} // namespace wtf

// Branch to for specific platform implementations.
Expand All @@ -43,12 +49,12 @@ void PlatformSetThreadLocalEventBuffer(EventBuffer* event_buffer);
#if defined(WTF_SINGLE_THREADED)
// Process is single threaded so avoid TLS.
#include "wtf/platform/platform_aux_single_threaded_inl.h"
#elif defined(WIN32)
// Modern VC++ supports C++11 std threading.
#include "wtf/platform/platform_aux_std_threaded_inl.h"
#else
// Other platforms default to pthreads.
#elif defined(WTF_PTHREAD_THREADED)
// Explicitly use pthreads instead of std::thread.
#include "wtf/platform/platform_aux_pthreads_threaded_inl.h"
#else
// Default to std::thread and friends.
#include "wtf/platform/platform_aux_std_threaded_inl.h"
#endif

#endif // TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_H_
@@ -1,6 +1,14 @@
#ifndef TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_PTHREADS_THREADED_IMPL_H_
#define TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_PTHREADS_THREADED_IMPL_H_

// Only include non-portable pthread APIs where supported.
#if defined(__APPLE__)
#include <pthread_np.h>
#endif

#include <algorithm>
#include <cstring>

#include "wtf/buffer.h"

namespace wtf {
Expand Down Expand Up @@ -30,6 +38,20 @@ void PlatformSetThreadLocalEventBuffer(EventBuffer* event_buffer) {
pthread_setspecific(internal::event_buffer_key, event_buffer);
}

std::string PlatformGetThreadName() {
#if defined(__APPLE__)
return std::to_string(pthread_getthreadid_np());
#else
// The ultimate fallback mechanism for getting a thread id involves bit
// casting pthread_self() to an integer. This sucks but is portable.
// Add platform-specific special cases above.
pthread_t current = pthread_self();
uintptr_t result = 0;
std::memcpy(&result, &current, std::min(sizeof(current), sizeof(result)));
return std::to_string(result);
#endif
}

} // namespace wtf

#endif // TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_PTHREADS_THREADED_IMPL_H_
Expand Up @@ -21,6 +21,8 @@ void PlatformSetThreadLocalEventBuffer(EventBuffer* new_event_buffer) {
wtf::internal::event_buffer = new_event_buffer;
}

std::string PlatformGetThreadName() { return "Main"; }

} // namespace wtf

#endif // TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_SINGLE_THREADED_IMPL_H_
@@ -1,6 +1,7 @@
#ifndef TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_STD_THREADED_IMPL_H_
#define TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_STD_THREADED_IMPL_H_

#include <functional>
#include <mutex>

#include "wtf/buffer.h"
Expand Down Expand Up @@ -33,6 +34,14 @@ void PlatformSetThreadLocalEventBuffer(EventBuffer* event_buffer) {
storage_.event_buffer = event_buffer;
}

std::string PlatformGetThreadName() {
// Note: Many platforms have richer APIs for getting friendly thread
// names. Feel free to add platform specific conditionals prior to this
// fallback.
return std::to_string(
std::hash<std::thread::id>{}(std::this_thread::get_id()));
}

} // namespace wtf

#endif // TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_STD_THREADED_IMPL_H_
Expand Up @@ -6,6 +6,7 @@

#include <atomic>
#include <mutex>
#include <thread>

namespace wtf {

Expand Down
12 changes: 12 additions & 0 deletions bindings/cpp/macros_test.cc
Expand Up @@ -56,6 +56,12 @@ TEST_F(MacrosTest, ThreadShouldBeDisabled) {
EXPECT_FALSE(EventsHaveBeenLogged());
}

TEST_F(MacrosTest, AutoThreadShouldBeDisabled) {
WTF_AUTO_THREAD_ENABLE();
// Enabling a thread scribbles into the buffer.
EXPECT_FALSE(EventsHaveBeenLogged());
}

TEST_F(MacrosTest, EventsShouldBeDisabled) {
WTF_THREAD_ENABLE_IF(true, "ShouldBeDisabled");
EXPECT_TRUE(PrefixEventsHaveBeenLogged());
Expand All @@ -82,6 +88,12 @@ TEST_F(MacrosTest, ThreadShouldBeEnabled) {
EXPECT_TRUE(PrefixEventsHaveBeenLogged());
}

TEST_F(MacrosTest, AutoThreadShouldBeEnabled) {
WTF_AUTO_THREAD_ENABLE();
// Enabling a thread scribbles into the buffer.
EXPECT_TRUE(PrefixEventsHaveBeenLogged());
}

TEST_F(MacrosTest, EventsShouldBeEnabled) {
WTF_THREAD_ENABLE_IF(true, "ShouldBeEnabled");
// Enabling a thread should only write prefix events.
Expand Down
6 changes: 3 additions & 3 deletions bindings/cpp/platform.cc
Expand Up @@ -11,8 +11,8 @@
// Select threading library.
#if defined(WTF_SINGLE_THREADED)
#include "wtf/platform/platform_aux_single_threaded_impl.h"
#elif defined(WIN32)
#include "wtf/platform/platform_aux_std_threaded_impl.h"
#else
#elif defined(WTF_PTHREAD_THREADED)
#include "wtf/platform/platform_aux_pthreads_threaded_impl.h"
#else
#include "wtf/platform/platform_aux_std_threaded_impl.h"
#endif
2 changes: 1 addition & 1 deletion bindings/cpp/threaded_torture_test.cc
Expand Up @@ -15,7 +15,7 @@ std::atomic<bool> stop;
std::vector<std::string> thread_names;

void SaveThread() {
WTF_THREAD_ENABLE("SaveThread");
WTF_AUTO_THREAD_ENABLE();
wtf::Runtime::SaveCheckpoint checkpoint;
for (int i = 0; i < 1001; i++) {
if (i > 0 && (i % 250) == 0) {
Expand Down

0 comments on commit 7b3567a

Please sign in to comment.