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

Commit

Permalink
Adding real std thread implementation and moving pthreads to its own …
Browse files Browse the repository at this point in the history
…file.

pthreads is still used everywhere but WIN32 right now and will need to
remain around as iOS doesn't support thread_local.

This also picked up an internal change or two that hadn't been mirrored.
  • Loading branch information
Ben Vanik committed Jun 20, 2016
1 parent dfda82f commit e08860e
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 51 deletions.
1 change: 1 addition & 0 deletions bindings/cpp/event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iterator>

namespace wtf {

Expand Down
7 changes: 6 additions & 1 deletion bindings/cpp/include/wtf/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ void PlatformSetThreadLocalEventBuffer(EventBuffer* event_buffer);

// Select threading library.
#if defined(WTF_SINGLE_THREADED)
// Process is single threaded so avoid TLS.
#include "wtf/platform/platform_aux_single_threaded_inl.h"
#else
#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.
#include "wtf/platform/platform_aux_pthreads_threaded_inl.h"
#endif

#endif // TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_H_
3 changes: 2 additions & 1 deletion bindings/cpp/include/wtf/platform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ disposed of in favor of C++ standard library calls.

Threading models:

* std_threaded (default): Uses C++ std threading library.
* pthreads_threaded (default): Uses pthreads threading library.
* std_threaded: Uses C++ std threading library.
* single_threaded: Uses dummy threading constructs.

Platforms can force a single threaded model, or it is selectable via
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#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_

#include "wtf/buffer.h"

namespace wtf {

namespace internal {
pthread_key_t event_buffer_key;
pthread_once_t initialize_threading_once = PTHREAD_ONCE_INIT;

void EventBufferDtor(void* event_buffer) {
static_cast<EventBuffer*>(event_buffer)->MarkOutOfScope();
}

void InitializeThreadingOnce() {
pthread_key_create(&event_buffer_key, EventBufferDtor);
PlatformInitialize();
}
} // namespace internal

void PlatformInitializeThreading() {
pthread_once(&internal::initialize_threading_once,
internal::InitializeThreadingOnce);
}

void PlatformSetThreadLocalEventBuffer(EventBuffer* event_buffer) {
pthread_once(&internal::initialize_threading_once,
internal::InitializeThreadingOnce);
pthread_setspecific(internal::event_buffer_key, event_buffer);
}

} // namespace wtf

#endif // TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_PTHREADS_THREADED_IMPL_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Provides the PlatformGetThreadLocalEventBuffer() function by using
// pthread keys. This should work for all POSIX platforms.
#ifndef TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_PTHREADS_THREADED_INL_H_
#define TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_PTHREADS_THREADED_INL_H_

#include <pthread.h>

#include <atomic>
#include <mutex>

namespace wtf {

// On this platform, use the standard-library versions of atomics and mutexes.
namespace platform {
using mutex = std::mutex;

template <typename T>
using lock_guard = std::lock_guard<T>;

template <typename T>
using atomic = std::atomic<T>;

// Since memory_order is an old-school enum, it needs to be imported
// individually.
using std::memory_order;
using std::memory_order_relaxed;
using std::memory_order_consume;
using std::memory_order_acquire;
using std::memory_order_release;
using std::memory_order_acq_rel;
using std::memory_order_seq_cst;
} // namespace platform

namespace internal {
extern pthread_key_t event_buffer_key;
extern pthread_once_t initialize_threading_once;

void InitializeThreadingOnce();

} // namespace internal

inline EventBuffer* PlatformGetThreadLocalEventBuffer() {
pthread_once(&internal::initialize_threading_once,
internal::InitializeThreadingOnce);
return static_cast<EventBuffer*>(
pthread_getspecific(internal::event_buffer_key));
}

} // namespace wtf

#endif // TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_PTHREADS_THREADED_INL_H_
33 changes: 18 additions & 15 deletions bindings/cpp/include/wtf/platform/platform_aux_std_threaded_impl.h
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
#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 <mutex>

#include "wtf/buffer.h"

namespace wtf {

namespace internal {
pthread_key_t event_buffer_key;
pthread_once_t initialize_threading_once = PTHREAD_ONCE_INIT;
std::once_flag initialize_once_;

void EventBufferDtor(void* event_buffer) {
static_cast<EventBuffer*>(event_buffer)->MarkOutOfScope();
}
thread_local struct ThreadLocalStorage {
ThreadLocalStorage() = default;
~ThreadLocalStorage() {
if (event_buffer) {
event_buffer->MarkOutOfScope();
}
}

EventBuffer* event_buffer = nullptr;
} storage_;

void InitializeThreadingOnce() {
pthread_key_create(&event_buffer_key, EventBufferDtor);
PlatformInitialize();
EventBuffer* PlatformGetThreadLocalEventBuffer() {
return storage_.event_buffer;
}
} // namespace internal

void PlatformInitializeThreading() {
pthread_once(&internal::initialize_threading_once,
internal::InitializeThreadingOnce);
std::call_once(initialize_once_, PlatformInitialize);
}

void PlatformSetThreadLocalEventBuffer(EventBuffer* event_buffer) {
pthread_once(&internal::initialize_threading_once,
internal::InitializeThreadingOnce);
pthread_setspecific(internal::event_buffer_key, event_buffer);
std::call_once(initialize_once_, PlatformInitialize);
storage_.event_buffer = event_buffer;
}

} // namespace wtf
Expand Down
22 changes: 3 additions & 19 deletions bindings/cpp/include/wtf/platform/platform_aux_std_threaded_inl.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
// Provides the PlatformGetThreadLocalEventBuffer() function by using
// pthread keys. This should work for all POSIX platforms, but will need
// to be different for Windows.
// C++11 thread_local variables. Should work on most modern platforms (besides
// iOS).
#ifndef TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_STD_THREADED_INL_H_
#define TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_STD_THREADED_INL_H_

#include <atomic>
#include <mutex>

// TODO(wcraddock, laurenzo): Begin using the C++11 thread interface.
#include <pthread.h>

namespace wtf {

// On this platform, use the standard-library versions of atomics and mutexes.
Expand All @@ -33,20 +30,7 @@ using std::memory_order_acq_rel;
using std::memory_order_seq_cst;
} // namespace platform

namespace internal {
extern pthread_key_t event_buffer_key;
extern pthread_once_t initialize_threading_once;

void InitializeThreadingOnce();

} // namespace internal

inline EventBuffer* PlatformGetThreadLocalEventBuffer() {
pthread_once(&internal::initialize_threading_once,
internal::InitializeThreadingOnce);
return static_cast<EventBuffer*>(
pthread_getspecific(internal::event_buffer_key));
}
EventBuffer* PlatformGetThreadLocalEventBuffer();

} // namespace wtf

Expand Down
1 change: 1 addition & 0 deletions bindings/cpp/include/wtf/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ class Runtime {

platform::mutex mu_;
std::vector<std::unique_ptr<EventBuffer>> thread_event_buffers_;
int uniquifier_ = 0;
};

} // namespace wtf
Expand Down
4 changes: 3 additions & 1 deletion bindings/cpp/platform.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
// Select threading library.
#if defined(WTF_SINGLE_THREADED)
#include "wtf/platform/platform_aux_single_threaded_impl.h"
#else
#elif defined(WIN32)
#include "wtf/platform/platform_aux_std_threaded_impl.h"
#else
#include "wtf/platform/platform_aux_pthreads_threaded_impl.h"
#endif
27 changes: 13 additions & 14 deletions bindings/cpp/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -116,29 +116,28 @@ void Runtime::EnableCurrentThread(const char* thread_name, const char* type,
if (PlatformGetThreadLocalEventBuffer()) {
return;
}
EventBuffer* event_buffer;
{
platform::lock_guard<platform::mutex> lock{mu_};
event_buffer = CreateThreadEventBuffer();
}

int zone_id =
ZoneRegistry::GetInstance()->CreateZone(thread_name, type, location);
StandardEvents::SetZone(event_buffer, zone_id);
event_buffer->FreezePrefixSlots();
EventBuffer* event_buffer =
RegisterExternalThread(thread_name, type, location);
PlatformSetThreadLocalEventBuffer(event_buffer);
}

EventBuffer* Runtime::RegisterExternalThread(const char* thread_name,
const char* type,
const char* location) {
EventBuffer* event_buffer;
int unique_id;
{
platform::lock_guard<platform::mutex> lock{mu_};
event_buffer = CreateThreadEventBuffer();
unique_id = uniquifier_++;
}
int zone_id =
ZoneRegistry::GetInstance()->CreateZone(thread_name, type, location);
// Add uniquifier to the provided thread name to make sure that
// different threads don't get attributed to the same zone.
std::ostringstream ss;
ss << unique_id << ":" << thread_name;
std::string unique_name = ss.str();
int zone_id = ZoneRegistry::GetInstance()->CreateZone(unique_name.c_str(),
type, location);
StandardEvents::SetZone(event_buffer, zone_id);
event_buffer->FreezePrefixSlots();
return event_buffer;
Expand All @@ -157,10 +156,10 @@ bool Runtime::SaveToFile(const std::string& file_name,
return false;
}

bool append = (mode & std::ios_base::app);
bool append = (mode & std::ios_base::app) ? true : false;

// If the file was deleted out from under us, reset the checkpoint.
if (append && save_options.checkpoint && out.tellp() == 0) {
if (append && save_options.checkpoint && out.tellp() == std::streampos(0)) {
*save_options.checkpoint = SaveCheckpoint{};
}

Expand Down

0 comments on commit e08860e

Please sign in to comment.