зеркало из https://github.com/mozilla/gecko-dev.git
181 строка
4.2 KiB
C++
181 строка
4.2 KiB
C++
/* -*- 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 {
|
|
|
|
struct LogRecDispatch {
|
|
uint32_t mType;
|
|
uint32_t mSourceEventType;
|
|
uint64_t mTaskId;
|
|
uint64_t mTime;
|
|
uint64_t mSourceEventId;
|
|
uint64_t mParentTaskId;
|
|
};
|
|
|
|
struct LogRecBegin {
|
|
uint32_t mType;
|
|
uint64_t mTaskId;
|
|
uint64_t mTime;
|
|
uint32_t mPid;
|
|
uint32_t mTid;
|
|
};
|
|
|
|
struct LogRecEnd {
|
|
uint32_t mType;
|
|
uint64_t mTaskId;
|
|
uint64_t mTime;
|
|
};
|
|
|
|
struct LogRecVPtr {
|
|
uint32_t mType;
|
|
uint64_t mTaskId;
|
|
uintptr_t mVPtr;
|
|
};
|
|
|
|
struct LogRecLabel {
|
|
uint32_t mType;
|
|
uint32_t mStrIdx;
|
|
uint64_t mTaskId;
|
|
uint64_t mTime;
|
|
};
|
|
|
|
union TraceInfoLogType {
|
|
uint32_t mType;
|
|
LogRecDispatch mDispatch;
|
|
LogRecBegin mBegin;
|
|
LogRecEnd mEnd;
|
|
LogRecVPtr mVPtr;
|
|
LogRecLabel mLabel;
|
|
};
|
|
|
|
struct TraceInfoLogNode {
|
|
TraceInfoLogType mLog;
|
|
TraceInfoLogNode* mNext;
|
|
};
|
|
|
|
struct TraceInfo {
|
|
explicit TraceInfo(uint32_t aThreadId)
|
|
: mCurTraceSourceId(0),
|
|
mCurTaskId(0),
|
|
mCurTraceSourceType(Unknown),
|
|
mThreadId(aThreadId),
|
|
mLastUniqueTaskId(0),
|
|
mObsolete(false),
|
|
mLogsMutex("TraceInfoMutex"),
|
|
mLogsHead(nullptr),
|
|
mLogsTail(nullptr),
|
|
mLogsSize(0) {
|
|
MOZ_COUNT_CTOR(TraceInfo);
|
|
}
|
|
|
|
~TraceInfo() {
|
|
MOZ_COUNT_DTOR(TraceInfo);
|
|
while (mLogsHead) {
|
|
auto node = mLogsHead;
|
|
mLogsHead = node->mNext;
|
|
delete node;
|
|
}
|
|
}
|
|
|
|
TraceInfoLogType* AppendLog();
|
|
|
|
uint64_t mCurTraceSourceId;
|
|
uint64_t mCurTaskId;
|
|
SourceEventType mCurTraceSourceType;
|
|
uint32_t mThreadId;
|
|
uint32_t mLastUniqueTaskId;
|
|
mozilla::Atomic<bool> mObsolete;
|
|
|
|
// This mutex protects the following log
|
|
mozilla::Mutex mLogsMutex;
|
|
TraceInfoLogNode* mLogsHead;
|
|
TraceInfoLogNode* mLogsTail;
|
|
int mLogsSize;
|
|
nsTArray<nsCString> mStrs;
|
|
};
|
|
|
|
class TraceInfoHolder {
|
|
public:
|
|
TraceInfoHolder() : mInfo(nullptr) {}
|
|
explicit TraceInfoHolder(TraceInfo* aInfo) : mInfo(aInfo) {
|
|
aInfo->mLogsMutex.AssertNotCurrentThreadOwns(); // in case of recursive
|
|
aInfo->mLogsMutex.Lock();
|
|
MOZ_ASSERT(aInfo);
|
|
}
|
|
TraceInfoHolder(const TraceInfoHolder& aOther) = delete;
|
|
TraceInfoHolder(TraceInfoHolder&& aOther) : mInfo(aOther.mInfo) {
|
|
if (!!aOther) {
|
|
aOther->mLogsMutex.AssertCurrentThreadOwns();
|
|
}
|
|
aOther.mInfo = nullptr;
|
|
}
|
|
~TraceInfoHolder() {
|
|
if (mInfo) mInfo->mLogsMutex.Unlock();
|
|
}
|
|
explicit operator bool() const { return !!mInfo; }
|
|
TraceInfo* operator->() { return mInfo; }
|
|
bool operator==(TraceInfo* aOther) const { return mInfo == aOther; }
|
|
bool operator==(const TraceInfoHolder& aOther) const {
|
|
return mInfo == aOther.mInfo;
|
|
}
|
|
void Reset() {
|
|
if (mInfo) {
|
|
mInfo->mLogsMutex.Unlock();
|
|
mInfo = nullptr;
|
|
}
|
|
}
|
|
|
|
private:
|
|
TraceInfo* mInfo;
|
|
};
|
|
|
|
// Return the TraceInfo of current thread, allocate a new one if not exit.
|
|
TraceInfoHolder GetOrCreateTraceInfo();
|
|
|
|
uint64_t GenNewUniqueTaskId();
|
|
|
|
void SetCurTraceInfo(uint64_t aSourceEventId, uint64_t aParentTaskId,
|
|
SourceEventType aSourceEventType);
|
|
|
|
/**
|
|
* 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 tasktracer
|
|
} // namespace mozilla
|
|
|
|
#endif
|