зеркало из 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
|
#endif
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
using mozilla::profiler::detail::RacyFeatures;
|
||||||
|
|
||||||
LazyLogModule gProfilerLog("prof");
|
LazyLogModule gProfilerLog("prof");
|
||||||
|
|
||||||
|
@ -600,50 +601,6 @@ uint32_t ActivePS::sNextGeneration = 0;
|
||||||
// The mutex that guards accesses to CorePS and ActivePS.
|
// The mutex that guards accesses to CorePS and ActivePS.
|
||||||
static PSMutex gPSMutex;
|
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);
|
Atomic<uint32_t> RacyFeatures::sActiveAndFeatures(0);
|
||||||
|
|
||||||
// Each live thread has a ThreadInfo, and we store a reference to it in TLS.
|
// 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);
|
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
|
void
|
||||||
profiler_register_thread(const char* aName, void* aGuessStackTop)
|
profiler_register_thread(const char* aName, void* aGuessStackTop)
|
||||||
{
|
{
|
||||||
|
|
|
@ -142,6 +142,64 @@ struct ProfilerFeature
|
||||||
#undef DECLARE
|
#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
|
// 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
|
// expensive data will end up being created but not used if another thread
|
||||||
// stops the profiler between the CreateExpensiveData() and PROFILER_OPERATION
|
// stops the profiler between the CreateExpensiveData() and PROFILER_OPERATION
|
||||||
// calls.
|
// 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.
|
// Is the profiler active and paused? Returns false if the profiler is inactive.
|
||||||
bool profiler_is_paused();
|
bool profiler_is_paused();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче