gecko-dev/tools/profiler/core/platform-linux-android.cpp

543 строки
17 KiB
C++
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google, Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
// This file is used for both Linux and Android.
#include <stdio.h>
#include <math.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sched.h>
#include <ucontext.h>
// Ubuntu Dapper requires memory pages to be marked as
// executable. Otherwise, OS raises an exception when executing code
// in that page.
#include <sys/types.h> // mmap & munmap
#include <sys/mman.h> // mmap & munmap
#include <sys/stat.h> // open
#include <fcntl.h> // open
#include <unistd.h> // sysconf
#include <semaphore.h>
#ifdef __GLIBC__
#include <execinfo.h> // backtrace, backtrace_symbols
#endif // def __GLIBC__
#include <strings.h> // index
#include <errno.h>
#include <stdarg.h>
#include "prenv.h"
#include "mozilla/LinuxSignal.h"
Bug 1342102 - Use the same threading structure in platform-linux-android.cpp as for the -macos and -win32 versions. r=n.nethercote. The MacOS and Windows profiler cores have a threading structure where one thread ("sampler thread") collects information from a thread to be profiled ("samplee thread") by suspending it, getting its register state, unwinding its stack, and then resuming it. This requires kernel-level primitives to perform the suspend, get-registers and resume steps. The Linux/Android core is different, because none of those three primitives exist. Until now, data collection has been done by sending a SIGPROF to the samplee, and collecting all relevant data within the signal handler. This has a number of disadvantages: (1) Current work to rationalise/clean up the threading structure of the profiler is complicated by the need to reason about/verify two different schemes. In particular, the Tick call in the Windows and MacOS implementations will produce its output on the sampler thread. In the Linux implementation that is produced on the sampled threads. (2) Dynamic verification results (primarily, absence of data races and deadlocks) established for the Linux implementation are less likely to carry over to the other two implementations, because the threading structures are different. (3) It causes a lot of duplicated code in platform-*.cpp. For example SamplerThread::Run() in the -win32.cpp and -macos.cpp files are very similar. Ideally all three could be merged into a single file with the identical logic commoned up. (4) Running lots of code -- the entire contents of Tick -- in a signal handler isn't considered good practice. POSIX severely restricts the set of functions we can safely call from within a signal handler. This commit changes the Linux implementation by using semaphores to implement the suspend and resume primitives, and moves the bulk of the data collection work to the sampler thread. By doing this, it causes the Linux implementation to have the same threading structure as the other two. --HG-- extra : rebase_source : 675b6ef76915d164ed263b831dddd6ce0c0e97f3
2017-03-01 16:57:34 +03:00
#include "mozilla/PodOperations.h"
#include "mozilla/DebugOnly.h"
#include <string.h>
#include <list>
using namespace mozilla;
/* static */ Thread::tid_t
Thread::GetCurrentId()
{
return gettid();
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
static void
PopulateRegsFromContext(Registers& aRegs, ucontext_t* aContext)
{
aRegs.mContext = aContext;
mcontext_t& mcontext = aContext->uc_mcontext;
// Extracting the sample from the context is extremely machine dependent.
#if defined(GP_ARCH_x86)
aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
aRegs.mLR = 0;
#elif defined(GP_ARCH_amd64)
aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
aRegs.mLR = 0;
#elif defined(GP_ARCH_arm)
aRegs.mPC = reinterpret_cast<Address>(mcontext.arm_pc);
aRegs.mSP = reinterpret_cast<Address>(mcontext.arm_sp);
aRegs.mFP = reinterpret_cast<Address>(mcontext.arm_fp);
aRegs.mLR = reinterpret_cast<Address>(mcontext.arm_lr);
#elif defined(GP_ARCH_aarch64)
aRegs.mPC = reinterpret_cast<Address>(mcontext.pc);
aRegs.mSP = reinterpret_cast<Address>(mcontext.sp);
aRegs.mFP = reinterpret_cast<Address>(mcontext.regs[29]);
aRegs.mLR = reinterpret_cast<Address>(mcontext.regs[30]);
#else
# error "bad platform"
#endif
}
#if defined(GP_OS_android)
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
# define SYS_tgkill __NR_tgkill
#endif
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
int
tgkill(pid_t tgid, pid_t tid, int signalno)
{
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
return syscall(SYS_tgkill, tgid, tid, signalno);
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
class PlatformData
{
public:
explicit PlatformData(int aThreadId)
{
MOZ_COUNT_CTOR(PlatformData);
}
~PlatformData()
{
MOZ_COUNT_DTOR(PlatformData);
}
};
////////////////////////////////////////////////////////////////////////
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
// BEGIN Sampler target specifics
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
// The only way to reliably interrupt a Linux thread and inspect its register
// and stack state is by sending a signal to it, and doing the work inside the
// signal handler. But we don't want to run much code inside the signal
// handler, since POSIX severely restricts what we can do in signal handlers.
// So we use a system of semaphores to suspend the thread and allow the
// sampler thread to do all the work of unwinding and copying out whatever
// data it wants.
//
// A four-message protocol is used to reliably suspend and later resume the
// thread to be sampled (the samplee):
//
// Sampler (signal sender) thread Samplee (thread to be sampled)
//
// Prepare the SigHandlerCoordinator
// and point sSigHandlerCoordinator at it
//
// send SIGPROF to samplee ------- MSG 1 ----> (enter signal handler)
// wait(mMessage2) Copy register state
// into sSigHandlerCoordinator
// <------ MSG 2 ----- post(mMessage2)
// Samplee is now suspended. wait(mMessage3)
// Examine its stack/register
// state at leisure
//
// Release samplee:
// post(mMessage3) ------- MSG 3 ----->
// wait(mMessage4) Samplee now resumes. Tell
// the sampler that we are done.
// <------ MSG 4 ------ post(mMessage4)
// Now we know the samplee's signal (leave signal handler)
// handler has finished using
// sSigHandlerCoordinator. We can
// safely reuse it for some other thread.
//
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// A type used to coordinate between the sampler (signal sending) thread and
// the thread currently being sampled (the samplee, which receives the
// signals).
//
// The first message is sent using a SIGPROF signal delivery. The subsequent
// three are sent using sem_wait/sem_post pairs. They are named accordingly
// in the following struct.
struct SigHandlerCoordinator
{
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
SigHandlerCoordinator()
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
{
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
PodZero(&mUContext);
int r = sem_init(&mMessage2, /* pshared */ 0, 0);
r |= sem_init(&mMessage3, /* pshared */ 0, 0);
r |= sem_init(&mMessage4, /* pshared */ 0, 0);
MOZ_ASSERT(r == 0);
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
~SigHandlerCoordinator()
{
int r = sem_destroy(&mMessage2);
r |= sem_destroy(&mMessage3);
r |= sem_destroy(&mMessage4);
MOZ_ASSERT(r == 0);
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
sem_t mMessage2; // To sampler: "context is in sSigHandlerCoordinator"
sem_t mMessage3; // To samplee: "resume"
sem_t mMessage4; // To sampler: "finished with sSigHandlerCoordinator"
ucontext_t mUContext; // Context at signal
};
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
struct SigHandlerCoordinator* Sampler::sSigHandlerCoordinator = nullptr;
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
static void
SigprofHandler(int aSignal, siginfo_t* aInfo, void* aContext)
{
// Avoid TSan warning about clobbering errno.
int savedErrno = errno;
MOZ_ASSERT(aSignal == SIGPROF);
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
MOZ_ASSERT(Sampler::sSigHandlerCoordinator);
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// By sending us this signal, the sampler thread has sent us message 1 in
// the comment above, with the meaning "|sSigHandlerCoordinator| is ready
// for use, please copy your register context into it."
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
Sampler::sSigHandlerCoordinator->mUContext =
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
*static_cast<ucontext_t*>(aContext);
// Send message 2: tell the sampler thread that the context has been copied
// into |sSigHandlerCoordinator->mUContext|. sem_post can never fail by
// being interrupted by a signal, so there's no loop around this call.
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
int r = sem_post(&Sampler::sSigHandlerCoordinator->mMessage2);
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
MOZ_ASSERT(r == 0);
// At this point, the sampler thread assumes we are suspended, so we must
// not touch any global state here.
// Wait for message 3: the sampler thread tells us to resume.
while (true) {
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
r = sem_wait(&Sampler::sSigHandlerCoordinator->mMessage3);
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
if (r == -1 && errno == EINTR) {
// Interrupted by a signal. Try again.
continue;
}
// We don't expect any other kind of failure
MOZ_ASSERT(r == 0);
break;
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// Send message 4: tell the sampler thread that we are finished accessing
// |sSigHandlerCoordinator|. After this point it is not safe to touch
// |sSigHandlerCoordinator|.
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
r = sem_post(&Sampler::sSigHandlerCoordinator->mMessage4);
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
MOZ_ASSERT(r == 0);
errno = savedErrno;
}
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
Sampler::Sampler(PSLockRef aLock)
: mMyPid(getpid())
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// We don't know what the sampler thread's ID will be until it runs, so set
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
// mSamplerTid to a dummy value and fill it in for real in
// SuspendAndSampleAndResumeThread().
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
, mSamplerTid(-1)
{
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
#if defined(USE_EHABI_STACKWALK)
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
mozilla::EHABIStackWalkInit();
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
#elif defined(USE_LUL_STACKWALK)
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
bool createdLUL = false;
lul::LUL* lul = CorePS::Lul(aLock);
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
if (!lul) {
CorePS::SetLul(aLock, MakeUnique<lul::LUL>(logging_sink_for_LUL));
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// Read all the unwind info currently available.
lul = CorePS::Lul(aLock);
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
read_procmaps(lul);
createdLUL = true;
}
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
#endif
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// Request profiling signals.
struct sigaction sa;
sa.sa_sigaction = MOZ_SIGNAL_TRAMPOLINE(SigprofHandler);
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_SIGINFO;
if (sigaction(SIGPROF, &sa, &mOldSigprofHandler) != 0) {
MOZ_CRASH("Error installing SIGPROF handler in the profiler");
}
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
#if defined(USE_LUL_STACKWALK)
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
if (createdLUL) {
// Switch into unwind mode. After this point, we can't add or remove any
// unwind info to/from this LUL instance. The only thing we can do with
// it is Unwind() calls.
lul->EnableUnwinding();
// Has a test been requested?
if (PR_GetEnv("MOZ_PROFILER_LUL_TEST")) {
int nTests = 0, nTestsPassed = 0;
RunLulUnitTests(&nTests, &nTestsPassed, lul);
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
}
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
#endif
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
void
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
Sampler::Disable(PSLockRef aLock)
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
{
// Restore old signal handler. This is global state so it's important that
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
// we do it now, while gPSMutex is locked.
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
sigaction(SIGPROF, &mOldSigprofHandler, 0);
}
template<typename Func>
void
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
Sampler::SuspendAndSampleAndResumeThread(PSLockRef aLock,
const ThreadInfo& aThreadInfo,
const Func& aProcessRegs)
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
{
// Only one sampler thread can be sampling at once. So we expect to have
// complete control over |sSigHandlerCoordinator|.
MOZ_ASSERT(!sSigHandlerCoordinator);
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
if (mSamplerTid == -1) {
mSamplerTid = gettid();
}
int sampleeTid = aThreadInfo.ThreadId();
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
MOZ_RELEASE_ASSERT(sampleeTid != mSamplerTid);
//----------------------------------------------------------------//
// Suspend the samplee thread and get its context.
SigHandlerCoordinator coord; // on sampler thread's stack
sSigHandlerCoordinator = &coord;
// Send message 1 to the samplee (the thread to be sampled), by
// signalling at it.
int r = tgkill(mMyPid, sampleeTid, SIGPROF);
MOZ_ASSERT(r == 0);
// Wait for message 2 from the samplee, indicating that the context
// is available and that the thread is suspended.
while (true) {
r = sem_wait(&sSigHandlerCoordinator->mMessage2);
if (r == -1 && errno == EINTR) {
// Interrupted by a signal. Try again.
continue;
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// We don't expect any other kind of failure.
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
MOZ_ASSERT(r == 0);
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
break;
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
//----------------------------------------------------------------//
// Sample the target thread.
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
//
// The profiler's "critical section" begins here. In the critical section,
// we must not do any dynamic memory allocation, nor try to acquire any lock
// or any other unshareable resource. This is because the thread to be
// sampled has been suspended at some entirely arbitrary point, and we have
// no idea which unsharable resources (locks, essentially) it holds. So any
// attempt to acquire any lock, including the implied locks used by the
// malloc implementation, risks deadlock. This includes TimeStamp::Now(),
// which gets a lock on Windows.
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// The samplee thread is now frozen and sSigHandlerCoordinator->mUContext is
// valid. We can poke around in it and unwind its stack as we like.
// Extract the current register values.
Registers regs;
PopulateRegsFromContext(regs, &sSigHandlerCoordinator->mUContext);
aProcessRegs(regs);
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
//----------------------------------------------------------------//
// Resume the target thread.
// Send message 3 to the samplee, which tells it to resume.
r = sem_post(&sSigHandlerCoordinator->mMessage3);
MOZ_ASSERT(r == 0);
// Wait for message 4 from the samplee, which tells us that it has
// finished with |sSigHandlerCoordinator|.
while (true) {
r = sem_wait(&sSigHandlerCoordinator->mMessage4);
if (r == -1 && errno == EINTR) {
continue;
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
MOZ_ASSERT(r == 0);
break;
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// The profiler's critical section ends here. After this point, none of the
// critical section limitations documented above apply.
//
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// This isn't strictly necessary, but doing so does help pick up anomalies
// in which the signal handler is running when it shouldn't be.
sSigHandlerCoordinator = nullptr;
}
Bug 1342306 (part 1) - Introduce SamplerThread class in platform-linux-android.cpp. r=jseward. This makes it more like platform-{macos,win32}.cpp, and will make it easier to introduce locking around all the globals in platform.cpp. The following things were moved into the new class. - Types: - SigHandlerCoordinator - Functions: - SigProfHandler() - SigprofSender() as Run() - Variables: - gOldSigprofHandler as mOldSigprofHandler - gSigprofSenderThread as mThread - gIntervalMicro as mIntervalMicro - gSigHandlerCoordinator as sSigHandlerCoordinator sInstance is the singleton instance. PlatformStart() and PlatformStop() now just delegate to StartSampler/StopSampler. The patch also does the following tidy-ups. Linux: - gWasPaused is now cleared in the parent and child processes after forking. - LUL: inlined and removed gLUL_initialization_routine(). - LUL: now only calling EnabledUnwinding() and doing the unit tests on the first call to profiler_start(), instead of all of them. Mac: - Removed a useless call to pthread_self() -- mThread is already set by the earlier call to pthread_create(). - Removed some low-value checking involving kNoThread. Mac + Win: - Renamed SamplerThread::mInstance as sInstance, because it's static. - Merged SamplerThread::Start() with the constructor. - Tweaked how mInterval/mIntervalMicro is initialized, so it can become const. All platforms: - Converted NULL to nullptr throughout. - A few other very minor clean-ups, e.g. formatting. --HG-- extra : rebase_source : 4d10be873c4a7544f450e6a3b3d86c5d5b2fb603
2017-03-03 07:52:35 +03:00
Bug 1357829 - Part 1: Expose profiler_suspend_and_sample_thread, r=njn This patch performs a refactoring to the internals of the profiler in order to expose a function, profiler_suspend_and_sample_thread, which can be called from a background thread to suspend, sample the native stack, and then resume the target passed-in thread. The interface was designed to expose as few internals of the profiler as possible, exposing only a single callback which accepts the list of program counters and stack pointers collected during the backtrace. A method `profiler_current_thread_id` was also added to get the thread_id of the current thread, which can then be passed by another thread into profiler_suspend_sample_thread to sample the stack of that thread. This is implemented in two parts: 1) Splitting SamplerThread into two classes: Sampler, and SamplerThread. Sampler was created to extract the core logic from SamplerThread which manages unix signals on android and linux, as well as suspends the target thread on all platforms. SamplerThread was then modified to subclass this type, adding the extra methods and fields required for the creation and management of the actual Sampler Thread. Some work was done to ensure that the methods on Sampler would not require ActivePS to be present, as we intend to sample threads when the profiler is not active for the Background Hang Reporter. 2) Moving the Tick() logic into the TickController interface. A TickController interface was added to platform which has 2 methods: Tick and Backtrace. The Tick method replaces the previous Tick() static method, allowing it to be overridden by a different consumer of SuspendAndSampleAndResumeThread, while the Backtrace() method replaces the previous MergeStacksIntoProfile method, allowing it to be overridden by different consumers of DoNativeBacktrace. This interface object is then used to wrap implementation specific data, such as the ProfilerBuffer, and is threaded through the SuspendAndSampleAndResumeThread and DoNativeBacktrace methods. This change added 2 virtual calls to the SamplerThread's critical section, which I believe should be a small enough overhead that it will not affect profiling performance. These virtual calls could be avoided using templating, but I decided that doing so would be unnecessary. MozReview-Commit-ID: AT48xb2asgV
2017-05-02 22:36:35 +03:00
// END Sampler target specifics
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// BEGIN SamplerThread target specifics
static void*
ThreadEntry(void* aArg)
{
auto thread = static_cast<SamplerThread*>(aArg);
thread->Run();
return nullptr;
}
SamplerThread::SamplerThread(PSLockRef aLock, uint32_t aActivityGeneration,
double aIntervalMilliseconds)
: Sampler(aLock)
, mActivityGeneration(aActivityGeneration)
, mIntervalMicroseconds(
std::max(1, int(floor(aIntervalMilliseconds * 1000 + 0.5))))
{
// Start the sampling thread. It repeatedly sends a SIGPROF signal. Sending
// the signal ourselves instead of relying on itimer provides much better
// accuracy.
if (pthread_create(&mThread, nullptr, ThreadEntry, this) != 0) {
MOZ_CRASH("pthread_create failed");
}
}
SamplerThread::~SamplerThread()
{
pthread_join(mThread, nullptr);
}
void
SamplerThread::SleepMicro(uint32_t aMicroseconds)
{
if (aMicroseconds >= 1000000) {
// Use usleep for larger intervals, because the nanosleep
// code below only supports intervals < 1 second.
MOZ_ALWAYS_TRUE(!::usleep(aMicroseconds));
return;
}
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = aMicroseconds * 1000UL;
int rv = ::nanosleep(&ts, &ts);
while (rv != 0 && errno == EINTR) {
// Keep waiting in case of interrupt.
// nanosleep puts the remaining time back into ts.
rv = ::nanosleep(&ts, &ts);
}
MOZ_ASSERT(!rv, "nanosleep call failed");
}
void
SamplerThread::Stop(PSLockRef aLock)
{
// Restore old signal handler. This is global state so it's important that
// we do it now, while gPSMutex is locked. It's safe to do this now even
// though this SamplerThread is still alive, because the next time the main
// loop of Run() iterates it won't get past the mActivityGeneration check,
// and so won't send any signals.
Sampler::Disable(aLock);
}
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
// END SamplerThread target specifics
////////////////////////////////////////////////////////////////////////
#if defined(GP_OS_linux)
// We use pthread_atfork() to temporarily disable signal delivery during any
// fork() call. Without that, fork() can be repeatedly interrupted by signal
// delivery, requiring it to be repeatedly restarted, which can lead to *long*
// delays. See bug 837390.
//
// We provide no paf_child() function to run in the child after forking. This
// is fine because we always immediately exec() after fork(), and exec()
// clobbers all process state. (At one point we did have a paf_child()
// function, but it caused problems related to locking gPSMutex. See bug
// 1348374.)
//
// Unfortunately all this is only doable on non-Android because Bionic doesn't
// have pthread_atfork.
// In the parent, before the fork, record IsPaused, and then pause.
static void
paf_prepare()
{
MOZ_RELEASE_ASSERT(CorePS::Exists());
PSAutoLock lock(gPSMutex);
if (ActivePS::Exists(lock)) {
ActivePS::SetWasPaused(lock, ActivePS::IsPaused(lock));
ActivePS::SetIsPaused(lock, true);
}
}
// In the parent, after the fork, return IsPaused to the pre-fork state.
static void
paf_parent()
{
MOZ_RELEASE_ASSERT(CorePS::Exists());
PSAutoLock lock(gPSMutex);
if (ActivePS::Exists(lock)) {
ActivePS::SetIsPaused(lock, ActivePS::WasPaused(lock));
ActivePS::SetWasPaused(lock, false);
}
}
static void
PlatformInit(PSLockRef aLock)
{
// Set up the fork handlers.
pthread_atfork(paf_prepare, paf_parent, nullptr);
}
#else
static void
PlatformInit(PSLockRef aLock)
{
}
2012-07-11 19:28:04 +04:00
#endif
#if defined(HAVE_NATIVE_UNWIND)
// Context used by synchronous samples. It's safe to have a single one because
// only one synchronous sample can be taken at a time (due to
// profiler_get_backtrace()'s PSAutoLock).
ucontext_t sSyncUContext;
Bug 1344169 - Factor out the common parts of SamplerThread::Run(). r=n.nethercote. All three platform-*.cpp files have similar structure, most especially for SamplerThread::Run(), with considerable duplication. This patch factors out the common parts into a single implementation in platform.cpp. * The top level structure of class SamplerThread has been moved to platform.cpp. * The class has some target-dependent fields, relating to signal handling and thread identity. * There's a single implementation of Run() in platform.cpp. * AllocPlatformData() and PlatformDataDestructor::operator() have also been commoned up and moved into platform.cpp. * Time units in SamplerThread have been tidied up. We now use microseconds throughout, except in the constructor. All time interval field and variable names incorporate the unit (microseconds/milliseconds) for clarity. The Windows uses of such values are scaled up/down by 1000 accordingly. * The pre-existing MacOS Run() implementation contained logic that attempted to keep "to schedule" in the presence of inaccuracy in the actual sleep intervals. This now applies to all targets. A couple of comments on this code have been added. * platform-{win32,macos,linux-android}.cpp have had their Run() methods removed, and all other methods placed in the same sequences, to the extent that is possible. * In the Win32 and MacOS implementations, Thread::SampleContext has been renamed to Thread::SuspendSampleAndResumeThread as that better describes what it does. In the Linux/Android implementation there was no such separate method, so one has been created. * The three Thread::SuspendSampleAndResumeThread methods have been commented in such a way as to emphasise their identical top level structure. * The point in platform.cpp where platform-{win32,macos,linux-android}.cpp are #included has been moved slightly earlier in the file, into the SamplerThread encampment, as that seems like a better place for it. --HG-- extra : rebase_source : 0f93e15967b810c09e645fa593dbf85f94b53a9b
2017-03-10 18:10:14 +03:00
void
Registers::SyncPopulate()
{
if (!getcontext(&sSyncUContext)) {
PopulateRegsFromContext(*this, &sSyncUContext);
}
}
#endif