Serialize lock processing.

This makes is much easier to process on the server and opens new
optimization possibilities. It also fixes theoretical problems, which
may be caused by invalid ordering of events with the same timestamp.
This commit is contained in:
Bartosz Taudul 2019-08-12 13:51:01 +02:00
parent 0431c03556
commit d6f32a0839
4 changed files with 63 additions and 86 deletions

View File

@ -80,29 +80,27 @@ public:
return;
}
#endif
const auto thread = GetThreadHandle();
{
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockWait );
MemWrite( &item->lockWait.thread, thread );
MemWrite( &item->lockWait.id, m_id );
MemWrite( &item->lockWait.time, Profiler::GetTime() );
MemWrite( &item->lockWait.type, LockType::Lockable );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
m_lockable.lock();
{
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockObtain );
MemWrite( &item->lockObtain.thread, thread );
MemWrite( &item->lockObtain.id, m_id );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
}
@ -120,14 +118,12 @@ public:
}
#endif
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockRelease );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
tracy_force_inline bool try_lock()
@ -151,14 +147,12 @@ public:
if( ret )
{
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockObtain );
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
MemWrite( &item->lockObtain.id, m_id );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
return ret;
@ -177,14 +171,12 @@ public:
}
#endif
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockMark );
MemWrite( &item->lockMark.thread, GetThreadHandle() );
MemWrite( &item->lockMark.id, m_id );
MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
private:
@ -267,29 +259,27 @@ public:
return;
}
#endif
const auto thread = GetThreadHandle();
{
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockWait );
MemWrite( &item->lockWait.thread, thread );
MemWrite( &item->lockWait.id, m_id );
MemWrite( &item->lockWait.time, Profiler::GetTime() );
MemWrite( &item->lockWait.type, LockType::SharedLockable );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
m_lockable.lock();
{
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockObtain );
MemWrite( &item->lockObtain.thread, thread );
MemWrite( &item->lockObtain.id, m_id );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
}
@ -307,14 +297,12 @@ public:
}
#endif
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockRelease );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
tracy_force_inline bool try_lock()
@ -338,14 +326,12 @@ public:
if( ret )
{
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockObtain );
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
MemWrite( &item->lockObtain.id, m_id );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
return ret;
@ -369,29 +355,27 @@ public:
return;
}
#endif
const auto thread = GetThreadHandle();
{
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockSharedWait );
MemWrite( &item->lockWait.thread, thread );
MemWrite( &item->lockWait.id, m_id );
MemWrite( &item->lockWait.time, Profiler::GetTime() );
MemWrite( &item->lockWait.type, LockType::SharedLockable );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
m_lockable.lock_shared();
{
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
MemWrite( &item->lockObtain.thread, thread );
MemWrite( &item->lockObtain.id, m_id );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
}
@ -409,14 +393,12 @@ public:
}
#endif
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockSharedRelease );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
tracy_force_inline bool try_lock_shared()
@ -440,14 +422,12 @@ public:
if( ret )
{
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
MemWrite( &item->lockObtain.id, m_id );
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
return ret;
@ -466,14 +446,12 @@ public:
}
#endif
Magic magic;
auto token = GetToken();
auto& tail = token->get_tail_index();
auto item = token->enqueue_begin( magic );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockMark );
MemWrite( &item->lockMark.thread, GetThreadHandle() );
MemWrite( &item->lockMark.id, m_id );
MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc );
tail.store( magic + 1, std::memory_order_release );
Profiler::QueueSerialFinish();
}
private:

View File

@ -9,7 +9,7 @@
namespace tracy
{
enum : uint32_t { ProtocolVersion = 14 };
enum : uint32_t { ProtocolVersion = 15 };
enum : uint32_t { BroadcastVersion = 0 };
using lz4sz_t = uint32_t;

View File

@ -152,6 +152,7 @@ struct QueueLockTerminate
struct QueueLockWait
{
uint64_t thread;
uint32_t id;
int64_t time;
LockType type;
@ -159,18 +160,21 @@ struct QueueLockWait
struct QueueLockObtain
{
uint64_t thread;
uint32_t id;
int64_t time;
};
struct QueueLockRelease
{
uint64_t thread;
uint32_t id;
int64_t time;
};
struct QueueLockMark
{
uint64_t thread;
uint32_t id;
uint64_t srcloc; // ptr
};

View File

@ -2064,16 +2064,11 @@ void Worker::InsertLockEvent( LockMap& lockmap, LockEvent* lev, uint64_t thread
timeline.push_back( { lev } );
UpdateLockCount( lockmap, timeline.size() - 1 );
}
else if( timeline.back().ptr->time <= lt )
{
timeline.push_back_non_empty( { lev } );
UpdateLockCount( lockmap, timeline.size() - 1 );
}
else
{
auto it = std::upper_bound( timeline.begin(), timeline.end(), lt, [] ( const auto& lhs, const auto& rhs ) { return lhs < rhs.ptr->time; } );
it = timeline.insert( it, { lev } );
UpdateLockCount( lockmap, std::distance( timeline.begin(), it ) );
assert( timeline.back().ptr->time <= lt );
timeline.push_back_non_empty( { lev } );
UpdateLockCount( lockmap, timeline.size() - 1 );
}
auto& range = lockmap.range[it->second];
@ -3040,7 +3035,7 @@ void Worker::ProcessLockWait( const QueueLockWait& ev )
lev->type = LockEvent::Type::Wait;
lev->srcloc = 0;
InsertLockEvent( *it->second, lev, m_threadCtx );
InsertLockEvent( *it->second, lev, ev.thread );
}
void Worker::ProcessLockObtain( const QueueLockObtain& ev )
@ -3054,7 +3049,7 @@ void Worker::ProcessLockObtain( const QueueLockObtain& ev )
lev->type = LockEvent::Type::Obtain;
lev->srcloc = 0;
InsertLockEvent( lock, lev, m_threadCtx );
InsertLockEvent( lock, lev, ev.thread );
}
void Worker::ProcessLockRelease( const QueueLockRelease& ev )
@ -3068,7 +3063,7 @@ void Worker::ProcessLockRelease( const QueueLockRelease& ev )
lev->type = LockEvent::Type::Release;
lev->srcloc = 0;
InsertLockEvent( lock, lev, m_threadCtx );
InsertLockEvent( lock, lev, ev.thread );
}
void Worker::ProcessLockSharedWait( const QueueLockWait& ev )
@ -3089,7 +3084,7 @@ void Worker::ProcessLockSharedWait( const QueueLockWait& ev )
lev->type = LockEvent::Type::WaitShared;
lev->srcloc = 0;
InsertLockEvent( *it->second, lev, m_threadCtx );
InsertLockEvent( *it->second, lev, ev.thread );
}
void Worker::ProcessLockSharedObtain( const QueueLockObtain& ev )
@ -3104,7 +3099,7 @@ void Worker::ProcessLockSharedObtain( const QueueLockObtain& ev )
lev->type = LockEvent::Type::ObtainShared;
lev->srcloc = 0;
InsertLockEvent( lock, lev, m_threadCtx );
InsertLockEvent( lock, lev, ev.thread );
}
void Worker::ProcessLockSharedRelease( const QueueLockRelease& ev )
@ -3119,7 +3114,7 @@ void Worker::ProcessLockSharedRelease( const QueueLockRelease& ev )
lev->type = LockEvent::Type::ReleaseShared;
lev->srcloc = 0;
InsertLockEvent( lock, lev, m_threadCtx );
InsertLockEvent( lock, lev, ev.thread );
}
void Worker::ProcessLockMark( const QueueLockMark& ev )
@ -3128,7 +3123,7 @@ void Worker::ProcessLockMark( const QueueLockMark& ev )
auto lit = m_data.lockMap.find( ev.id );
assert( lit != m_data.lockMap.end() );
auto& lockmap = *lit->second;
auto tid = lockmap.threadMap.find( m_threadCtx );
auto tid = lockmap.threadMap.find( ev.thread );
assert( tid != lockmap.threadMap.end() );
const auto thread = tid->second;
auto it = lockmap.timeline.end();