summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authormnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-18 17:11:15 +0000
committermnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-18 17:11:15 +0000
commit9483034e46cf077d5c192e9c074a424e94afa179 (patch)
treeb30f76c221fb66d199418e8f5355397691bf2825 /third_party
parent5e83e609de9acac8186bf24641367467cc55d0aa (diff)
downloadchromium_src-9483034e46cf077d5c192e9c074a424e94afa179.zip
chromium_src-9483034e46cf077d5c192e9c074a424e94afa179.tar.gz
chromium_src-9483034e46cf077d5c192e9c074a424e94afa179.tar.bz2
Partially revert r173151 - Switch prefs::kExtensionInstallForceList to be a dictionary.
It accidentally included local tcmalloc changes not part of the CL. BUG=None TEST=Everything builds and passes tests. TBR=mnissler@chromium.org Review URL: https://codereview.chromium.org/11614031 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173746 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r--third_party/tcmalloc/chromium/src/gperftools/profiler.h4
-rw-r--r--third_party/tcmalloc/chromium/src/profile-handler.cc304
-rw-r--r--third_party/tcmalloc/chromium/src/profile-handler.h12
-rw-r--r--third_party/tcmalloc/chromium/src/profiler.cc5
-rw-r--r--third_party/tcmalloc/chromium/src/tests/profile-handler_unittest.cc1
-rw-r--r--third_party/tcmalloc/chromium/src/tests/profiler_unittest.cc2
6 files changed, 171 insertions, 157 deletions
diff --git a/third_party/tcmalloc/chromium/src/gperftools/profiler.h b/third_party/tcmalloc/chromium/src/gperftools/profiler.h
index 72a74ba..07323e4 100644
--- a/third_party/tcmalloc/chromium/src/gperftools/profiler.h
+++ b/third_party/tcmalloc/chromium/src/gperftools/profiler.h
@@ -150,10 +150,6 @@ PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads();
*/
PERFTOOLS_DLL_DECL void ProfilerRegisterThread();
-/* Routine for unregistering new threads with the profiler.
- */
-PERFTOOLS_DLL_DECL void ProfilerUnregisterThread();
-
/* Stores state about profiler's current status into "*state". */
struct ProfilerState {
int enabled; /* Is profiling currently enabled? */
diff --git a/third_party/tcmalloc/chromium/src/profile-handler.cc b/third_party/tcmalloc/chromium/src/profile-handler.cc
index 1abc922..20e5cca 100644
--- a/third_party/tcmalloc/chromium/src/profile-handler.cc
+++ b/third_party/tcmalloc/chromium/src/profile-handler.cc
@@ -38,12 +38,11 @@
#if !(defined(__CYGWIN__) || defined(__CYGWIN32__))
-#include <errno.h>
#include <stdio.h>
+#include <errno.h>
#include <sys/time.h>
#include <list>
-#include <map>
#include <string>
#include "base/dynamic_annotations.h"
@@ -53,7 +52,6 @@
#include "maybe_threads.h"
using std::list;
-using std::map;
using std::string;
// This structure is used by ProfileHandlerRegisterCallback and
@@ -71,47 +69,39 @@ struct ProfileHandlerToken {
void* callback_arg;
};
-// Blocks a signal from being delivered to the current thread while the object
-// is alive. Restores previous state upon destruction.
-class ScopedSignalBlocker {
- public:
- ScopedSignalBlocker(int signo) {
- sigemptyset(&sig_set_);
- sigaddset(&sig_set_, signo);
- RAW_CHECK(sigprocmask(SIG_BLOCK, &sig_set_, NULL) == 0,
- "sigprocmask (block)");
- }
- ~ScopedSignalBlocker() {
- RAW_CHECK(sigprocmask(SIG_UNBLOCK, &sig_set_, NULL) == 0,
- "sigprocmask (unblock)");
- }
-
- private:
- sigset_t sig_set_;
-};
-
// This class manages profile timers and associated signal handler. This is a
// a singleton.
class ProfileHandler {
public:
- // Registers the current thread with the profile handler.
+ // Registers the current thread with the profile handler. On systems which
+ // have a separate interval timer for each thread, this function starts the
+ // timer for the current thread.
+ //
+ // The function also attempts to determine whether or not timers are shared by
+ // all threads in the process. (With LinuxThreads, and with NPTL on some
+ // Linux kernel versions, each thread has separate timers.)
+ //
+ // Prior to determining whether timers are shared, this function will
+ // unconditionally start the timer. However, if this function determines
+ // that timers are shared, then it will stop the timer if no callbacks are
+ // currently registered.
void RegisterThread();
- // Unregisters the current thread with the profile handler.
- void UnregisterThread();
-
// Registers a callback routine to receive profile timer ticks. The returned
// token is to be used when unregistering this callback and must not be
- // deleted by the caller.
+ // deleted by the caller. Registration of the first callback enables the
+ // SIGPROF handler (or SIGALRM if using ITIMER_REAL).
ProfileHandlerToken* RegisterCallback(ProfileHandlerCallback callback,
void* callback_arg);
// Unregisters a previously registered callback. Expects the token returned
- // by the corresponding RegisterCallback routine.
+ // by the corresponding RegisterCallback routine. Unregistering the last
+ // callback disables the SIGPROF handler (or SIGALRM if using ITIMER_REAL).
void UnregisterCallback(ProfileHandlerToken* token)
NO_THREAD_SAFETY_ANALYSIS;
- // Unregisters all the callbacks and stops the timer(s).
+ // Unregisters all the callbacks, stops the timer if shared, disables the
+ // SIGPROF (or SIGALRM) handler and clears the timer_sharing_ state.
void Reset();
// Gets the current state of profile handler.
@@ -135,12 +125,6 @@ class ProfileHandler {
// pthread_once_t for one time initialization of ProfileHandler singleton.
static pthread_once_t once_;
-#if defined(HAVE_TLS)
- // Timer state as configured previously. This bit is kept in
- // |registered_threads_| if TLS is not available.
- static __thread bool timer_running_;
-#endif
-
// Initializes the ProfileHandler singleton via GoogleOnceInit.
static void Init();
@@ -159,6 +143,19 @@ class ProfileHandler {
// Is profiling allowed at all?
bool allowed_;
+ // Whether or not the threading system provides interval timers that are
+ // shared by all threads in a process.
+ enum {
+ // No timer initialization attempted yet.
+ TIMERS_UNTOUCHED,
+ // First thread has registered and set timer.
+ TIMERS_ONE_SET,
+ // Timers are shared by all threads.
+ TIMERS_SHARED,
+ // Timers are separate in each thread.
+ TIMERS_SEPARATE
+ } timer_sharing_ GUARDED_BY(control_lock_);
+
// This lock serializes the registration of threads and protects the
// callbacks_ list below.
// Locking order:
@@ -168,13 +165,6 @@ class ProfileHandler {
SpinLock control_lock_ ACQUIRED_BEFORE(signal_lock_);
SpinLock signal_lock_;
- // Set of threads registered through RegisterThread. This is consulted
- // whenever timers are switched on or off to post a signal to these threads
- // so they can arm their timers. Locking rules as for |callbacks_| below. If
- // TLS is not available, this map is also used to keep the thread's timer
- // state.
- map<pthread_t, bool> registered_threads_ GUARDED_BY(signal_lock_);
-
// Holds the list of registered callbacks. We expect the list to be pretty
// small. Currently, the cpu profiler (base/profiler) and thread module
// (base/thread.h) are the only two components registering callbacks.
@@ -192,18 +182,26 @@ class ProfileHandler {
typedef CallbackList::iterator CallbackIterator;
CallbackList callbacks_ GUARDED_BY(signal_lock_);
- // Returns the signal to be used with |timer_type_| (SIGPROF or SIGALARM).
- int signal_number() {
- return (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
- }
+ // Starts the interval timer. If the thread library shares timers between
+ // threads, this function starts the shared timer. Otherwise, this will start
+ // the timer in the current thread.
+ void StartTimer() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);
+
+ // Stops the interval timer. If the thread library shares timers between
+ // threads, this fucntion stops the shared timer. Otherwise, this will stop
+ // the timer in the current thread.
+ void StopTimer() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);
- // Starts or stops the interval timer(s). In case of non-shared timers, this
- // will post a signal to all registered threads, causing them to arm their
- // timers.
- void UpdateTimers(bool enable) EXCLUSIVE_LOCKS_REQUIRED(signal_lock_);
+ // Returns true if the profile interval timer is enabled in the current
+ // thread. This actually checks the kernel's interval timer setting. (It is
+ // used to detect whether timers are shared or separate.)
+ bool IsTimerRunning() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);
- // Configures the timer. If |frequency| is 0, the timer will be disabled.
- void SetupTimer(int32 frequency) EXCLUSIVE_LOCKS_REQUIRED(signal_lock_);
+ // Sets the timer interrupt signal handler.
+ void EnableHandler() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);
+
+ // Disables (ignores) the timer interrupt signal.
+ void DisableHandler() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);
// Returns true if the handler is not being used by something else.
// This checks the kernel's signal handler table.
@@ -218,21 +216,15 @@ class ProfileHandler {
ProfileHandler* ProfileHandler::instance_ = NULL;
pthread_once_t ProfileHandler::once_ = PTHREAD_ONCE_INIT;
-#if defined(HAVE_TLS)
-bool __thread ProfileHandler::timer_running_ = false;
-#endif
-
const int32 ProfileHandler::kMaxFrequency;
const int32 ProfileHandler::kDefaultFrequency;
-// If we are LD_PRELOAD-ed against a non-pthreads app, then pthread_* functions
-// won't be defined. We declare them here, for that case (with weak linkage)
-// which will cause the non-definition to resolve to NULL. We can then check
-// for NULL or not in Instance.
+// If we are LD_PRELOAD-ed against a non-pthreads app, then
+// pthread_once won't be defined. We declare it here, for that
+// case (with weak linkage) which will cause the non-definition to
+// resolve to NULL. We can then check for NULL or not in Instance.
extern "C" int pthread_once(pthread_once_t *, void (*)(void))
ATTRIBUTE_WEAK;
-extern "C" int pthread_kill(pthread_t thread_id, int signo)
- ATTRIBUTE_WEAK;
void ProfileHandler::Init() {
instance_ = new ProfileHandler();
@@ -255,7 +247,8 @@ ProfileHandler* ProfileHandler::Instance() {
ProfileHandler::ProfileHandler()
: interrupts_(0),
callback_count_(0),
- allowed_(true) {
+ allowed_(true),
+ timer_sharing_(TIMERS_UNTOUCHED) {
SpinLockHolder cl(&control_lock_);
timer_type_ = (getenv("CPUPROFILE_REALTIME") ? ITIMER_REAL : ITIMER_PROF);
@@ -279,17 +272,14 @@ ProfileHandler::ProfileHandler()
// assume it has priority over us and stop.
if (!IsSignalHandlerAvailable()) {
RAW_LOG(INFO, "Disabling profiler because %s handler is already in use.",
- signal_number());
+ timer_type_ == ITIMER_REAL ? "SIGALRM" : "SIGPROF");
allowed_ = false;
return;
}
- // Install the signal handler.
- struct sigaction sa;
- sa.sa_sigaction = SignalHandler;
- sa.sa_flags = SA_RESTART | SA_SIGINFO;
- sigemptyset(&sa.sa_mask);
- RAW_CHECK(sigaction(signal_number(), &sa, NULL) == 0, "sigprof (enable)");
+ // Ignore signals until we decide to turn profiling on. (Paranoia;
+ // should already be ignored.)
+ DisableHandler();
}
ProfileHandler::~ProfileHandler() {
@@ -303,17 +293,47 @@ void ProfileHandler::RegisterThread() {
return;
}
- // Record the thread identifier and start the timer if profiling is on.
- ScopedSignalBlocker block(signal_number());
- SpinLockHolder sl(&signal_lock_);
- registered_threads_[pthread_self()] = false;
- SetupTimer(callback_count_ > 0 ? frequency_ : 0);
-}
-
-void ProfileHandler::UnregisterThread() {
- ScopedSignalBlocker block(signal_number());
- SpinLockHolder sl(&signal_lock_);
- registered_threads_.erase(pthread_self());
+ // We try to detect whether timers are being shared by setting a
+ // timer in the first call to this function, then checking whether
+ // it's set in the second call.
+ //
+ // Note that this detection method requires that the first two calls
+ // to RegisterThread must be made from different threads. (Subsequent
+ // calls will see timer_sharing_ set to either TIMERS_SEPARATE or
+ // TIMERS_SHARED, and won't try to detect the timer sharing type.)
+ //
+ // Also note that if timer settings were inherited across new thread
+ // creation but *not* shared, this approach wouldn't work. That's
+ // not an issue for any Linux threading implementation, and should
+ // not be a problem for a POSIX-compliant threads implementation.
+ switch (timer_sharing_) {
+ case TIMERS_UNTOUCHED:
+ StartTimer();
+ timer_sharing_ = TIMERS_ONE_SET;
+ break;
+ case TIMERS_ONE_SET:
+ // If the timer is running, that means that the main thread's
+ // timer setup is seen in this (second) thread -- and therefore
+ // that timers are shared.
+ if (IsTimerRunning()) {
+ timer_sharing_ = TIMERS_SHARED;
+ // If callback is already registered, we have to keep the timer
+ // running. If not, we disable the timer here.
+ if (callback_count_ == 0) {
+ StopTimer();
+ }
+ } else {
+ timer_sharing_ = TIMERS_SEPARATE;
+ StartTimer();
+ }
+ break;
+ case TIMERS_SHARED:
+ // Nothing needed.
+ break;
+ case TIMERS_SEPARATE:
+ StartTimer();
+ break;
+ }
}
ProfileHandlerToken* ProfileHandler::RegisterCallback(
@@ -322,13 +342,17 @@ ProfileHandlerToken* ProfileHandler::RegisterCallback(
ProfileHandlerToken* token = new ProfileHandlerToken(callback, callback_arg);
SpinLockHolder cl(&control_lock_);
+ DisableHandler();
{
- ScopedSignalBlocker block(signal_number());
SpinLockHolder sl(&signal_lock_);
callbacks_.push_back(token);
- ++callback_count_;
- UpdateTimers(true);
}
+ // Start the timer if timer is shared and this is a first callback.
+ if ((callback_count_ == 0) && (timer_sharing_ == TIMERS_SHARED)) {
+ StartTimer();
+ }
+ ++callback_count_;
+ EnableHandler();
return token;
}
@@ -338,14 +362,17 @@ void ProfileHandler::UnregisterCallback(ProfileHandlerToken* token) {
++it) {
if ((*it) == token) {
RAW_CHECK(callback_count_ > 0, "Invalid callback count");
+ DisableHandler();
{
- ScopedSignalBlocker block(signal_number());
SpinLockHolder sl(&signal_lock_);
delete *it;
callbacks_.erase(it);
- --callback_count_;
- if (callback_count_ == 0)
- UpdateTimers(false);
+ }
+ --callback_count_;
+ if (callback_count_ > 0) {
+ EnableHandler();
+ } else if (timer_sharing_ == TIMERS_SHARED) {
+ StopTimer();
}
return;
}
@@ -356,8 +383,8 @@ void ProfileHandler::UnregisterCallback(ProfileHandlerToken* token) {
void ProfileHandler::Reset() {
SpinLockHolder cl(&control_lock_);
+ DisableHandler();
{
- ScopedSignalBlocker block(signal_number());
SpinLockHolder sl(&signal_lock_);
CallbackIterator it = callbacks_.begin();
while (it != callbacks_.end()) {
@@ -366,66 +393,87 @@ void ProfileHandler::Reset() {
delete *tmp;
callbacks_.erase(tmp);
}
- callback_count_ = 0;
- UpdateTimers(false);
}
+ callback_count_ = 0;
+ if (timer_sharing_ == TIMERS_SHARED) {
+ StopTimer();
+ }
+ timer_sharing_ = TIMERS_UNTOUCHED;
}
void ProfileHandler::GetState(ProfileHandlerState* state) {
SpinLockHolder cl(&control_lock_);
+ DisableHandler();
{
- ScopedSignalBlocker block(signal_number());
SpinLockHolder sl(&signal_lock_); // Protects interrupts_.
state->interrupts = interrupts_;
}
+ if (callback_count_ > 0) {
+ EnableHandler();
+ }
state->frequency = frequency_;
state->callback_count = callback_count_;
state->allowed = allowed_;
}
-void ProfileHandler::UpdateTimers(bool enabled) {
+void ProfileHandler::StartTimer() {
if (!allowed_) {
return;
}
- SetupTimer(enabled ? frequency_ : 0);
-
- // Tell other threads to start their timers.
- for (map<pthread_t, bool>::const_iterator thread(registered_threads_.begin());
- thread != registered_threads_.end();
- ++thread) {
- if (thread->first != pthread_self() && pthread_kill) {
- int err = pthread_kill(thread->first, signal_number());
- if (err == ESRCH) {
- // Thread exited.
- registered_threads_.erase(thread->first);
- } else {
- RAW_CHECK(err == 0, "pthread_kill");
- }
- }
- }
+ struct itimerval timer;
+ timer.it_interval.tv_sec = 0;
+ timer.it_interval.tv_usec = 1000000 / frequency_;
+ timer.it_value = timer.it_interval;
+ setitimer(timer_type_, &timer, 0);
}
-void ProfileHandler::SetupTimer(int32 frequency) {
- bool enable = (frequency > 0);
-#if defined(HAVE_TLS)
- bool& timer_running = timer_running_;
-#else
- bool& timer_running = registered_threads_[pthread_self()];
-#endif
- if (enable == timer_running)
+void ProfileHandler::StopTimer() {
+ if (!allowed_) {
return;
+ }
struct itimerval timer;
- timer.it_interval.tv_sec = 0;
- timer.it_interval.tv_usec = (enable ? (1000000 / frequency) : 0);
- timer.it_value = timer.it_interval;
+ memset(&timer, 0, sizeof timer);
setitimer(timer_type_, &timer, 0);
- timer_running = enable;
+}
+
+bool ProfileHandler::IsTimerRunning() {
+ if (!allowed_) {
+ return false;
+ }
+ struct itimerval current_timer;
+ RAW_CHECK(0 == getitimer(timer_type_, &current_timer), "getitimer");
+ return (current_timer.it_value.tv_sec != 0 ||
+ current_timer.it_value.tv_usec != 0);
+}
+
+void ProfileHandler::EnableHandler() {
+ if (!allowed_) {
+ return;
+ }
+ struct sigaction sa;
+ sa.sa_sigaction = SignalHandler;
+ sa.sa_flags = SA_RESTART | SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+ const int signal_number = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
+ RAW_CHECK(sigaction(signal_number, &sa, NULL) == 0, "sigprof (enable)");
+}
+
+void ProfileHandler::DisableHandler() {
+ if (!allowed_) {
+ return;
+ }
+ struct sigaction sa;
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ const int signal_number = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
+ RAW_CHECK(sigaction(signal_number, &sa, NULL) == 0, "sigprof (disable)");
}
bool ProfileHandler::IsSignalHandlerAvailable() {
struct sigaction sa;
- RAW_CHECK(sigaction(signal_number(), NULL, &sa) == 0,
- "is-signal-handler avail");
+ const int signal_number = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
+ RAW_CHECK(sigaction(signal_number, NULL, &sa) == 0, "is-signal-handler avail");
// We only take over the handler if the current one is unset.
// It must be SIG_IGN or SIG_DFL, not some other function.
@@ -447,9 +495,6 @@ void ProfileHandler::SignalHandler(int sig, siginfo_t* sinfo, void* ucontext) {
{
SpinLockHolder sl(&instance->signal_lock_);
++instance->interrupts_;
- // Enable/Disable the timer if necessary.
- instance->SetupTimer(
- instance->callbacks_.empty() ? 0 : instance->frequency_);
for (CallbackIterator it = instance->callbacks_.begin();
it != instance->callbacks_.end();
++it) {
@@ -467,10 +512,6 @@ extern "C" void ProfileHandlerRegisterThread() {
ProfileHandler::Instance()->RegisterThread();
}
-extern "C" void ProfileHandlerUnregisterThread() {
- ProfileHandler::Instance()->UnregisterThread();
-}
-
extern "C" ProfileHandlerToken* ProfileHandlerRegisterCallback(
ProfileHandlerCallback callback, void* callback_arg) {
return ProfileHandler::Instance()->RegisterCallback(callback, callback_arg);
@@ -497,9 +538,6 @@ extern "C" void ProfileHandlerGetState(ProfileHandlerState* state) {
extern "C" void ProfileHandlerRegisterThread() {
}
-extern "C" void ProfileHandlerUnregisterThread() {
-}
-
extern "C" ProfileHandlerToken* ProfileHandlerRegisterCallback(
ProfileHandlerCallback callback, void* callback_arg) {
return NULL;
diff --git a/third_party/tcmalloc/chromium/src/profile-handler.h b/third_party/tcmalloc/chromium/src/profile-handler.h
index cc50dbb..4b078ec 100644
--- a/third_party/tcmalloc/chromium/src/profile-handler.h
+++ b/third_party/tcmalloc/chromium/src/profile-handler.h
@@ -102,18 +102,6 @@ typedef void (*ProfileHandlerCallback)(int sig, siginfo_t* sig_info,
void ProfileHandlerRegisterThread();
/*
- * Unregisters a thread before exiting. This is not strictly necessary in most
- * cases, because the pthread library will detect that previously-valid thread
- * identifiers have become invalid. For dead-thread detection to work, pthread
- * identifiers are accessed even after the thread has been destroyed, which may
- * fail in some edge cases (thread ID recycling) and even crash in exotic cases
- * (for example, when using user-allocated stacks with NPTL and unmapping the
- * memory after the thread terminates). Thus, it is generally good practice to
- * call ProfileHandlerUnregisterThread() just before exiting the thread.
- */
-void ProfileHandlerUnregisterThread();
-
-/*
* Registers a callback routine. This callback function will be called in the
* context of SIGPROF handler, so must be async-signal-safe. The returned token
* is to be used when unregistering this callback via
diff --git a/third_party/tcmalloc/chromium/src/profiler.cc b/third_party/tcmalloc/chromium/src/profiler.cc
index 65879f6..dfb6aab 100644
--- a/third_party/tcmalloc/chromium/src/profiler.cc
+++ b/third_party/tcmalloc/chromium/src/profiler.cc
@@ -290,10 +290,6 @@ extern "C" PERFTOOLS_DLL_DECL void ProfilerRegisterThread() {
ProfileHandlerRegisterThread();
}
-extern "C" PERFTOOLS_DLL_DECL void ProfilerUnregisterThread() {
- ProfileHandlerUnregisterThread();
-}
-
extern "C" PERFTOOLS_DLL_DECL void ProfilerFlush() {
CpuProfiler::instance_.FlushTable();
}
@@ -327,7 +323,6 @@ extern "C" PERFTOOLS_DLL_DECL void ProfilerGetCurrentState(
// these issues, unless a specific need is identified, profiler support is
// disabled under Cygwin.
extern "C" void ProfilerRegisterThread() { }
-extern "C" void ProfilerUnregisterThread() { }
extern "C" void ProfilerFlush() { }
extern "C" int ProfilingIsEnabledForAllThreads() { return 0; }
extern "C" int ProfilerStart(const char* fname) { return 0; }
diff --git a/third_party/tcmalloc/chromium/src/tests/profile-handler_unittest.cc b/third_party/tcmalloc/chromium/src/tests/profile-handler_unittest.cc
index e46ab83..98cfe6d 100644
--- a/third_party/tcmalloc/chromium/src/tests/profile-handler_unittest.cc
+++ b/third_party/tcmalloc/chromium/src/tests/profile-handler_unittest.cc
@@ -58,7 +58,6 @@ class Thread {
static void* DoRun(void* cls) {
ProfileHandlerRegisterThread();
reinterpret_cast<Thread*>(cls)->Run();
- ProfileHandlerUnregisterThread();
return NULL;
}
pthread_t thread_;
diff --git a/third_party/tcmalloc/chromium/src/tests/profiler_unittest.cc b/third_party/tcmalloc/chromium/src/tests/profiler_unittest.cc
index 2afe209..399891b 100644
--- a/third_party/tcmalloc/chromium/src/tests/profiler_unittest.cc
+++ b/third_party/tcmalloc/chromium/src/tests/profiler_unittest.cc
@@ -63,8 +63,6 @@ static void test_other_thread() {
}
snprintf(b, sizeof(b), "other: %d", result); // get some libc action
}
-
- ProfilerUnregisterThread();
#endif
}