summaryrefslogtreecommitdiffstats
path: root/external/optick/optick_core.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'external/optick/optick_core.cpp')
-rw-r--r--external/optick/optick_core.cpp1657
1 files changed, 0 insertions, 1657 deletions
diff --git a/external/optick/optick_core.cpp b/external/optick/optick_core.cpp
deleted file mode 100644
index 1d533d0..0000000
--- a/external/optick/optick_core.cpp
+++ /dev/null
@@ -1,1657 +0,0 @@
-#include "optick.config.h"
-
-#if USE_OPTICK
-
-#include "optick_core.h"
-#include "optick_server.h"
-
-#include <algorithm>
-#include <fstream>
-
-//////////////////////////////////////////////////////////////////////////
-// Start of the Platform-specific stuff
-//////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_MSVC)
-#include "optick_core.win.h"
-#endif
-#if defined(OPTICK_LINUX)
-#include "optick_core.linux.h"
-#endif
-#if defined(OPTICK_OSX)
-#include "optick_core.macos.h"
-#endif
-#if defined(OPTICK_PS4)
-#include "optick_core.ps4.h"
-#endif
-//////////////////////////////////////////////////////////////////////////
-// End of the Platform-specific stuff
-//////////////////////////////////////////////////////////////////////////
-
-extern "C" Optick::EventData* NextEvent()
-{
- if (Optick::EventStorage* storage = Optick::Core::storage)
- {
- return &storage->NextEvent();
- }
-
- return nullptr;
-}
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void* (*Memory::allocate)(size_t) = operator new;
-void (*Memory::deallocate)(void* p) = operator delete;
-std::atomic<uint64_t> Memory::memAllocated;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-uint64_t MurmurHash64A(const void * key, int len, uint64_t seed)
-{
- const uint64_t m = 0xc6a4a7935bd1e995;
- const int r = 47;
-
- uint64_t h = seed ^ (len * m);
-
- const uint64_t * data = (const uint64_t *)key;
- const uint64_t * end = data + (len / 8);
-
- while (data != end)
- {
- uint64_t k = *data++;
-
- k *= m;
- k ^= k >> r;
- k *= m;
-
- h ^= k;
- h *= m;
- }
-
- const unsigned char * data2 = (const unsigned char*)data;
-
- switch (len & 7)
- {
- case 7: h ^= uint64_t(data2[6]) << 48;
- case 6: h ^= uint64_t(data2[5]) << 40;
- case 5: h ^= uint64_t(data2[4]) << 32;
- case 4: h ^= uint64_t(data2[3]) << 24;
- case 3: h ^= uint64_t(data2[2]) << 16;
- case 2: h ^= uint64_t(data2[1]) << 8;
- case 1: h ^= uint64_t(data2[0]);
- h *= m;
- };
-
- h ^= h >> r;
- h *= m;
- h ^= h >> r;
-
- return h;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-uint64_t StringHash::CalcHash(const char* str)
-{
- return MurmurHash64A(str, (int)strlen(str), 0);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Base 64
-// https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-static inline bool is_base64(unsigned char c) {
- return (isalnum(c) || (c == '+') || (c == '/'));
-}
-string base64_decode(string const& encoded_string) {
- static string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- int in_len = (int)encoded_string.size();
- int i = 0;
- int j = 0;
- int in_ = 0;
- unsigned char char_array_4[4], char_array_3[3];
- string ret;
-
- while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
- char_array_4[i++] = encoded_string[in_]; in_++;
- if (i == 4) {
- for (i = 0; i < 4; i++)
- char_array_4[i] = (unsigned char)base64_chars.find(char_array_4[i]);
-
- char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
- char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
- char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
- for (i = 0; (i < 3); i++)
- ret += char_array_3[i];
- i = 0;
- }
- }
-
- if (i) {
- for (j = i; j < 4; j++)
- char_array_4[j] = 0;
-
- for (j = 0; j < 4; j++)
- char_array_4[j] = (unsigned char)base64_chars.find(char_array_4[j]);
-
- char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
- char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
- char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
- for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
- }
-
- return ret;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Get current time in milliseconds
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64 GetTimeMilliSeconds()
-{
- return Platform::GetTime() * 1000 / Platform::GetFrequency();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64 TicksToMs(int64 ticks)
-{
- return ticks * 1000 / Platform::GetFrequency();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64 TicksToUs(int64 ticks)
-{
- return ticks * 1000000 / Platform::GetFrequency();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template<class T>
-OutputDataStream& operator<<(OutputDataStream& stream, const TagData<T>& ob)
-{
- return stream << ob.timestamp << ob.description->index << ob.data;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& os, const Symbol * const symbol)
-{
- OPTICK_VERIFY(symbol, "Can't serialize NULL symbol!", return os);
- return os << symbol->address << symbol->function << symbol->file << symbol->line;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& os, const Module& module)
-{
- return os << module.path << (uint64)module.address << (uint64)module.size;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// VS TODO: Replace with random access iterator for MemoryPool
-template<class T, uint32 SIZE>
-void SortMemoryPool(MemoryPool<T, SIZE>& memoryPool)
-{
- size_t count = memoryPool.Size();
- if (count == 0)
- return;
-
- vector<T> memoryArray;
- memoryArray.resize(count);
- memoryPool.ToArray(&memoryArray[0]);
-
- std::sort(memoryArray.begin(), memoryArray.end());
-
- memoryPool.Clear(true);
-
- for (const T& item : memoryArray)
- memoryPool.Add(item);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription* EventDescription::Create(const char* eventName, const char* fileName, const unsigned long fileLine, const unsigned long eventColor /*= Color::Null*/, const unsigned long filter /*= 0*/)
-{
- return EventDescriptionBoard::Get().CreateDescription(eventName, fileName, fileLine, eventColor, filter);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription* EventDescription::CreateShared(const char* eventName, const char* fileName, const unsigned long fileLine, const unsigned long eventColor /*= Color::Null*/, const unsigned long filter /*= 0*/)
-{
- return EventDescriptionBoard::Get().CreateSharedDescription(eventName, fileName, fileLine, eventColor, filter);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription::EventDescription() : name(""), file(""), line(0), color(0)
-{
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription& EventDescription::operator=(const EventDescription&)
-{
- OPTICK_FAILED("It is pointless to copy EventDescription. Please, check you logic!"); return *this;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventData* Event::Start(const EventDescription& description)
-{
- EventData* result = nullptr;
-
- if (EventStorage* storage = Core::storage)
- {
- result = &storage->NextEvent();
- result->description = &description;
- result->Start();
- }
- return result;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Stop(EventData& data)
-{
- if (EventStorage* storage = Core::storage)
- {
- data.Stop();
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void OPTICK_INLINE PushEvent(EventStorage* pStorage, const EventDescription* description, int64_t timestampStart)
-{
- if (EventStorage* storage = pStorage)
- {
- EventData& result = storage->NextEvent();
- result.description = description;
- result.start = timestampStart;
- result.finish = EventTime::INVALID_TIMESTAMP;
- storage->pushPopEventStack[storage->pushPopEventStackIndex++] = &result;
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void OPTICK_INLINE PopEvent(EventStorage* pStorage, int64_t timestampFinish)
-{
- if (EventStorage* storage = pStorage)
- if (storage->pushPopEventStackIndex > 0)
- storage->pushPopEventStack[--storage->pushPopEventStackIndex]->finish = timestampFinish;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Push(const char* name)
-{
- if (EventStorage* storage = Core::storage)
- {
- EventDescription* desc = EventDescription::CreateShared(name);
- Push(*desc);
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Push(const EventDescription& description)
-{
- PushEvent(Core::storage, &description, GetHighPrecisionTime());
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Pop()
-{
- PopEvent(Core::storage, GetHighPrecisionTime());
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Add(EventStorage* storage, const EventDescription* description, int64_t timestampStart, int64_t timestampFinish)
-{
- EventData& data = storage->eventBuffer.Add();
- data.description = description;
- data.start = timestampStart;
- data.finish = timestampFinish;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Push(EventStorage* storage, const EventDescription* description, int64_t timestampStart)
-{
- PushEvent(storage, description, timestampStart);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Pop(EventStorage* storage, int64_t timestampFinish)
-{
- PopEvent(storage, timestampFinish);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventData* GPUEvent::Start(const EventDescription& description)
-{
- EventData* result = nullptr;
-
- if (EventStorage* storage = Core::storage)
- result = storage->gpuStorage.Start(description);
-
- return result;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void GPUEvent::Stop(EventData& data)
-{
- if (EventStorage* storage = Core::storage)
- storage->gpuStorage.Stop(data);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void FiberSyncData::AttachToThread(EventStorage* storage, uint64_t threadId)
-{
- if (storage)
- {
- FiberSyncData& data = storage->fiberSyncBuffer.Add();
- data.Start();
- data.finish = EventTime::INVALID_TIMESTAMP;
- data.threadId = threadId;
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void FiberSyncData::DetachFromThread(EventStorage* storage)
-{
- if (storage)
- {
- if (FiberSyncData* syncData = storage->fiberSyncBuffer.Back())
- {
- syncData->Stop();
- }
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, float val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagFloatBuffer.Add(TagFloat(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, int32_t val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagS32Buffer.Add(TagS32(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, uint32_t val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagU32Buffer.Add(TagU32(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, uint64_t val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagU64Buffer.Add(TagU64(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, float val[3])
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagPointBuffer.Add(TagPoint(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, const char* val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagStringBuffer.Add(TagString(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream & operator<<(OutputDataStream &stream, const EventDescription &ob)
-{
- byte flags = 0;
- return stream << ob.name << ob.file << ob.line << ob.filter << ob.color << (float)0.0f << flags;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const EventTime& ob)
-{
- return stream << ob.start << ob.finish;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const EventData& ob)
-{
- return stream << (EventTime)(ob) << (ob.description ? ob.description->index : (uint32)-1);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const SyncData& ob)
-{
- return stream << (EventTime)(ob) << ob.core << ob.reason << ob.newThreadId;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const FiberSyncData& ob)
-{
- return stream << (EventTime)(ob) << ob.threadId;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-static std::mutex& GetBoardLock()
-{
- // Initialize as static local variable to prevent problems with static initialization order
- static std::mutex lock;
- return lock;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescriptionBoard& EventDescriptionBoard::Get()
-{
- static EventDescriptionBoard instance;
- return instance;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const EventDescriptionList& EventDescriptionBoard::GetEvents() const
-{
- return boardDescriptions;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription* EventDescriptionBoard::CreateDescription(const char* name, const char* file /*= nullptr*/, uint32_t line /*= 0*/, uint32_t color /*= Color::Null*/, uint32_t filter /*= 0*/)
-{
- std::lock_guard<std::mutex> lock(GetBoardLock());
-
- size_t index = boardDescriptions.Size();
-
- EventDescription& desc = boardDescriptions.Add();
- desc.index = (uint32)index;
- desc.name = name;
- desc.file = file;
- desc.line = line;
- desc.color = color;
- desc.filter = filter;
-
- return &desc;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription* EventDescriptionBoard::CreateSharedDescription(const char* name, const char* file /*= nullptr*/, uint32_t line /*= 0*/, uint32_t color /*= Color::Null*/, uint32_t filter /*= 0*/)
-{
- StringHash nameHash(name);
-
- std::lock_guard<std::mutex> lock(sharedLock);
-
- std::pair<DescriptionMap::iterator, bool> cached = sharedDescriptions.insert({ nameHash, nullptr });
-
- if (cached.second)
- {
- const char* nameCopy = sharedNames.Add(name, strlen(name) + 1, false);
- cached.first->second = CreateDescription(nameCopy, file, line, color, filter);
- }
-
- return cached.first->second;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator << (OutputDataStream& stream, const EventDescriptionBoard& ob)
-{
- std::lock_guard<std::mutex> lock(GetBoardLock());
- stream << ob.GetEvents();
- return stream;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ProcessDescription::ProcessDescription(const char* processName, ProcessID pid, uint64 key) : name(processName), processID(pid), uniqueKey(key)
-{
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ThreadDescription::ThreadDescription(const char* threadName, ThreadID tid, ProcessID pid, int32 _maxDepth /*= 1*/, int32 _priority /*= 0*/, uint32 _mask /*= 0*/)
- : name(threadName), threadID(tid), processID(pid), maxDepth(_maxDepth), priority(_priority), mask(_mask)
-{
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64_t GetHighPrecisionTime()
-{
- return Platform::GetTime();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64_t GetHighPrecisionFrequency()
-{
- return Platform::GetFrequency();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream & operator<<(OutputDataStream &stream, const SysCallData &ob)
-{
- return stream << (const EventData&)ob << ob.threadID << ob.id;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-SysCallData& SysCallCollector::Add()
-{
- return syscallPool.Add();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void SysCallCollector::Clear()
-{
- syscallPool.Clear(false);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool SysCallCollector::Serialize(OutputDataStream& stream)
-{
- stream << syscallPool;
-
- if (!syscallPool.IsEmpty())
- {
- syscallPool.Clear(false);
- return true;
- }
-
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void CallstackCollector::Add(const CallstackDesc& desc)
-{
- if (uint64* storage = callstacksPool.TryAdd(desc.count + 3))
- {
- storage[0] = desc.threadID;
- storage[1] = desc.timestamp;
- storage[2] = desc.count;
-
- for (uint64 i = 0; i < desc.count; ++i)
- {
- storage[3 + i] = desc.callstack[desc.count - i - 1];
- }
- }
- else
- {
- uint64& item0 = callstacksPool.Add();
- uint64& item1 = callstacksPool.Add();
- uint64& item2 = callstacksPool.Add();
-
- item0 = desc.threadID;
- item1 = desc.timestamp;
- item2 = desc.count;
-
- for (uint64 i = 0; i < desc.count; ++i)
- {
- callstacksPool.Add() = desc.callstack[desc.count - i - 1];
- }
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void CallstackCollector::Clear()
-{
- callstacksPool.Clear(false);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool CallstackCollector::SerializeModules(OutputDataStream& stream)
-{
- if (SymbolEngine* symEngine = Core::Get().symbolEngine)
- {
- stream << symEngine->GetModules();
- return true;
- }
- else
- {
- stream << (int)0;
- }
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool CallstackCollector::SerializeSymbols(OutputDataStream& stream)
-{
- typedef unordered_set<uint64> SymbolSet;
- SymbolSet symbolSet;
-
- for (CallstacksPool::const_iterator it = callstacksPool.begin(); it != callstacksPool.end();)
- {
- CallstacksPool::const_iterator startIt = it;
- OPTICK_UNUSED(startIt);
-
- uint64 threadID = *it;
- OPTICK_UNUSED(threadID);
- ++it; //Skip ThreadID
- uint64 timestamp = *it;
- OPTICK_UNUSED
- (timestamp);
- ++it; //Skip Timestamp
- uint64 count = *it;
- count = (count & 0xFF);
- ++it; //Skip Count
-
- bool isBadAddrFound = false;
-
- for (uint64 i = 0; i < count; ++i)
- {
- uint64 address = *it;
- ++it;
-
- if (address == 0)
- {
- isBadAddrFound = true;
- }
-
- if (!isBadAddrFound)
- {
- symbolSet.insert(address);
- }
- }
- }
-
- SymbolEngine* symEngine = Core::Get().symbolEngine;
-
- vector<const Symbol*> symbols;
- symbols.reserve(symbolSet.size());
-
- size_t callstackIndex = 0;
-
- Core::Get().DumpProgress("Resolving addresses... ");
-
- if (symEngine)
- {
- for (auto it = symbolSet.begin(); it != symbolSet.end(); ++it)
- {
- callstackIndex++;
-
- uint64 address = *it;
- if (const Symbol* symbol = symEngine->GetSymbol(address))
- {
- symbols.push_back(symbol);
- }
- }
- }
-
- stream << symbols;
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool CallstackCollector::SerializeCallstacks(OutputDataStream& stream)
-{
- stream << callstacksPool;
-
- if (!callstacksPool.IsEmpty())
- {
- callstacksPool.Clear(false);
- return true;
- }
-
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool CallstackCollector::IsEmpty() const
-{
- return callstacksPool.IsEmpty();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream & operator<<(OutputDataStream &stream, const SwitchContextDesc &ob)
-{
- return stream << ob.timestamp << ob.oldThreadId << ob.newThreadId << ob.cpuId << ob.reason;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void SwitchContextCollector::Add(const SwitchContextDesc& desc)
-{
- switchContextPool.Add() = desc;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void SwitchContextCollector::Clear()
-{
- switchContextPool.Clear(false);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool SwitchContextCollector::Serialize(OutputDataStream& stream)
-{
- stream << switchContextPool;
-
- if (!switchContextPool.IsEmpty())
- {
- switchContextPool.Clear(false);
- return true;
- }
-
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_MSVC)
-#define CPUID(INFO, ID) __cpuid(INFO, ID)
-#include <intrin.h>
-#elif defined(OPTICK_GCC)
-#include <cpuid.h>
-#define CPUID(INFO, ID) __cpuid(ID, INFO[0], INFO[1], INFO[2], INFO[3])
-#else
-#error Platform is not supported!
-#endif
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-string GetCPUName()
-{
- int cpuInfo[4] = { -1 };
- char cpuBrandString[0x40] = { 0 };
- CPUID(cpuInfo, 0x80000000);
- unsigned nExIds = cpuInfo[0];
- for (unsigned i = 0x80000000; i <= nExIds; ++i)
- {
- CPUID(cpuInfo, i);
- if (i == 0x80000002)
- memcpy(cpuBrandString, cpuInfo, sizeof(cpuInfo));
- else if (i == 0x80000003)
- memcpy(cpuBrandString + 16, cpuInfo, sizeof(cpuInfo));
- else if (i == 0x80000004)
- memcpy(cpuBrandString + 32, cpuInfo, sizeof(cpuInfo));
- }
- return string(cpuBrandString);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Core& Core::Get()
-{
- static Core instance;
- return instance;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::StartCapture()
-{
- pendingState = State::START_CAPTURE;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::StopCapture()
-{
- pendingState = State::STOP_CAPTURE;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::CancelCapture()
-{
- pendingState = State::CANCEL_CAPTURE;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpCapture()
-{
- pendingState = State::DUMP_CAPTURE;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpProgress(const char* message)
-{
- progressReportedLastTimestampMS = GetTimeMilliSeconds();
-
- OutputDataStream stream;
- stream << message;
-
- Server::Get().Send(DataResponse::ReportProgress, stream);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpEvents(EventStorage& entry, const EventTime& timeSlice, ScopeData& scope)
-{
- if (!entry.eventBuffer.IsEmpty())
- {
- const EventData* rootEvent = nullptr;
-
- entry.eventBuffer.ForEach([&](const EventData& data)
- {
- if (data.finish >= data.start && data.start >= timeSlice.start && timeSlice.finish >= data.finish)
- {
- if (!rootEvent)
- {
- rootEvent = &data;
- scope.InitRootEvent(*rootEvent);
- }
- else if (rootEvent->finish < data.finish)
- {
- scope.Send();
-
- rootEvent = &data;
- scope.InitRootEvent(*rootEvent);
- }
- else
- {
- scope.AddEvent(data);
- }
- }
- });
-
- scope.Send();
-
- entry.eventBuffer.Clear(false);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpTags(EventStorage& entry, ScopeData& scope)
-{
- if (!entry.tagFloatBuffer.IsEmpty() ||
- !entry.tagS32Buffer.IsEmpty() ||
- !entry.tagU32Buffer.IsEmpty() ||
- !entry.tagU64Buffer.IsEmpty() ||
- !entry.tagPointBuffer.IsEmpty() ||
- !entry.tagStringBuffer.IsEmpty())
- {
- OutputDataStream tagStream;
- tagStream << scope.header.boardNumber << scope.header.threadNumber;
- tagStream
- << (uint32)0
- << entry.tagFloatBuffer
- << entry.tagU32Buffer
- << entry.tagS32Buffer
- << entry.tagU64Buffer
- << entry.tagPointBuffer
- << (uint32)0
- << (uint32)0
- << entry.tagStringBuffer;
- Server::Get().Send(DataResponse::TagsPack, tagStream);
-
- entry.ClearTags(false);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpThread(ThreadEntry& entry, const EventTime& timeSlice, ScopeData& scope)
-{
- // We need to sort events for all the custom thread storages
- if (entry.description.threadID == INVALID_THREAD_ID)
- entry.Sort();
-
- // Events
- DumpEvents(entry.storage, timeSlice, scope);
- DumpTags(entry.storage, scope);
- OPTICK_ASSERT(entry.storage.fiberSyncBuffer.IsEmpty(), "Fiber switch events in native threads?");
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpFiber(FiberEntry& entry, const EventTime& timeSlice, ScopeData& scope)
-{
- // Events
- DumpEvents(entry.storage, timeSlice, scope);
-
- if (!entry.storage.fiberSyncBuffer.IsEmpty())
- {
- OutputDataStream fiberSynchronizationStream;
- fiberSynchronizationStream << scope.header.boardNumber;
- fiberSynchronizationStream << scope.header.fiberNumber;
- fiberSynchronizationStream << entry.storage.fiberSyncBuffer;
- Server::Get().Send(DataResponse::FiberSynchronizationData, fiberSynchronizationStream);
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventTime CalculateRange(const ThreadEntry& entry, const EventDescription* rootDescription)
-{
- EventTime timeSlice = { INT64_MAX, INT64_MIN };
- entry.storage.eventBuffer.ForEach([&](const EventData& data)
- {
- if (data.description == rootDescription)
- {
- timeSlice.start = std::min(timeSlice.start, data.start);
- timeSlice.finish = std::max(timeSlice.finish, data.finish);
- }
- });
- return timeSlice;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpFrames(uint32 mode)
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- if (frames.empty() || threads.empty())
- return;
-
- ++boardNumber;
-
- DumpProgress("Generating summary...");
-
- GenerateCommonSummary();
- DumpSummary();
-
- DumpProgress("Collecting Frame Events...");
-
-
- ThreadID mainThreadID = Platform::GetThreadID();
- uint32 mainThreadIndex = 0;
- for (size_t i = 0; i < threads.size(); ++i)
- if (threads[i]->description.threadID == mainThreadID)
- mainThreadIndex = (uint32)i;
-
- EventTime timeSlice = CalculateRange(*threads[mainThreadIndex], GetFrameDescription(FrameType::CPU));
- if (timeSlice.start >= timeSlice.finish)
- {
- timeSlice.start = frames.front().start;
- timeSlice.finish = frames.back().finish;
- }
-
- DumpBoard(mode, timeSlice, mainThreadIndex);
-
- ScopeData threadScope;
- threadScope.header.boardNumber = boardNumber;
- threadScope.header.fiberNumber = -1;
-
- if (gpuProfiler)
- gpuProfiler->Dump(mode);
-
- for (size_t i = 0; i < threads.size(); ++i)
- {
- threadScope.header.threadNumber = (uint32)i;
- DumpThread(*threads[i], timeSlice, threadScope);
- }
-
- ScopeData fiberScope;
- fiberScope.header.boardNumber = (uint32)boardNumber;
- fiberScope.header.threadNumber = -1;
- for (size_t i = 0; i < fibers.size(); ++i)
- {
- fiberScope.header.fiberNumber = (uint32)i;
- DumpFiber(*fibers[i], timeSlice, fiberScope);
- }
-
- frames.clear();
- CleanupThreadsAndFibers();
-
- {
- DumpProgress("Serializing SwitchContexts");
- OutputDataStream switchContextsStream;
- switchContextsStream << boardNumber;
- switchContextCollector.Serialize(switchContextsStream);
- Server::Get().Send(DataResponse::SynchronizationData, switchContextsStream);
- }
-
- {
- DumpProgress("Serializing SysCalls");
- OutputDataStream callstacksStream;
- callstacksStream << boardNumber;
- syscallCollector.Serialize(callstacksStream);
- Server::Get().Send(DataResponse::SyscallPack, callstacksStream);
- }
-
- if (!callstackCollector.IsEmpty())
- {
- DumpProgress("Resolving callstacks");
- OutputDataStream symbolsStream;
- symbolsStream << boardNumber;
- callstackCollector.SerializeModules(symbolsStream);
- callstackCollector.SerializeSymbols(symbolsStream);
- Server::Get().Send(DataResponse::CallstackDescriptionBoard, symbolsStream);
-
- DumpProgress("Serializing callstacks");
- OutputDataStream callstacksStream;
- callstacksStream << boardNumber;
- callstackCollector.SerializeCallstacks(callstacksStream);
- Server::Get().Send(DataResponse::CallstackPack, callstacksStream);
- }
-
- Server::Get().Send(DataResponse::NullFrame, OutputDataStream::Empty);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpSummary()
-{
- OutputDataStream stream;
-
- // Board Number
- stream << boardNumber;
-
- // Frames
- double frequency = (double)Platform::GetFrequency();
- stream << (uint32_t)frames.size();
- for (const EventTime& frame : frames)
- {
- double frameTimeMs = 1000.0 * (frame.finish - frame.start) / frequency;
- stream << (float)frameTimeMs;
- }
-
- // Summary
- stream << (uint32_t)summary.size();
- for (size_t i = 0; i < summary.size(); ++i)
- stream << summary[i].first << summary[i].second;
- summary.clear();
-
- // Attachments
- stream << (uint32_t)attachments.size();
- for (const Attachment& att : attachments)
- stream << (uint32_t)att.type << att.name << att.data;
- attachments.clear();
-
- // Send
- Server::Get().Send(DataResponse::SummaryPack, stream);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::CleanupThreadsAndFibers()
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- for (ThreadList::iterator it = threads.begin(); it != threads.end();)
- {
- if (!(*it)->isAlive)
- {
- Memory::Delete(*it);
- it = threads.erase(it);
- }
- else
- {
- ++it;
- }
- }
-}
-
-void Core::DumpBoard(uint32 mode, EventTime timeSlice, uint32 mainThreadIndex)
-{
- OutputDataStream boardStream;
-
- boardStream << boardNumber;
- boardStream << Platform::GetFrequency();
- boardStream << (uint64)0; // Origin
- boardStream << (uint32)0; // Precision
- boardStream << timeSlice;
- boardStream << threads;
- boardStream << fibers;
- boardStream << mainThreadIndex;
- boardStream << EventDescriptionBoard::Get();
- boardStream << (uint32)0; // Tags
- boardStream << (uint32)0; // Run
- boardStream << (uint32)0; // Filters
- boardStream << (uint32)0; // ThreadDescs
- boardStream << mode; // Mode
- boardStream << processDescs;
- boardStream << threadDescs;
- boardStream << (uint32)Platform::GetProcessID();
- boardStream << (uint32)std::thread::hardware_concurrency();
- Server::Get().Send(DataResponse::FrameDescriptionBoard, boardStream);
-
- // Cleanup
- processDescs.clear();
- threadDescs.clear();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::GenerateCommonSummary()
-{
- AttachSummary("Platform", Platform::GetName());
- AttachSummary("CPU", GetCPUName().c_str());
- if (gpuProfiler)
- AttachSummary("GPU", gpuProfiler->GetName().c_str());
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Core::Core()
- : progressReportedLastTimestampMS(0)
- , boardNumber(0)
- , frameNumber(0)
- , stateCallback(nullptr)
- , currentState(State::DUMP_CAPTURE)
- , pendingState(State::DUMP_CAPTURE)
- , currentMode(Mode::OFF)
- , symbolEngine(nullptr)
- , tracer(nullptr)
- , gpuProfiler(nullptr)
-{
-#if OPTICK_ENABLE_TRACING
- tracer = Platform::GetTrace();
- symbolEngine = Platform::GetSymbolEngine();
-#endif
-
- frameDescriptions[FrameType::CPU] = EventDescription::Create("CPU Frame", __FILE__, __LINE__);
- frameDescriptions[FrameType::GPU] = EventDescription::Create("GPU Frame", __FILE__, __LINE__);
- frameDescriptions[FrameType::Render] = EventDescription::Create("Render Frame", __FILE__, __LINE__);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::UpdateState()
-{
- if (currentState != pendingState)
- {
- State::Type nextState = pendingState;
- if (pendingState == State::DUMP_CAPTURE && currentState == State::START_CAPTURE)
- nextState = State::STOP_CAPTURE;
-
- if ((stateCallback != nullptr) && !stateCallback(nextState))
- return false;
-
- switch (nextState)
- {
- case State::START_CAPTURE:
- Activate((Mode::Type)settings.mode);
- break;
-
- case State::STOP_CAPTURE:
- case State::CANCEL_CAPTURE:
- Activate(Mode::OFF);
- break;
-
- case State::DUMP_CAPTURE:
- DumpFrames();
- break;
- }
- currentState = nextState;
- return true;
- }
- return false;
-}
-
-
-uint32_t Core::Update()
-{
- std::lock_guard<std::recursive_mutex> lock(coreLock);
-
- if (currentMode != Mode::OFF)
- {
- if (!frames.empty())
- frames.back().Stop();
-
- if (settings.frameLimit > 0 && frames.size() >= settings.frameLimit)
- DumpCapture();
-
- if (settings.timeLimitUs > 0)
- {
- if (TicksToUs(frames.back().finish - frames.front().start) >= settings.timeLimitUs)
- DumpCapture();
- }
-
- if (settings.spikeLimitUs > 0)
- {
- if (TicksToUs(frames.back().finish - frames.back().start) >= settings.spikeLimitUs)
- DumpCapture();
- }
-
- if (IsTimeToReportProgress())
- DumpCapturingProgress();
- }
-
- UpdateEvents();
-
- while (UpdateState()) {}
-
- if (currentMode != Mode::OFF)
- {
- frames.push_back(EventTime());
- frames.back().Start();
- }
-
- return ++frameNumber;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::UpdateEvents()
-{
- Server::Get().Update();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::ReportSwitchContext(const SwitchContextDesc& desc)
-{
- switchContextCollector.Add(desc);
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::ReportStackWalk(const CallstackDesc& desc)
-{
- callstackCollector.Add(desc);
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::Activate(Mode::Type mode)
-{
- if (mode != currentMode)
- {
- Mode::Type prevMode = currentMode;
- currentMode = mode;
-
- {
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
- for(auto it = threads.begin(); it != threads.end(); ++it)
- {
- ThreadEntry* entry = *it;
- entry->Activate(mode);
- }
- }
-
-
- if (mode != Mode::OFF)
- {
- CaptureStatus::Type status = CaptureStatus::ERR_TRACER_FAILED;
-
- if (tracer && (mode & Mode::TRACER))
- {
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
- tracer->SetPassword(settings.password.c_str());
- status = tracer->Start(mode, settings.samplingFrequency, threads);
- // Let's retry with more narrow setup
- if (status != CaptureStatus::OK && (mode & Mode::AUTOSAMPLING))
- status = tracer->Start((Mode::Type)(mode & ~Mode::AUTOSAMPLING), settings.samplingFrequency, threads);
- }
-
- if (gpuProfiler && (mode & Mode::GPU))
- gpuProfiler->Start(mode);
-
- SendHandshakeResponse(status);
- }
- else
- {
- if (tracer)
- tracer->Stop();
-
- if (gpuProfiler)
- gpuProfiler->Stop(prevMode);
- }
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpCapturingProgress()
-{
- stringstream stream;
-
- if (currentMode != Mode::OFF)
- {
- size_t memUsedKb = Memory::GetAllocatedSize() >> 10;
- float memUsedMb = memUsedKb / 1024.0f;
- // VS TODO: Format to 3 digits
- stream << "Capturing Frame " << (uint32)frames.size() << "..." << std::endl << "Memory Used: " << memUsedMb << " Mb";
- }
-
- DumpProgress(stream.str().c_str());
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::IsTimeToReportProgress() const
-{
- return GetTimeMilliSeconds() > progressReportedLastTimestampMS + 200;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::SendHandshakeResponse(CaptureStatus::Type status)
-{
- OutputDataStream stream;
- stream << (uint32)status;
- stream << Platform::GetName();
- stream << Server::Get().GetHostName();
- Server::Get().Send(DataResponse::Handshake, stream);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::IsRegistredThread(ThreadID id)
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- for (ThreadList::iterator it = threads.begin(); it != threads.end(); ++it)
- {
- ThreadEntry* entry = *it;
- if (entry->description.threadID == id)
- {
- return true;
- }
- }
- return false;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ThreadEntry* Core::RegisterThread(const ThreadDescription& description, EventStorage** slot)
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- ThreadEntry* entry = Memory::New<ThreadEntry>(description, slot);
- threads.push_back(entry);
-
- if ((currentMode != Mode::OFF) && slot != nullptr)
- *slot = &entry->storage;
-
- return entry;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::UnRegisterThread(ThreadID threadID, bool keepAlive)
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- for (ThreadList::iterator it = threads.begin(); it != threads.end(); ++it)
- {
- ThreadEntry* entry = *it;
- if (entry->description.threadID == threadID && entry->isAlive)
- {
- if ((currentMode == Mode::OFF) && !keepAlive)
- {
- Memory::Delete(entry);
- threads.erase(it);
- return true;
- }
- else
- {
- entry->isAlive = false;
- return true;
- }
- }
- }
-
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::RegisterFiber(const FiberDescription& description, EventStorage** slot)
-{
- std::lock_guard<std::recursive_mutex> lock(coreLock);
- FiberEntry* entry = Memory::New<FiberEntry>(description);
- fibers.push_back(entry);
- entry->storage.isFiberStorage = true;
- *slot = &entry->storage;
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::RegisterProcessDescription(const ProcessDescription& description)
-{
- processDescs.push_back(description);
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::RegisterThreadDescription(const ThreadDescription& description)
-{
- threadDescs.push_back(description);
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::SetStateChangedCallback(StateCallback cb)
-{
- stateCallback = cb;
- return stateCallback != nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachSummary(const char* key, const char* value)
-{
- summary.push_back(make_pair(string(key), string(value)));
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachFile(File::Type type, const char* name, const uint8_t* data, uint32_t size)
-{
- if (size > 0)
- {
- attachments.push_back(Attachment(type, name));
- Attachment& attachment = attachments.back();
- attachment.data.resize(size);
- memcpy(&attachment.data[0], data, size);
- return true;
- }
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachFile(File::Type type, const char* name, std::istream& stream)
-{
- std::streampos beg = stream.tellg();
- stream.seekg(0, std::ios::end);
- std::streampos end = stream.tellg();
- stream.seekg(beg, std::ios::beg);
-
- size_t size =(size_t)(end - beg);
- void* buffer = Memory::Alloc(size);
-
- stream.read((char*)buffer, size);
- bool result = AttachFile(type, name, (uint8*)buffer, (uint32_t)size);
-
- Memory::Free(buffer);
- return result;
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachFile(File::Type type, const char* name, const char* path)
-{
- std::ifstream stream(path, std::ios::binary);
- return AttachFile(type, name, stream);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachFile(File::Type type, const char* name, const wchar_t* path)
-{
-#if defined(OPTICK_MSVC)
- std::ifstream stream(path, std::ios::binary);
- return AttachFile(type, name, stream);
-#else
- char p[256] = { 0 };
- wcstombs(p, path, sizeof(p));
- std::ifstream stream(p, std::ios::binary);
- return AttachFile(type, name, stream);
-#endif
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::InitGPUProfiler(GPUProfiler* profiler)
-{
- OPTICK_ASSERT(gpuProfiler == nullptr, "Can't reinitialize GPU profiler! Not supported yet!");
- Memory::Delete<GPUProfiler>(gpuProfiler);
- gpuProfiler = profiler;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::SetSettings(const CaptureSettings& captureSettings)
-{
- settings = captureSettings;
-
- //if (tracer)
- //{
- // string decoded = base64_decode(encodedPassword);
- // tracer->SetPassword(decoded.c_str());
- // return true;
- //}
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const EventDescription* Core::GetFrameDescription(FrameType::Type frame) const
-{
- return frameDescriptions[frame];
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Core::~Core()
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- for (ThreadList::iterator it = threads.begin(); it != threads.end(); ++it)
- {
- Memory::Delete(*it);
- }
- threads.clear();
-
- for (FiberList::iterator it = fibers.begin(); it != fibers.end(); ++it)
- {
- Memory::Delete(*it);
- }
- fibers.clear();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const vector<ThreadEntry*>& Core::GetThreads() const
-{
- return threads;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_THREAD_LOCAL EventStorage* Core::storage = nullptr;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ScopeHeader::ScopeHeader() : boardNumber(0), threadNumber(0)
-{
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ScopeHeader& header)
-{
- return stream << header.boardNumber << header.threadNumber << header.fiberNumber << header.event;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ScopeData& ob)
-{
- return stream << ob.header << ob.categories << ob.events;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ThreadDescription& description)
-{
- return stream << description.threadID << description.processID << description.name << description.maxDepth << description.priority << description.mask;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ThreadEntry* entry)
-{
- return stream << entry->description;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const FiberDescription& description)
-{
- return stream << description.id;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const FiberEntry* entry)
-{
- return stream << entry->description;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ProcessDescription& description)
-{
- return stream << description.processID << description.name << description.uniqueKey;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool SetStateChangedCallback(StateCallback cb)
-{
- return Core::Get().SetStateChangedCallback(cb);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool AttachSummary(const char* key, const char* value)
-{
- return Core::Get().AttachSummary(key, value);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool AttachFile(File::Type type, const char* name, const uint8_t* data, uint32_t size)
-{
- return Core::Get().AttachFile(type, name, data, size);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool AttachFile(File::Type type, const char* name, const char* path)
-{
- return Core::Get().AttachFile(type, name, path);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool AttachFile(File::Type type, const char* name, const wchar_t* path)
-{
- return Core::Get().AttachFile(type, name, path);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const Point& ob)
-{
- return stream << ob.x << ob.y << ob.z;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API uint32_t NextFrame()
-{
- return Core::NextFrame();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool IsActive(Mode::Type mode /*= Mode::INSTRUMENTATION_EVENTS*/)
-{
- return (Core::Get().currentMode & mode) != 0;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API EventStorage** GetEventStorageSlotForCurrentThread()
-{
- return &Core::Get().storage;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool IsFiberStorage(EventStorage* fiberStorage)
-{
- return fiberStorage->isFiberStorage;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool RegisterThread(const char* name)
-{
- return Core::Get().RegisterThread(ThreadDescription(name, Platform::GetThreadID(), Platform::GetProcessID()), &Core::storage) != nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool RegisterThread(const wchar_t* name)
-{
- const int THREAD_NAME_LENGTH = 128;
- char mbName[THREAD_NAME_LENGTH];
- wcstombs_s(mbName, name, THREAD_NAME_LENGTH);
-
- return Core::Get().RegisterThread(ThreadDescription(mbName, Platform::GetThreadID(), Platform::GetProcessID()), &Core::storage) != nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool UnRegisterThread(bool keepAlive)
-{
- return Core::Get().UnRegisterThread(Platform::GetThreadID(), keepAlive);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool RegisterFiber(uint64 fiberId, EventStorage** slot)
-{
- return Core::Get().RegisterFiber(FiberDescription(fiberId), slot);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API EventStorage* RegisterStorage(const char* name, uint64_t threadID, ThreadMask::Type type)
-{
- ThreadEntry* entry = Core::Get().RegisterThread(ThreadDescription(name, threadID, Platform::GetProcessID(), 1, 0, type), nullptr);
- return entry ? &entry->storage : nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API void GpuFlip(void* swapChain)
-{
- if (GPUProfiler* gpuProfiler = Core::Get().gpuProfiler)
- gpuProfiler->Flip(swapChain);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API GPUContext SetGpuContext(GPUContext context)
-{
- if (EventStorage* storage = Core::storage)
- {
- GPUContext prevContext = storage->gpuStorage.context;
- storage->gpuStorage.context = context;
- return prevContext;
- }
- return GPUContext();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API const EventDescription* GetFrameDescription(FrameType::Type frame)
-{
- return Core::Get().GetFrameDescription(frame);
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventStorage::EventStorage(): currentMode(Mode::OFF), pushPopEventStackIndex(0), isFiberStorage(false)
-{
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ThreadEntry::Activate(Mode::Type mode)
-{
- if (!isAlive)
- return;
-
- if (mode != Mode::OFF)
- storage.Clear(true);
-
- if (threadTLS != nullptr)
- {
- storage.currentMode = mode;
- *threadTLS = mode != Mode::OFF ? &storage : nullptr;
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ThreadEntry::Sort()
-{
- SortMemoryPool(storage.eventBuffer);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool IsSleepOnlyScope(const ScopeData& scope)
-{
- //if (!scope.categories.empty())
- // return false;
-
- const vector<EventData>& events = scope.events;
- for(auto it = events.begin(); it != events.end(); ++it)
- {
- const EventData& data = *it;
-
- if (data.description->color != Color::White)
- {
- return false;
- }
- }
-
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ScopeData::Send()
-{
- if (!events.empty() || !categories.empty())
- {
- if (!IsSleepOnlyScope(*this))
- {
- OutputDataStream frameStream;
- frameStream << *this;
- Server::Get().Send(DataResponse::EventFrame, frameStream);
- }
- }
-
- Clear();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ScopeData::Clear()
-{
- events.clear();
- categories.clear();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void EventStorage::GPUStorage::Clear(bool preserveMemory)
-{
- for (size_t i = 0; i < gpuBuffer.size(); ++i)
- for (int j = 0; j < GPU_QUEUE_COUNT; ++j)
- gpuBuffer[i][j].Clear(preserveMemory);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventData* EventStorage::GPUStorage::Start(const EventDescription &desc)
-{
- if (GPUProfiler* gpuProfiler = Core::Get().gpuProfiler)
- {
- EventData& result = gpuBuffer[context.node][context.queue].Add();
- result.description = &desc;
- result.start = EventTime::INVALID_TIMESTAMP;
- result.finish = EventTime::INVALID_TIMESTAMP;
- gpuProfiler->QueryTimestamp(context.cmdBuffer, &result.start);
- return &result;
- }
- return nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void EventStorage::GPUStorage::Stop(EventData& data)
-{
- if (GPUProfiler* gpuProfiler = Core::Get().gpuProfiler)
- {
- gpuProfiler->QueryTimestamp(context.cmdBuffer, &data.finish);
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-#endif //USE_OPTICK \ No newline at end of file