-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(Core/Threading): Refactored LockedQueue / MPSCQueue - Improve thread safety, performance, and memory management #21127
base: master
Are you sure you want to change the base?
Conversation
Thread-Safety Improvements: use std::atomic<bool> for the cancellation flag, ensuring proper atomic operations and synchronization. Performance: By using move semantics in add() and next(), it avoids unnecessary copies, which is more efficient. Simplified Locking: It uses std::lock_guard<std::mutex> consistently for thread safety, reducing the chance of errors related to manual locking and unlocking. Const-Correctness: It marks methods that don’t modify the object as const. No Need for Manual Unlocking in Peek: The second version’s peek() method avoids the complexity of manually unlocking the mutex, which makes it easier to use safely.
Stricter Memory Ordering: Ensures stricter memory order semantics are used consistently with std::memory_order_acquire and std::memory_order_release. Complete Node Deletion: avoiding potential memory leaks or dangling pointers. Improved Synchronization on Initialization.
Retain Node() = default; as I remembered that this seems to have preference.
Note: I am not 100% sure if it is really required to replace the memory_order_relaxed within the Dmitry Vyukov's lock free MPSC queue, so that can be debatable due to its single consumer concept. |
Looks like, anyone test this? |
Been running on mine for a few days (helped with testing pre PR). Been real smooth |
Personally, I have tested this on Linux, a friend on Windows. What has been tested:
Nothing out of the ordinary has been observed.
|
I did glance at it and looks okay to me. The only small hesitation I have is the change to stricter ordering on the MPSC queue, not sure if it's really necessary or if it may or may not have any impact on throughput. |
This is where I was somewhat hesitant as well, yet I haven't noticed an performance impact and overall it just sounds safer to me. |
Changes Proposed:
Refactored LockedQueue class:
Thread-Safety Improvements: use std::atomic for the cancellation flag, ensuring proper atomic operations and synchronization.
Performance: By using move semantics in add() and next(), it avoids unnecessary copies, which is more efficient.
Simplified Locking: It uses std::lock_guardstd::mutex consistently for thread safety, reducing the chance of errors related to manual locking and unlocking.
Const-Correctness: It marks methods that don’t modify the object as const.
No Need for Manual Unlocking in Peek: The second version’s peek() method avoids the complexity of manually unlocking the mutex, which makes it easier to use safely.
Refactored MPSCQueue class:
Stricter Memory Ordering: Ensures stricter memory order semantics are used consistently using std::memory_order_acquire and std::memory_order_release.
Complete Node Deletion:
avoiding potential memory leaks or dangling pointers.
Improved Synchronization on Initialization.
This PR proposes changes to:
Issues Addressed:
SOURCE:
The changes have been validated through:
Tests Performed:
This PR has been:
How to Test the Changes:
No functional changes have been made. The changes primarily involve code refactoring aimed at potential performance improvements, with enhanced code structure and more efficient memory handling for greater robustness and stability.
There should be no issues or deficiencies resulting from these changes.
Known Issues and TODO List:
How to Test AzerothCore PRs
When a PR is ready to be tested, it will be marked as [WAITING TO BE TESTED].
You can help by testing PRs and writing your feedback here on the PR's page on GitHub. Follow the instructions here:
http://www.azerothcore.org/wiki/How-to-test-a-PR
REMEMBER: when testing a PR that changes something generic (i.e. a part of code that handles more than one specific thing), the tester should not only check that the PR does its job (e.g. fixing spell XXX) but especially check that the PR does not cause any regression (i.e. introducing new bugs).
For example: if a PR fixes spell X by changing a part of code that handles spells X, Y, and Z, we should not only test X, but we should test Y and Z as well.