import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,472 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#include "GeckoTaskTracer.h"
#include "GeckoTaskTracerImpl.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/ThreadLocal.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Unused.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "prtime.h"
#include <stdarg.h>
// We need a definition of gettid(), but glibc doesn't provide a
// wrapper for it.
#if defined(__GLIBC__)
#include <unistd.h>
#include <sys/syscall.h>
static inline pid_t gettid()
{
return (pid_t) syscall(SYS_gettid);
}
#elif defined(XP_MACOSX)
#include <unistd.h>
#include <sys/syscall.h>
static inline pid_t gettid()
{
return (pid_t) syscall(SYS_thread_selfid);
}
#elif defined(LINUX)
#include <sys/types.h>
pid_t gettid();
#endif
// NS_ENSURE_TRUE_VOID() without the warning on the debug build.
#define ENSURE_TRUE_VOID(x) \
do { \
if (MOZ_UNLIKELY(!(x))) { \
return; \
} \
} while(0)
// NS_ENSURE_TRUE() without the warning on the debug build.
#define ENSURE_TRUE(x, ret) \
do { \
if (MOZ_UNLIKELY(!(x))) { \
return ret; \
} \
} while(0)
namespace mozilla {
namespace tasktracer {
static MOZ_THREAD_LOCAL(TraceInfo*) sTraceInfoTLS;
static mozilla::StaticMutex sMutex;
// The generation of TraceInfo. It will be > 0 if the Task Tracer is started and
// <= 0 if stopped.
static mozilla::Atomic<bool> sStarted;
static nsTArray<UniquePtr<TraceInfo>>* sTraceInfos = nullptr;
static PRTime sStartTime;
static const char sJSLabelPrefix[] = "#tt#";
namespace {
static PRTime
GetTimestamp()
{
return PR_Now() / 1000;
}
static TraceInfo*
AllocTraceInfo(int aTid)
{
StaticMutexAutoLock lock(sMutex);
auto* info = sTraceInfos->AppendElement(MakeUnique<TraceInfo>(aTid));
return info->get();
}
static void
SaveCurTraceInfo()
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
info->mSavedCurTraceSourceId = info->mCurTraceSourceId;
info->mSavedCurTraceSourceType = info->mCurTraceSourceType;
info->mSavedCurTaskId = info->mCurTaskId;
}
static void
RestoreCurTraceInfo()
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
info->mCurTraceSourceId = info->mSavedCurTraceSourceId;
info->mCurTraceSourceType = info->mSavedCurTraceSourceType;
info->mCurTaskId = info->mSavedCurTaskId;
}
static void
CreateSourceEvent(SourceEventType aType)
{
// Save the currently traced source event info.
SaveCurTraceInfo();
// Create a new unique task id.
uint64_t newId = GenNewUniqueTaskId();
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
info->mCurTraceSourceId = newId;
info->mCurTraceSourceType = aType;
info->mCurTaskId = newId;
uintptr_t* namePtr;
#define SOURCE_EVENT_NAME(type) \
case SourceEventType::type: \
{ \
static int CreateSourceEvent##type; \
namePtr = (uintptr_t*)&CreateSourceEvent##type; \
break; \
}
switch (aType) {
#include "SourceEventTypeMap.h"
default:
MOZ_CRASH("Unknown SourceEvent.");
}
#undef CREATE_SOURCE_EVENT_NAME
// Log a fake dispatch and start for this source event.
LogDispatch(newId, newId, newId, aType);
LogVirtualTablePtr(newId, newId, namePtr);
LogBegin(newId, newId);
}
static void
DestroySourceEvent()
{
// Log a fake end for this source event.
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
LogEnd(info->mCurTraceSourceId, info->mCurTraceSourceId);
// Restore the previously saved source event info.
RestoreCurTraceInfo();
}
inline static bool
IsStartLogging()
{
return sStarted;
}
static void
SetLogStarted(bool aIsStartLogging)
{
MOZ_ASSERT(aIsStartLogging != IsStartLogging());
sStarted = aIsStartLogging;
StaticMutexAutoLock lock(sMutex);
if (!aIsStartLogging) {
for (uint32_t i = 0; i < sTraceInfos->Length(); ++i) {
(*sTraceInfos)[i]->mObsolete = true;
}
}
}
static void
CleanUp()
{
SetLogStarted(false);
StaticMutexAutoLock lock(sMutex);
if (sTraceInfos) {
delete sTraceInfos;
sTraceInfos = nullptr;
}
}
inline static void
ObsoleteCurrentTraceInfos()
{
// Note that we can't and don't need to acquire sMutex here because this
// function is called before the other threads are recreated.
for (uint32_t i = 0; i < sTraceInfos->Length(); ++i) {
(*sTraceInfos)[i]->mObsolete = true;
}
}
} // namespace anonymous
nsCString*
TraceInfo::AppendLog()
{
MutexAutoLock lock(mLogsMutex);
return mLogs.AppendElement();
}
void
TraceInfo::MoveLogsInto(TraceInfoLogsType& aResult)
{
MutexAutoLock lock(mLogsMutex);
aResult.AppendElements(Move(mLogs));
}
void
InitTaskTracer(uint32_t aFlags)
{
if (aFlags & FORKED_AFTER_NUWA) {
ObsoleteCurrentTraceInfos();
return;
}
MOZ_ASSERT(!sTraceInfos);
sTraceInfos = new nsTArray<UniquePtr<TraceInfo>>();
if (!sTraceInfoTLS.initialized()) {
Unused << sTraceInfoTLS.init();
}
}
void
ShutdownTaskTracer()
{
CleanUp();
}
static void
FreeTraceInfo(TraceInfo* aTraceInfo)
{
StaticMutexAutoLock lock(sMutex);
if (aTraceInfo) {
sTraceInfos->RemoveElement(aTraceInfo);
}
}
void FreeTraceInfo()
{
FreeTraceInfo(sTraceInfoTLS.get());
}
TraceInfo*
GetOrCreateTraceInfo()
{
ENSURE_TRUE(sTraceInfoTLS.initialized(), nullptr);
ENSURE_TRUE(IsStartLogging(), nullptr);
TraceInfo* info = sTraceInfoTLS.get();
if (info && info->mObsolete) {
// TraceInfo is obsolete: remove it.
FreeTraceInfo(info);
info = nullptr;
}
if (!info) {
info = AllocTraceInfo(gettid());
sTraceInfoTLS.set(info);
}
return info;
}
uint64_t
GenNewUniqueTaskId()
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE(info, 0);
pid_t tid = gettid();
uint64_t taskid = ((uint64_t)tid << 32) | ++info->mLastUniqueTaskId;
return taskid;
}
AutoSaveCurTraceInfo::AutoSaveCurTraceInfo()
{
SaveCurTraceInfo();
}
AutoSaveCurTraceInfo::~AutoSaveCurTraceInfo()
{
RestoreCurTraceInfo();
}
void
SetCurTraceInfo(uint64_t aSourceEventId, uint64_t aParentTaskId,
SourceEventType aSourceEventType)
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
info->mCurTraceSourceId = aSourceEventId;
info->mCurTaskId = aParentTaskId;
info->mCurTraceSourceType = aSourceEventType;
}
void
GetCurTraceInfo(uint64_t* aOutSourceEventId, uint64_t* aOutParentTaskId,
SourceEventType* aOutSourceEventType)
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
*aOutSourceEventId = info->mCurTraceSourceId;
*aOutParentTaskId = info->mCurTaskId;
*aOutSourceEventType = info->mCurTraceSourceType;
}
void
LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId, uint64_t aSourceEventId,
SourceEventType aSourceEventType)
{
LogDispatch(aTaskId, aParentTaskId, aSourceEventId, aSourceEventType, 0);
}
void
LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId, uint64_t aSourceEventId,
SourceEventType aSourceEventType, int aDelayTimeMs)
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
// aDelayTimeMs is the expected delay time in milliseconds, thus the dispatch
// time calculated of it might be slightly off in the real world.
uint64_t time = (aDelayTimeMs <= 0) ? GetTimestamp() :
GetTimestamp() + aDelayTimeMs;
// Log format:
// [0 taskId dispatchTime sourceEventId sourceEventType parentTaskId]
nsCString* log = info->AppendLog();
if (log) {
log->AppendPrintf("%d %lld %lld %lld %d %lld",
ACTION_DISPATCH, aTaskId, time, aSourceEventId,
aSourceEventType, aParentTaskId);
}
}
void
LogBegin(uint64_t aTaskId, uint64_t aSourceEventId)
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
// Log format:
// [1 taskId beginTime processId threadId]
nsCString* log = info->AppendLog();
if (log) {
log->AppendPrintf("%d %lld %lld %d %d",
ACTION_BEGIN, aTaskId, GetTimestamp(), getpid(), gettid());
}
}
void
LogEnd(uint64_t aTaskId, uint64_t aSourceEventId)
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
// Log format:
// [2 taskId endTime]
nsCString* log = info->AppendLog();
if (log) {
log->AppendPrintf("%d %lld %lld", ACTION_END, aTaskId, GetTimestamp());
}
}
void
LogVirtualTablePtr(uint64_t aTaskId, uint64_t aSourceEventId, uintptr_t* aVptr)
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
// Log format:
// [4 taskId address]
nsCString* log = info->AppendLog();
if (log) {
log->AppendPrintf("%d %lld %p", ACTION_GET_VTABLE, aTaskId, aVptr);
}
}
AutoSourceEvent::AutoSourceEvent(SourceEventType aType)
{
CreateSourceEvent(aType);
}
AutoSourceEvent::~AutoSourceEvent()
{
DestroySourceEvent();
}
void AddLabel(const char* aFormat, ...)
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
va_list args;
va_start(args, aFormat);
nsAutoCString buffer;
buffer.AppendPrintf(aFormat, args);
va_end(args);
// Log format:
// [3 taskId "label"]
nsCString* log = info->AppendLog();
if (log) {
log->AppendPrintf("%d %lld %lld \"%s\"", ACTION_ADD_LABEL, info->mCurTaskId,
GetTimestamp(), buffer.get());
}
}
// Functions used by GeckoProfiler.
void
StartLogging()
{
sStartTime = GetTimestamp();
SetLogStarted(true);
}
void
StopLogging()
{
SetLogStarted(false);
}
UniquePtr<TraceInfoLogsType>
GetLoggedData(TimeStamp aTimeStamp)
{
auto result = MakeUnique<TraceInfoLogsType>();
// TODO: This is called from a signal handler. Use semaphore instead.
StaticMutexAutoLock lock(sMutex);
for (uint32_t i = 0; i < sTraceInfos->Length(); ++i) {
(*sTraceInfos)[i]->MoveLogsInto(*result);
}
return result;
}
const PRTime
GetStartTime()
{
return sStartTime;
}
const char*
GetJSLabelPrefix()
{
return sJSLabelPrefix;
}
#undef ENSURE_TRUE_VOID
#undef ENSURE_TRUE
} // namespace tasktracer
} // namespace mozilla

View file

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 GECKO_TASK_TRACER_H
#define GECKO_TASK_TRACER_H
#include "mozilla/UniquePtr.h"
#include "nsCOMPtr.h"
#include "nsTArrayForwardDeclare.h"
/**
* TaskTracer provides a way to trace the correlation between different tasks
* across threads and processes. Unlike sampling based profilers, TaskTracer can
* tell you where a task is dispatched from, what its original source was, how
* long it waited in the event queue, and how long it took to execute.
*
* Source Events are usually some kinds of I/O events we're interested in, such
* as touch events, timer events, network events, etc. When a source event is
* created, TaskTracer records the entire chain of Tasks and nsRunnables as they
* are dispatched to different threads and processes. It records latency,
* execution time, etc. for each Task and nsRunnable that chains back to the
* original source event.
*/
class Task;
class nsIRunnable;
class nsCString;
namespace mozilla {
class TimeStamp;
namespace tasktracer {
enum {
FORKED_AFTER_NUWA = 1 << 0
};
enum SourceEventType {
Unknown = 0,
Touch,
Mouse,
Key,
Bluetooth,
Unixsocket,
Wifi
};
class AutoSourceEvent
{
public:
AutoSourceEvent(SourceEventType aType);
~AutoSourceEvent();
};
void InitTaskTracer(uint32_t aFlags = 0);
void ShutdownTaskTracer();
// Add a label to the currently running task, aFormat is the message to log,
// followed by corresponding parameters.
void AddLabel(const char* aFormat, ...);
void StartLogging();
void StopLogging();
UniquePtr<nsTArray<nsCString>> GetLoggedData(TimeStamp aStartTime);
// Returns the timestamp when Task Tracer is enabled in this process.
const PRTime GetStartTime();
/**
* Internal functions.
*/
Task* CreateTracedTask(Task* aTask);
already_AddRefed<nsIRunnable>
CreateTracedRunnable(already_AddRefed<nsIRunnable>&& aRunnable);
// Free the TraceInfo allocated on a thread's TLS. Currently we are wrapping
// tasks running on nsThreads and base::thread, so FreeTraceInfo is called at
// where nsThread and base::thread release themselves.
void FreeTraceInfo();
const char* GetJSLabelPrefix();
} // namespace tasktracer
} // namespace mozilla.
#endif

View file

@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 GECKO_TASK_TRACER_IMPL_H
#define GECKO_TASK_TRACER_IMPL_H
#include "GeckoTaskTracer.h"
#include "mozilla/Mutex.h"
#include "nsTArray.h"
namespace mozilla {
namespace tasktracer {
typedef nsTArray<nsCString> TraceInfoLogsType;
struct TraceInfo
{
TraceInfo(uint32_t aThreadId)
: mCurTraceSourceId(0)
, mCurTaskId(0)
, mSavedCurTraceSourceId(0)
, mSavedCurTaskId(0)
, mCurTraceSourceType(Unknown)
, mSavedCurTraceSourceType(Unknown)
, mThreadId(aThreadId)
, mLastUniqueTaskId(0)
, mObsolete(false)
, mLogsMutex("TraceInfoMutex")
{
MOZ_COUNT_CTOR(TraceInfo);
}
~TraceInfo() { MOZ_COUNT_DTOR(TraceInfo); }
nsCString* AppendLog();
void MoveLogsInto(TraceInfoLogsType& aResult);
uint64_t mCurTraceSourceId;
uint64_t mCurTaskId;
uint64_t mSavedCurTraceSourceId;
uint64_t mSavedCurTaskId;
SourceEventType mCurTraceSourceType;
SourceEventType mSavedCurTraceSourceType;
uint32_t mThreadId;
uint32_t mLastUniqueTaskId;
mozilla::Atomic<bool> mObsolete;
// This mutex protects the following log array because MoveLogsInto() might
// be called on another thread.
mozilla::Mutex mLogsMutex;
TraceInfoLogsType mLogs;
};
// Return the TraceInfo of current thread, allocate a new one if not exit.
TraceInfo* GetOrCreateTraceInfo();
uint64_t GenNewUniqueTaskId();
class AutoSaveCurTraceInfo
{
public:
AutoSaveCurTraceInfo();
~AutoSaveCurTraceInfo();
};
void SetCurTraceInfo(uint64_t aSourceEventId, uint64_t aParentTaskId,
SourceEventType aSourceEventType);
void GetCurTraceInfo(uint64_t* aOutSourceEventId, uint64_t* aOutParentTaskId,
SourceEventType* aOutSourceEventType);
/**
* Logging functions of different trace actions.
*/
enum ActionType {
ACTION_DISPATCH = 0,
ACTION_BEGIN,
ACTION_END,
ACTION_ADD_LABEL,
ACTION_GET_VTABLE
};
void LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId,
uint64_t aSourceEventId, SourceEventType aSourceEventType);
void LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId,
uint64_t aSourceEventId, SourceEventType aSourceEventType,
int aDelayTimeMs);
void LogBegin(uint64_t aTaskId, uint64_t aSourceEventId);
void LogEnd(uint64_t aTaskId, uint64_t aSourceEventId);
void LogVirtualTablePtr(uint64_t aTaskId, uint64_t aSourceEventId, uintptr_t* aVptr);
} // namespace mozilla
} // namespace tasktracer
#endif

View file

@ -0,0 +1,11 @@
/* 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/. */
SOURCE_EVENT_NAME(Unknown)
SOURCE_EVENT_NAME(Touch)
SOURCE_EVENT_NAME(Mouse)
SOURCE_EVENT_NAME(Key)
SOURCE_EVENT_NAME(Bluetooth)
SOURCE_EVENT_NAME(Unixsocket)
SOURCE_EVENT_NAME(Wifi)

View file

@ -0,0 +1,169 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#include "GeckoTaskTracerImpl.h"
#include "TracedTaskCommon.h"
// NS_ENSURE_TRUE_VOID() without the warning on the debug build.
#define ENSURE_TRUE_VOID(x) \
do { \
if (MOZ_UNLIKELY(!(x))) { \
return; \
} \
} while(0)
namespace mozilla {
namespace tasktracer {
TracedTaskCommon::TracedTaskCommon()
: mSourceEventType(SourceEventType::Unknown)
, mSourceEventId(0)
, mParentTaskId(0)
, mTaskId(0)
, mIsTraceInfoInit(false)
{
}
TracedTaskCommon::~TracedTaskCommon()
{
}
void
TracedTaskCommon::Init()
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
mTaskId = GenNewUniqueTaskId();
mSourceEventId = info->mCurTraceSourceId;
mSourceEventType = info->mCurTraceSourceType;
mParentTaskId = info->mCurTaskId;
mIsTraceInfoInit = true;
}
void
TracedTaskCommon::DispatchTask(int aDelayTimeMs)
{
LogDispatch(mTaskId, mParentTaskId, mSourceEventId, mSourceEventType,
aDelayTimeMs);
}
void
TracedTaskCommon::GetTLSTraceInfo()
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
mSourceEventType = info->mCurTraceSourceType;
mSourceEventId = info->mCurTraceSourceId;
mTaskId = info->mCurTaskId;
mIsTraceInfoInit = true;
}
void
TracedTaskCommon::SetTLSTraceInfo()
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
if (mIsTraceInfoInit) {
info->mCurTraceSourceId = mSourceEventId;
info->mCurTraceSourceType = mSourceEventType;
info->mCurTaskId = mTaskId;
}
}
void
TracedTaskCommon::ClearTLSTraceInfo()
{
TraceInfo* info = GetOrCreateTraceInfo();
ENSURE_TRUE_VOID(info);
info->mCurTraceSourceId = 0;
info->mCurTraceSourceType = SourceEventType::Unknown;
info->mCurTaskId = 0;
}
/**
* Implementation of class TracedRunnable.
*/
TracedRunnable::TracedRunnable(already_AddRefed<nsIRunnable>&& aOriginalObj)
: TracedTaskCommon()
, mOriginalObj(Move(aOriginalObj))
{
Init();
LogVirtualTablePtr(mTaskId, mSourceEventId, reinterpret_cast<uintptr_t*>(mOriginalObj.get()));
}
TracedRunnable::~TracedRunnable()
{
}
NS_IMETHODIMP
TracedRunnable::Run()
{
SetTLSTraceInfo();
LogBegin(mTaskId, mSourceEventId);
nsresult rv = mOriginalObj->Run();
LogEnd(mTaskId, mSourceEventId);
ClearTLSTraceInfo();
return rv;
}
/**
* Implementation of class TracedTask.
*/
TracedTask::TracedTask(Task* aOriginalObj)
: TracedTaskCommon()
, mOriginalObj(aOriginalObj)
{
Init();
LogVirtualTablePtr(mTaskId, mSourceEventId, reinterpret_cast<uintptr_t*>(aOriginalObj));
}
TracedTask::~TracedTask()
{
if (mOriginalObj) {
delete mOriginalObj;
mOriginalObj = nullptr;
}
}
void
TracedTask::Run()
{
SetTLSTraceInfo();
LogBegin(mTaskId, mSourceEventId);
mOriginalObj->Run();
LogEnd(mTaskId, mSourceEventId);
ClearTLSTraceInfo();
}
/**
* CreateTracedRunnable() returns a TracedRunnable wrapping the original
* nsIRunnable object, aRunnable.
*/
already_AddRefed<nsIRunnable>
CreateTracedRunnable(already_AddRefed<nsIRunnable>&& aRunnable)
{
nsCOMPtr<nsIRunnable> runnable = new TracedRunnable(Move(aRunnable));
return runnable.forget();
}
/**
* CreateTracedTask() returns a TracedTask wrapping the original Task object,
* aTask.
*/
Task*
CreateTracedTask(Task* aTask)
{
Task* task = new TracedTask(aTask);
return task;
}
} // namespace tasktracer
} // namespace mozilla

View file

@ -0,0 +1,73 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 TRACED_TASK_COMMON_H
#define TRACED_TASK_COMMON_H
#include "base/task.h"
#include "GeckoTaskTracer.h"
#include "nsCOMPtr.h"
#include "nsThreadUtils.h"
namespace mozilla {
namespace tasktracer {
class TracedTaskCommon
{
public:
TracedTaskCommon();
virtual ~TracedTaskCommon();
void DispatchTask(int aDelayTimeMs = 0);
void SetTLSTraceInfo();
void GetTLSTraceInfo();
void ClearTLSTraceInfo();
protected:
void Init();
// TraceInfo of TLS will be set by the following parameters, including source
// event type, source event ID, parent task ID, and task ID of this traced
// task/runnable.
SourceEventType mSourceEventType;
uint64_t mSourceEventId;
uint64_t mParentTaskId;
uint64_t mTaskId;
bool mIsTraceInfoInit;
};
class TracedRunnable : public TracedTaskCommon
, public nsRunnable
{
public:
NS_DECL_NSIRUNNABLE
TracedRunnable(already_AddRefed<nsIRunnable>&& aOriginalObj);
private:
virtual ~TracedRunnable();
nsCOMPtr<nsIRunnable> mOriginalObj;
};
class TracedTask : public TracedTaskCommon
, public Task
{
public:
TracedTask(Task* aOriginalObj);
~TracedTask();
virtual void Run();
private:
Task* mOriginalObj;
};
} // namespace tasktracer
} // namespace mozilla
#endif