зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1721939 - ProfilerThreadRegistrationInfo - r=canaltinova
`ProfilerThreadRegistrationInfo` will replace `ThreadInfo`, and contains thread-specific information that may be kept after that thread has ended, to identify recorded profiling data about that thread. It is public and not ref-counted because it will be included as value into the thread registration data (to avoid a separate allocation). Differential Revision: https://phabricator.services.mozilla.com/D120813
This commit is contained in:
Родитель
9b4a2add9f
Коммит
779c0c93b1
|
@ -154,6 +154,7 @@ EXPORTS.mozilla += [
|
|||
"public/ProfilerMarkersPrerequisites.h",
|
||||
"public/ProfilerMarkerTypes.h",
|
||||
"public/ProfilerState.h",
|
||||
"public/ProfilerThreadRegistrationInfo.h",
|
||||
"public/ProfilerUtils.h",
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef ProfilerThreadRegistrationInfo_h
|
||||
#define ProfilerThreadRegistrationInfo_h
|
||||
|
||||
#include "mozilla/ProfilerUtils.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mozilla::profiler {
|
||||
|
||||
// This class contains immutable information about a thread which needs to be
|
||||
// stored across restarts of the profiler and which can be useful even after the
|
||||
// thread has stopped running.
|
||||
class ThreadRegistrationInfo {
|
||||
public:
|
||||
// Construct on the thread.
|
||||
explicit ThreadRegistrationInfo(const char* aName) : mName(aName) {}
|
||||
|
||||
// Construct for a foreign thread (e.g., Java).
|
||||
ThreadRegistrationInfo(const char* aName, ProfilerThreadId aThreadId,
|
||||
bool aIsMainThread, const TimeStamp& aRegisterTime)
|
||||
: mName(aName),
|
||||
mRegisterTime(aRegisterTime),
|
||||
mThreadId(aThreadId),
|
||||
mIsMainThread(aIsMainThread) {}
|
||||
|
||||
// Only allow move construction, for extraction when the thread ends.
|
||||
ThreadRegistrationInfo(ThreadRegistrationInfo&&) = default;
|
||||
|
||||
// Other copies/moves disallowed.
|
||||
ThreadRegistrationInfo(const ThreadRegistrationInfo&) = delete;
|
||||
ThreadRegistrationInfo& operator=(const ThreadRegistrationInfo&) = delete;
|
||||
ThreadRegistrationInfo& operator=(ThreadRegistrationInfo&&) = delete;
|
||||
|
||||
[[nodiscard]] const char* Name() const { return mName.c_str(); }
|
||||
[[nodiscard]] const TimeStamp& RegisterTime() const { return mRegisterTime; }
|
||||
[[nodiscard]] ProfilerThreadId ThreadId() const { return mThreadId; }
|
||||
[[nodiscard]] bool IsMainThread() const { return mIsMainThread; }
|
||||
|
||||
private:
|
||||
const std::string mName;
|
||||
const TimeStamp mRegisterTime = TimeStamp::Now();
|
||||
const ProfilerThreadId mThreadId = profiler_current_thread_id();
|
||||
const bool mIsMainThread = profiler_is_main_thread();
|
||||
};
|
||||
|
||||
} // namespace mozilla::profiler
|
||||
|
||||
#endif // ProfilerThreadRegistrationInfo_h
|
|
@ -9,7 +9,9 @@
|
|||
// happens when calling these functions. They don't do much inspection of
|
||||
// profiler internals.
|
||||
|
||||
#include "mozilla/ProfilerThreadRegistrationInfo.h"
|
||||
#include "mozilla/ProfilerUtils.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
@ -34,7 +36,6 @@
|
|||
# include "mozilla/ProfileBufferEntrySerializationGeckoExtensions.h"
|
||||
# include "mozilla/ProfileJSONWriter.h"
|
||||
# include "mozilla/ScopeExit.h"
|
||||
# include "mozilla/UniquePtrExtensions.h"
|
||||
# include "mozilla/net/HttpBaseChannel.h"
|
||||
# include "nsIChannelEventSink.h"
|
||||
# include "nsIThread.h"
|
||||
|
@ -98,6 +99,72 @@ TEST(GeckoProfiler, ProfilerUtils)
|
|||
testThread.join();
|
||||
}
|
||||
|
||||
TEST(GeckoProfiler, ThreadRegistrationInfo)
|
||||
{
|
||||
profiler_init_main_thread_id();
|
||||
|
||||
TimeStamp ts = TimeStamp::Now();
|
||||
{
|
||||
profiler::ThreadRegistrationInfo trInfo{
|
||||
"name", ProfilerThreadId::FromNumber(123), false, ts};
|
||||
EXPECT_STREQ(trInfo.Name(), "name");
|
||||
EXPECT_NE(trInfo.Name(), "name")
|
||||
<< "ThreadRegistrationInfo should keep its own copy of the name";
|
||||
EXPECT_EQ(trInfo.RegisterTime(), ts);
|
||||
EXPECT_EQ(trInfo.ThreadId(), ProfilerThreadId::FromNumber(123));
|
||||
EXPECT_EQ(trInfo.IsMainThread(), false);
|
||||
}
|
||||
|
||||
// Make sure the next timestamp will be different from `ts`.
|
||||
while (TimeStamp::Now() == ts) {
|
||||
}
|
||||
|
||||
{
|
||||
profiler::ThreadRegistrationInfo trInfoHere{"Here"};
|
||||
EXPECT_STREQ(trInfoHere.Name(), "Here");
|
||||
EXPECT_NE(trInfoHere.Name(), "Here")
|
||||
<< "ThreadRegistrationInfo should keep its own copy of the name";
|
||||
EXPECT_GT(trInfoHere.RegisterTime(), ts);
|
||||
EXPECT_EQ(trInfoHere.ThreadId(), profiler_current_thread_id());
|
||||
EXPECT_EQ(trInfoHere.ThreadId(), profiler_main_thread_id())
|
||||
<< "Gtests are assumed to run on the main thread";
|
||||
EXPECT_EQ(trInfoHere.IsMainThread(), true)
|
||||
<< "Gtests are assumed to run on the main thread";
|
||||
}
|
||||
|
||||
{
|
||||
// Sub-thread test.
|
||||
// These will receive sub-thread data (to test move at thread end).
|
||||
TimeStamp tsThread;
|
||||
ProfilerThreadId threadThreadId;
|
||||
UniquePtr<profiler::ThreadRegistrationInfo> trInfoThreadPtr;
|
||||
|
||||
std::thread testThread([&]() {
|
||||
profiler::ThreadRegistrationInfo trInfoThread{"Thread"};
|
||||
EXPECT_STREQ(trInfoThread.Name(), "Thread");
|
||||
EXPECT_NE(trInfoThread.Name(), "Thread")
|
||||
<< "ThreadRegistrationInfo should keep its own copy of the name";
|
||||
EXPECT_GT(trInfoThread.RegisterTime(), ts);
|
||||
EXPECT_EQ(trInfoThread.ThreadId(), profiler_current_thread_id());
|
||||
EXPECT_NE(trInfoThread.ThreadId(), profiler_main_thread_id());
|
||||
EXPECT_EQ(trInfoThread.IsMainThread(), false);
|
||||
|
||||
tsThread = trInfoThread.RegisterTime();
|
||||
threadThreadId = trInfoThread.ThreadId();
|
||||
trInfoThreadPtr =
|
||||
MakeUnique<profiler::ThreadRegistrationInfo>(std::move(trInfoThread));
|
||||
});
|
||||
testThread.join();
|
||||
|
||||
ASSERT_NE(trInfoThreadPtr, nullptr);
|
||||
EXPECT_STREQ(trInfoThreadPtr->Name(), "Thread");
|
||||
EXPECT_EQ(trInfoThreadPtr->RegisterTime(), tsThread);
|
||||
EXPECT_EQ(trInfoThreadPtr->ThreadId(), threadThreadId);
|
||||
EXPECT_EQ(trInfoThreadPtr->IsMainThread(), false)
|
||||
<< "Gtests are assumed to run on the main thread";
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
|
||||
TEST(BaseProfiler, BlocksRingBuffer)
|
||||
|
|
Загрузка…
Ссылка в новой задаче