Skip to content
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

Add Lock-free Queue #253

Merged
Merged
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
561d370
add libboost-dev dependency
saikishor Dec 19, 2024
2455b16
Add LockFreeBuffer class
saikishor Dec 19, 2024
02db30d
Add LockFreeSPSCQueueBase class
saikishor Dec 28, 2024
1468fe8
Add more functionality and tests
saikishor Dec 29, 2024
2ef8020
Add tests to CMakeLists
saikishor Dec 30, 2024
268138b
Draft: functional lockfree queue (not spsc_queue)
saikishor Dec 30, 2024
5e94cc9
Add more template enabled methods
saikishor Dec 31, 2024
34d03b5
update tests
saikishor Dec 31, 2024
6b629b1
Update the LockFreeQueue to completely support SPSC and MPMC queues +…
saikishor Dec 31, 2024
9a9951d
cleanup and change license
saikishor Jan 1, 2025
8c2c974
Update the documentation and add some minor tests
saikishor Jan 1, 2025
c991609
Merge branch 'ros-controls:master' into boost/lockfree/realtime/buffer
saikishor Jan 1, 2025
860029e
Add is_lock_free method
saikishor Jan 1, 2025
fe75f45
Update documentation
saikishor Jan 1, 2025
52f53b1
Add get_latest method to the LockFreeQueue
saikishor Jan 1, 2025
356d87e
update CMakeLists.txt
saikishor Jan 2, 2025
ac7ae53
Apply suggestions from code review
saikishor Jan 2, 2025
66dcdfd
Change template arg LockFreeSPSCContainer to LockFreeContainer
saikishor Jan 2, 2025
5d990c0
Install boost
christophfroehlich Jan 2, 2025
71321b3
cleanup the commented tests
saikishor Jan 2, 2025
4f61624
Update include/realtime_tools/lock_free_queue.hpp
saikishor Jan 3, 2025
9a8acdf
Update tests
saikishor Jan 3, 2025
ddb5ca9
Update condition for bounded push and update documentation
saikishor Jan 3, 2025
494b47d
Install boost in Windows CI
christophfroehlich Jan 3, 2025
8d1bae4
Unify empty method with internal conditioning of SPSC queue or MPMC q…
saikishor Jan 3, 2025
f90d22b
Try to set CMP0167 for boost on windows
christophfroehlich Jan 3, 2025
081d2f6
Remove quiet and add Boost::boost
christophfroehlich Jan 3, 2025
2f8d285
Remove atomic link libraries
christophfroehlich Jan 3, 2025
fff6ee3
Try to fix msvc atomic
christophfroehlich Jan 3, 2025
2bb6519
Try to fix atomic.lib on msvc
christophfroehlich Jan 3, 2025
551a9fb
Don't link atomic on windows
christophfroehlich Jan 3, 2025
689f63c
Use master branch of CI repo
christophfroehlich Jan 3, 2025
b8becad
Simplify push method and also add fixed_size arg to the MPMC queue
saikishor Jan 9, 2025
bd74a53
reuse tests to test all constructable types of LockFreeQueues
saikishor Jan 9, 2025
0d3fc7e
Merge branch 'master' into boost/lockfree/realtime/buffer
saikishor Jan 13, 2025
f764bc8
Merge branch 'master' into boost/lockfree/realtime/buffer
saikishor Jan 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Change template arg LockFreeSPSCContainer to LockFreeContainer
saikishor committed Jan 2, 2025
commit 66dcdfdc50605449e2285c9a719b10ebada5b147
36 changes: 18 additions & 18 deletions include/realtime_tools/lock_free_queue.hpp
Original file line number Diff line number Diff line change
@@ -107,32 +107,32 @@ namespace realtime_tools
/**
* @brief Base class for lock-free queues
* @tparam DataType Type of the data to be stored in the queue
* @tparam LockFreeSPSCContainer Type of the lock-free container - Typically boost::lockfree::spsc_queue or boost::lockfree::queue with their own template parameters
* @tparam LockFreeContainer Type of the lock-free container - Typically boost::lockfree::spsc_queue or boost::lockfree::queue with their own template parameters
*/
template <typename DataType, typename LockFreeSPSCContainer>
template <typename DataType, typename LockFreeContainer>
class LockFreeQueueBase
{
public:
using T = DataType;

/**
* @brief Construct a new LockFreeQueueBase object
* @note This constructor is enabled only if the LockFreeSPSCContainer has a capacity set
* @note This constructor is enabled only if the LockFreeContainer has a capacity set
*/
template <
bool HasCapacity = has_capacity<LockFreeSPSCContainer>::value,
bool HasCapacity = has_capacity<LockFreeContainer>::value,
typename std::enable_if_t<HasCapacity, int> = 0>
LockFreeQueueBase() : capacity_(get_boost_lockfree_queue_capacity<LockFreeSPSCContainer>::value)
LockFreeQueueBase() : capacity_(get_boost_lockfree_queue_capacity<LockFreeContainer>::value)
{
}

/**
* @brief Construct a new LockFreeQueueBase object
* @param capacity Capacity of the queue
* @note This constructor is enabled only if the LockFreeSPSCContainer has no capacity set
* @note This constructor is enabled only if the LockFreeContainer has no capacity set
*/
template <
bool HasCapacity = has_capacity<LockFreeSPSCContainer>::value,
bool HasCapacity = has_capacity<LockFreeContainer>::value,
typename std::enable_if_t<!HasCapacity, int> = 1>
explicit LockFreeQueueBase(std::size_t capacity) : data_queue_(capacity), capacity_(capacity)
{
@@ -196,7 +196,7 @@ class LockFreeQueueBase
* single consumer queue. So, the behaviour might not be as expected.
*/
template <
typename U, bool IsSPSCQueue = is_spsc_queue<LockFreeSPSCContainer>::value,
typename U, bool IsSPSCQueue = is_spsc_queue<LockFreeContainer>::value,
typename std::enable_if_t<IsSPSCQueue, int> = 0>
[[nodiscard]] std::enable_if_t<std::is_convertible_v<T, U>, bool> bounded_push(const U & data)
{
@@ -230,7 +230,7 @@ class LockFreeQueueBase
* @note Can be used in a multi threaded applications
*/
template <
typename U, bool IsSPSCQueue = is_spsc_queue<LockFreeSPSCContainer>::value,
typename U, bool IsSPSCQueue = is_spsc_queue<LockFreeContainer>::value,
typename std::enable_if_t<!IsSPSCQueue, int> = 1>
[[nodiscard]] std::enable_if_t<std::is_convertible_v<T, U>, bool> bounded_push(const U & data)
{
saikishor marked this conversation as resolved.
Show resolved Hide resolved
@@ -250,7 +250,7 @@ class LockFreeQueueBase
* @note Should only be called from the consumer thread where pop is called
*/
template <
bool IsSPSCQueue = is_spsc_queue<LockFreeSPSCContainer>::value,
bool IsSPSCQueue = is_spsc_queue<LockFreeContainer>::value,
typename std::enable_if_t<IsSPSCQueue, int> = 0>
bool empty() const
{
@@ -266,7 +266,7 @@ class LockFreeQueueBase
* @note This function is enabled only if the queue is of multiple producer and multiple consumer type
*/
template <
bool IsSPSCQueue = is_spsc_queue<LockFreeSPSCContainer>::value,
bool IsSPSCQueue = is_spsc_queue<LockFreeContainer>::value,
typename std::enable_if_t<!IsSPSCQueue, int> = 1>
bool empty() const
{
@@ -285,7 +285,7 @@ class LockFreeQueueBase
* @note This function is enabled only if the queue is a spsc_queue
*/
template <
bool IsSPSCQueue = is_spsc_queue<LockFreeSPSCContainer>::value,
bool IsSPSCQueue = is_spsc_queue<LockFreeContainer>::value,
typename std::enable_if_t<IsSPSCQueue, int> = 0>
std::size_t size() const
{
@@ -305,7 +305,7 @@ class LockFreeQueueBase
*/
bool is_lock_free() const
{
if constexpr (is_spsc_queue<LockFreeSPSCContainer>::value) {
if constexpr (is_spsc_queue<LockFreeContainer>::value) {
return true;
} else {
return data_queue_.is_lock_free();
@@ -314,18 +314,18 @@ class LockFreeQueueBase

/**
* @brief Get the lockfree container
* @return const LockFreeSPSCContainer& Reference to the lockfree container
* @return const LockFreeContainer& Reference to the lockfree container
*/
const LockFreeSPSCContainer & get_lockfree_container() const { return data_queue_; }
const LockFreeContainer & get_lockfree_container() const { return data_queue_; }

/**
* @brief Get the lockfree container
* @return LockFreeSPSCContainer& Reference to the lockfree container
* @return LockFreeContainer& Reference to the lockfree container
*/
LockFreeSPSCContainer & get_lockfree_container() { return data_queue_; }
LockFreeContainer & get_lockfree_container() { return data_queue_; }

private:
LockFreeSPSCContainer data_queue_;
LockFreeContainer data_queue_;
std::size_t capacity_;
}; // class