forked from qt-creator/qt-creator
Nanotrace: Refactore event queue - replace std::mutex with a spinlock
The event queue was previously stored in thread-local storage, which led to complications when the associated thread became invalid or was no longer active. In such cases, attempts to acquire a std::mutex lock failed silently, likely due to the mutex being tied to a thread context that no longer existed or was in an undefined state. To address this, we replaced the std::mutex with a spinlock (std::atomic_flag-based). Spinlocks are not dependent on thread ownership semantics and provide a lightweight alternative for short critical sections, especially in scenarios where thread-local state may be unreliable or transient. This change ensures more robust and predictable locking behavior in multi-threaded environments where thread-local resources may be deallocated or invalidated unexpectedly. Change-Id: Ife360c09a803c77dfd39b3f49ba89c57ad5bb856 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -396,9 +396,24 @@ inline bool operator&(IsFlow first, IsFlow second)
|
||||
struct TraceEventWithoutArguments;
|
||||
struct TraceEventWithArguments;
|
||||
|
||||
class SpinLock
|
||||
{
|
||||
public:
|
||||
void lock()
|
||||
{
|
||||
while (flag.test_and_set(std::memory_order_acquire)) {
|
||||
}
|
||||
}
|
||||
|
||||
void unlock() { flag.clear(std::memory_order_release); }
|
||||
|
||||
private:
|
||||
std::atomic_flag flag;
|
||||
};
|
||||
|
||||
struct TaskWithArguments
|
||||
{
|
||||
TaskWithArguments(std::unique_lock<std::mutex> lock,
|
||||
TaskWithArguments(std::unique_lock<SpinLock> lock,
|
||||
Utils::span<TraceEventWithArguments> data,
|
||||
std::thread::id threadId)
|
||||
: lock{std::move(lock)}
|
||||
@@ -406,14 +421,14 @@ struct TaskWithArguments
|
||||
, threadId{threadId}
|
||||
{}
|
||||
|
||||
std::unique_lock<std::mutex> lock;
|
||||
std::unique_lock<SpinLock> lock;
|
||||
Utils::span<TraceEventWithArguments> data;
|
||||
std::thread::id threadId;
|
||||
};
|
||||
|
||||
struct TaskWithoutArguments
|
||||
{
|
||||
TaskWithoutArguments(std::unique_lock<std::mutex> lock,
|
||||
TaskWithoutArguments(std::unique_lock<SpinLock> lock,
|
||||
Utils::span<TraceEventWithoutArguments> data,
|
||||
std::thread::id threadId)
|
||||
: lock{std::move(lock)}
|
||||
@@ -421,20 +436,20 @@ struct TaskWithoutArguments
|
||||
, threadId{threadId}
|
||||
{}
|
||||
|
||||
std::unique_lock<std::mutex> lock;
|
||||
std::unique_lock<SpinLock> lock;
|
||||
Utils::span<TraceEventWithoutArguments> data;
|
||||
std::thread::id threadId;
|
||||
};
|
||||
|
||||
struct MetaData
|
||||
{
|
||||
MetaData(std::unique_lock<std::mutex> lock, std::string key, std::string value)
|
||||
MetaData(std::unique_lock<SpinLock> lock, std::string key, std::string value)
|
||||
: lock{std::move(lock)}
|
||||
, key{std::move(key)}
|
||||
, value{std::move(value)}
|
||||
{}
|
||||
|
||||
std::unique_lock<std::mutex> lock;
|
||||
std::unique_lock<SpinLock> lock;
|
||||
std::string key;
|
||||
std::string value;
|
||||
};
|
||||
@@ -646,7 +661,7 @@ public:
|
||||
TraceEventsSpan currentEvents;
|
||||
std::size_t eventsIndex = 0;
|
||||
IsEnabled isEnabled = IsEnabled::Yes;
|
||||
std::mutex mutex;
|
||||
SpinLock mutex;
|
||||
std::thread::id threadId;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user