1
0
mirror of https://github.com/wolfpld/tracy.git synced 2025-03-20 07:40:02 +08:00

Harden client code against unaligned memory access.

There shouldn't be any changes in generated code on modern
architectures, as the memcpy will be reduced to a store/load operation
identical to the one generated with plain struct member access.

GetTime( cpu ) needs special handling, as the MSVC intrinsic for rdtscp
can't store cpu identifier in a register. Using intermediate variable
would cause store to stack, read from stack, store to the destination
address. Since rdtscp is only available on x86, which handles unaligned
stores without any problems, we can have one place with direct struct
member access.
This commit is contained in:
Bartosz Taudul
2018-03-31 14:03:55 +02:00
parent 685432a85f
commit 3b03e849f0
7 changed files with 247 additions and 186 deletions
+68 -67
View File
@@ -5,6 +5,7 @@
#include <limits>
#include "../common/TracySystem.hpp"
#include "../common/TracyAlign.hpp"
#include "TracyProfiler.hpp"
namespace tracy
@@ -25,10 +26,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockAnnounce;
item->lockAnnounce.id = m_id;
item->lockAnnounce.lckloc = (uint64_t)srcloc;
item->lockAnnounce.type = LockType::Lockable;
MemWrite( &item->hdr.type, QueueType::LockAnnounce );
MemWrite( &item->lockAnnounce.id, m_id );
MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc );
MemWrite( &item->lockAnnounce.type, LockType::Lockable );
tail.store( magic + 1, std::memory_order_release );
}
@@ -43,11 +44,11 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockWait;
item->lockWait.id = m_id;
item->lockWait.thread = thread;
item->lockWait.time = Profiler::GetTime();
item->lockWait.type = LockType::Lockable;
MemWrite( &item->hdr.type, QueueType::LockWait );
MemWrite( &item->lockWait.id, m_id );
MemWrite( &item->lockWait.thread, thread );
MemWrite( &item->lockWait.time, Profiler::GetTime() );
MemWrite( &item->lockWait.type, LockType::Lockable );
tail.store( magic + 1, std::memory_order_release );
}
@@ -58,10 +59,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockObtain;
item->lockObtain.id = m_id;
item->lockObtain.thread = thread;
item->lockObtain.time = Profiler::GetTime();
MemWrite( &item->hdr.type, QueueType::LockObtain );
MemWrite( &item->lockObtain.id, m_id );
MemWrite( &item->lockObtain.thread, thread );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
}
}
@@ -74,10 +75,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockRelease;
item->lockRelease.id = m_id;
item->lockRelease.thread = GetThreadHandle();
item->lockRelease.time = Profiler::GetTime();
MemWrite( &item->hdr.type, QueueType::LockRelease );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
}
@@ -90,10 +91,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockObtain;
item->lockObtain.id = (uint64_t)&m_lockable;
item->lockObtain.thread = GetThreadHandle();
item->lockObtain.time = Profiler::GetTime();
MemWrite( &item->hdr.type, QueueType::LockObtain );
MemWrite( &item->lockObtain.id, (uint64_t)&m_lockable );
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
}
return ret;
@@ -105,10 +106,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockMark;
item->lockMark.id = m_id;
item->lockMark.thread = GetThreadHandle();
item->lockMark.srcloc = (uint64_t)srcloc;
MemWrite( &item->hdr.type, QueueType::LockMark );
MemWrite( &item->lockMark.id, m_id );
MemWrite( &item->lockMark.thread, GetThreadHandle() );
MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc );
tail.store( magic + 1, std::memory_order_release );
}
@@ -131,10 +132,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockAnnounce;
item->lockAnnounce.id = m_id;
item->lockAnnounce.lckloc = (uint64_t)srcloc;
item->lockAnnounce.type = LockType::SharedLockable;
MemWrite( &item->hdr.type, QueueType::LockAnnounce );
MemWrite( &item->lockAnnounce.id, m_id );
MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc );
MemWrite( &item->lockAnnounce.type, LockType::SharedLockable );
tail.store( magic + 1, std::memory_order_release );
}
@@ -149,11 +150,11 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockWait;
item->lockWait.id = m_id;
item->lockWait.thread = thread;
item->lockWait.time = Profiler::GetTime();
item->lockWait.type = LockType::SharedLockable;
MemWrite( &item->hdr.type, QueueType::LockWait );
MemWrite( &item->lockWait.id, m_id );
MemWrite( &item->lockWait.thread, thread );
MemWrite( &item->lockWait.time, Profiler::GetTime() );
MemWrite( &item->lockWait.type, LockType::SharedLockable );
tail.store( magic + 1, std::memory_order_release );
}
@@ -164,10 +165,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockObtain;
item->lockObtain.id = m_id;
item->lockObtain.thread = thread;
item->lockObtain.time = Profiler::GetTime();
MemWrite( &item->hdr.type, QueueType::LockObtain );
MemWrite( &item->lockObtain.id, m_id );
MemWrite( &item->lockObtain.thread, thread );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
}
}
@@ -180,10 +181,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockRelease;
item->lockRelease.id = m_id;
item->lockRelease.thread = GetThreadHandle();
item->lockRelease.time = Profiler::GetTime();
MemWrite( &item->hdr.type = QueueType::LockRelease );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
}
@@ -196,10 +197,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockObtain;
item->lockObtain.id = (uint64_t)&m_lockable;
item->lockObtain.thread = GetThreadHandle();
item->lockObtain.time = Profiler::GetTime();
MemWrite( &item->hdr.type, QueueType::LockObtain );
MemWrite( &item->lockObtain.id, (uint64_t)&m_lockable );
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
}
return ret;
@@ -213,11 +214,11 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockSharedWait;
item->lockWait.id = m_id;
item->lockWait.thread = thread;
item->lockWait.time = Profiler::GetTime();
item->lockWait.type = LockType::SharedLockable;
MemWrite( &item->hdr.type, QueueType::LockSharedWait );
MemWrite( &item->lockWait.id, m_id );
MemWrite( &item->lockWait.thread, thread );
MemWrite( &item->lockWait.time, Profiler::GetTime() );
MemWrite( &item->lockWait.type, LockType::SharedLockable );
tail.store( magic + 1, std::memory_order_release );
}
@@ -228,10 +229,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockSharedObtain;
item->lockObtain.id = m_id;
item->lockObtain.thread = thread;
item->lockObtain.time = Profiler::GetTime();
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
MemWrite( &item->lockObtain.id, m_id );
MemWrite( &item->lockObtain.thread, thread );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
}
}
@@ -244,10 +245,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockSharedRelease;
item->lockRelease.id = m_id;
item->lockRelease.thread = GetThreadHandle();
item->lockRelease.time = Profiler::GetTime();
MemWrite( &item->hdr.type, QueueType::LockSharedRelease );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
}
@@ -260,10 +261,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockSharedObtain;
item->lockObtain.id = (uint64_t)&m_lockable;
item->lockObtain.thread = GetThreadHandle();
item->lockObtain.time = Profiler::GetTime();
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
MemWrite( &item->lockObtain.id, (uint64_t)&m_lockable );
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
}
return ret;
@@ -275,10 +276,10 @@ public:
auto& token = s_token.ptr;
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin<moodycamel::CanAlloc>( magic );
item->hdr.type = QueueType::LockMark;
item->lockMark.id = m_id;
item->lockMark.thread = GetThreadHandle();
item->lockMark.srcloc = (uint64_t)srcloc;
MemWrite( &item->hdr.type, QueueType::LockMark );
MemWrite( &item->lockMark.id, m_id );
MemWrite( &item->lockMark.thread, GetThreadHandle() );
MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc );
tail.store( magic + 1, std::memory_order_release );
}