Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Unified Diff: tools/cygprofile/cygprofile.cc

Issue 1883093005: Reland (2) of Enable allocator shim for Android (crrev.com/1875043003) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix comment Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/config/allocator.gni ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/cygprofile/cygprofile.cc
diff --git a/tools/cygprofile/cygprofile.cc b/tools/cygprofile/cygprofile.cc
index d699c3e355bd255250df242b449a4a9424bc8b67..c7f12e8b49f62a76ada01584c596cdc22ab1a447 100644
--- a/tools/cygprofile/cygprofile.cc
+++ b/tools/cygprofile/cygprofile.cc
@@ -51,7 +51,27 @@ const char kLogFilenameFormat[] = "%scyglog.%d.%d-%d";
ThreadLog* const kMagicBeingConstructed = reinterpret_cast<ThreadLog*>(1);
// Per-thread pointer to the current log object.
-static __thread ThreadLog* g_tls_log = NULL;
+pthread_key_t g_tls_slot;
+
+// Used to initialize the tls slot, once per the entire process.
+pthread_once_t g_tls_slot_initializer_once = PTHREAD_ONCE_INIT;
+
+// This variable is to prevent re-entrancy in the __cyg_profile_func_enter()
+// while the TLS slot itself is being initialized. Volatile here is required
+// to avoid compiler optimizations as this need to be read in a re-entrant way.
+// This variable is written by one thread only, which is the first thread that
+// happens to run the TLSSlotInitializer(). In practice this will happen very
+// early in the startup process, as soon as the first instrumented function is
+// called.
+volatile bool g_tls_slot_being_initialized = false;
+
+// Initializes the global TLS slot. This is invoked only once per process.
+static void TLSSlotInitializer()
+{
+ g_tls_slot_being_initialized = true;
+ PCHECK(0 == pthread_key_create(&g_tls_slot, NULL));
+ g_tls_slot_being_initialized = false;
+}
// Returns light-weight process ID. On Linux, this is a system-wide unique
// thread id.
@@ -151,11 +171,11 @@ class Thread {
public:
Thread(const base::Closure& thread_callback)
: thread_callback_(thread_callback) {
- CHECK_EQ(0, pthread_create(&handle_, NULL, &Thread::EntryPoint, this));
+ PCHECK(0 == pthread_create(&handle_, NULL, &Thread::EntryPoint, this));
}
~Thread() {
- CHECK_EQ(0, pthread_join(handle_, NULL));
+ PCHECK(0 == pthread_join(handle_, NULL));
}
private:
@@ -163,8 +183,11 @@ class Thread {
// Disable logging on this thread. Although this routine is not instrumented
// (cygprofile.gyp provides that), the called routines are and thus will
// call instrumentation.
- CHECK(g_tls_log == NULL); // Must be 0 as this is a new thread.
- g_tls_log = kMagicBeingConstructed;
+ pthread_once(&g_tls_slot_initializer_once, TLSSlotInitializer);
+ ThreadLog* thread_log = reinterpret_cast<ThreadLog*>(
+ pthread_getspecific(g_tls_slot));
+ CHECK(thread_log == NULL); // Must be 0 as this is a new thread.
+ PCHECK(0 == pthread_setspecific(g_tls_slot, kMagicBeingConstructed));
Thread* const instance = reinterpret_cast<Thread*>(data);
instance->thread_callback_.Run();
@@ -199,7 +222,7 @@ ThreadLog::ThreadLog(const FlushCallback& flush_callback)
}
ThreadLog::~ThreadLog() {
- g_tls_log = NULL;
+ PCHECK(0 == pthread_setspecific(g_tls_slot, NULL));
}
void ThreadLog::AddEntry(void* address) {
@@ -358,16 +381,24 @@ void __cyg_profile_func_exit(void* this_fn, void* call_site)
__attribute__((no_instrument_function));
void __cyg_profile_func_enter(void* this_fn, void* callee_unused) {
- if (g_tls_log == NULL) {
- g_tls_log = kMagicBeingConstructed;
- ThreadLog* new_log = new ThreadLog();
- CHECK(new_log);
- g_logs_manager.Pointer()->AddLog(base::WrapUnique(new_log));
- g_tls_log = new_log;
+ // Avoid re-entrancy while initializing the TLS slot (once per process).
+ if (g_tls_slot_being_initialized)
+ return;
+
+ pthread_once(&g_tls_slot_initializer_once, TLSSlotInitializer);
+ ThreadLog* thread_log = reinterpret_cast<ThreadLog*>(
+ pthread_getspecific(g_tls_slot));
+
+ if (thread_log == NULL) {
+ PCHECK(0 == pthread_setspecific(g_tls_slot, kMagicBeingConstructed));
+ thread_log = new ThreadLog();
+ CHECK(thread_log);
+ g_logs_manager.Pointer()->AddLog(base::WrapUnique(thread_log));
+ PCHECK(0 == pthread_setspecific(g_tls_slot, thread_log));
}
- if (g_tls_log != kMagicBeingConstructed)
- g_tls_log->AddEntry(this_fn);
+ if (thread_log != kMagicBeingConstructed)
+ thread_log->AddEntry(this_fn);
}
void __cyg_profile_func_exit(void* this_fn, void* call_site) {}
« no previous file with comments | « build/config/allocator.gni ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698