зеркало из https://github.com/mozilla/gecko-dev.git
Bug 785440 - Move profiler_is_active() implementation (and RacyFeatures) into GeckoProfiler.h. r=njn
MozReview-Commit-ID: D8y5RK2t6N4 --HG-- extra : rebase_source : 50513145561a1123c47741cb845e9b4adcf104a0 extra : intermediate-source : 85c8d7e4a5eb1616d36d4ec7916e3b077da3b236 extra : source : 5dda2adf525363b32844ea8162235fae3b54d17d
This commit is contained in:
Родитель
b613ceee3f
Коммит
7a2c359a92
|
@ -151,6 +151,7 @@
|
|||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using mozilla::profiler::detail::RacyFeatures;
|
||||
|
||||
LazyLogModule gProfilerLog("prof");
|
||||
|
||||
|
@ -600,50 +601,6 @@ uint32_t ActivePS::sNextGeneration = 0;
|
|||
// The mutex that guards accesses to CorePS and ActivePS.
|
||||
static PSMutex gPSMutex;
|
||||
|
||||
// The preferred way to check profiler activeness and features is via
|
||||
// ActivePS(). However, that requires locking gPSMutex. There are some hot
|
||||
// operations where absolute precision isn't required, so we duplicate the
|
||||
// activeness/feature state in a lock-free manner in this class.
|
||||
class RacyFeatures
|
||||
{
|
||||
public:
|
||||
static void SetActive(uint32_t aFeatures)
|
||||
{
|
||||
sActiveAndFeatures = Active | aFeatures;
|
||||
}
|
||||
|
||||
static void SetInactive() { sActiveAndFeatures = 0; }
|
||||
|
||||
static bool IsActive() { return uint32_t(sActiveAndFeatures) & Active; }
|
||||
|
||||
static bool IsActiveWithFeature(uint32_t aFeature)
|
||||
{
|
||||
uint32_t af = sActiveAndFeatures; // copy it first
|
||||
return (af & Active) && (af & aFeature);
|
||||
}
|
||||
|
||||
static bool IsActiveWithoutPrivacy()
|
||||
{
|
||||
uint32_t af = sActiveAndFeatures; // copy it first
|
||||
return (af & Active) && !(af & ProfilerFeature::Privacy);
|
||||
}
|
||||
|
||||
private:
|
||||
static const uint32_t Active = 1u << 31;
|
||||
|
||||
// Ensure Active doesn't overlap with any of the feature bits.
|
||||
#define NO_OVERLAP(n_, str_, Name_) \
|
||||
static_assert(ProfilerFeature::Name_ != Active, "bad Active value");
|
||||
|
||||
PROFILER_FOR_EACH_FEATURE(NO_OVERLAP);
|
||||
|
||||
#undef NO_OVERLAP
|
||||
|
||||
// We combine the active bit with the feature bits so they can be read or
|
||||
// written in a single atomic operation.
|
||||
static Atomic<uint32_t> sActiveAndFeatures;
|
||||
};
|
||||
|
||||
Atomic<uint32_t> RacyFeatures::sActiveAndFeatures(0);
|
||||
|
||||
// Each live thread has a ThreadInfo, and we store a reference to it in TLS.
|
||||
|
@ -3071,17 +3028,6 @@ profiler_feature_active(uint32_t aFeature)
|
|||
return RacyFeatures::IsActiveWithFeature(aFeature);
|
||||
}
|
||||
|
||||
bool
|
||||
profiler_is_active()
|
||||
{
|
||||
// This function runs both on and off the main thread.
|
||||
|
||||
MOZ_RELEASE_ASSERT(CorePS::Exists());
|
||||
|
||||
// This function is hot enough that we use RacyFeatures, notActivePS.
|
||||
return RacyFeatures::IsActive();
|
||||
}
|
||||
|
||||
void
|
||||
profiler_register_thread(const char* aName, void* aGuessStackTop)
|
||||
{
|
||||
|
|
|
@ -142,6 +142,64 @@ struct ProfilerFeature
|
|||
#undef DECLARE
|
||||
};
|
||||
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
namespace mozilla {
|
||||
namespace profiler {
|
||||
namespace detail {
|
||||
|
||||
// RacyFeatures is only defined in this header file so that its methods can
|
||||
// be inlined into profiler_is_active(). Please do not use anything from the
|
||||
// detail namespace outside the profiler.
|
||||
|
||||
// Within the profiler's code, the preferred way to check profiler activeness
|
||||
// and features is via ActivePS(). However, that requires locking gPSMutex.
|
||||
// There are some hot operations where absolute precision isn't required, so we
|
||||
// duplicate the activeness/feature state in a lock-free manner in this class.
|
||||
class RacyFeatures
|
||||
{
|
||||
public:
|
||||
static void SetActive(uint32_t aFeatures)
|
||||
{
|
||||
sActiveAndFeatures = Active | aFeatures;
|
||||
}
|
||||
|
||||
static void SetInactive() { sActiveAndFeatures = 0; }
|
||||
|
||||
static bool IsActive() { return uint32_t(sActiveAndFeatures) & Active; }
|
||||
|
||||
static bool IsActiveWithFeature(uint32_t aFeature)
|
||||
{
|
||||
uint32_t af = sActiveAndFeatures; // copy it first
|
||||
return (af & Active) && (af & aFeature);
|
||||
}
|
||||
|
||||
static bool IsActiveWithoutPrivacy()
|
||||
{
|
||||
uint32_t af = sActiveAndFeatures; // copy it first
|
||||
return (af & Active) && !(af & ProfilerFeature::Privacy);
|
||||
}
|
||||
|
||||
private:
|
||||
static const uint32_t Active = 1u << 31;
|
||||
|
||||
// Ensure Active doesn't overlap with any of the feature bits.
|
||||
#define NO_OVERLAP(n_, str_, Name_) \
|
||||
static_assert(ProfilerFeature::Name_ != Active, "bad Active value");
|
||||
|
||||
PROFILER_FOR_EACH_FEATURE(NO_OVERLAP);
|
||||
|
||||
#undef NO_OVERLAP
|
||||
|
||||
// We combine the active bit with the feature bits so they can be read or
|
||||
// written in a single atomic operation.
|
||||
static mozilla::Atomic<uint32_t> sActiveAndFeatures;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace profiler
|
||||
} // namespace mozilla
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Start and stop the profiler
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -263,7 +321,14 @@ void profiler_clear_js_context();
|
|||
// expensive data will end up being created but not used if another thread
|
||||
// stops the profiler between the CreateExpensiveData() and PROFILER_OPERATION
|
||||
// calls.
|
||||
bool profiler_is_active();
|
||||
inline bool profiler_is_active()
|
||||
{
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
return mozilla::profiler::detail::RacyFeatures::IsActive();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Is the profiler active and paused? Returns false if the profiler is inactive.
|
||||
bool profiler_is_paused();
|
||||
|
|
Загрузка…
Ссылка в новой задаче