ATLAS Offline Software
Loading...
Searching...
No Matches
CaloRecGPU::Helpers::separate_thread_holder< T > Class Template Reference

Manages objects of type T in a thread-safe way, ensuring that there's an object available for each separate thread while minimizing the number of allocations. More...

#include <Helpers.h>

Collaboration diagram for CaloRecGPU::Helpers::separate_thread_holder< T >:

Public Member Functions

T & get_one ()
T & get_for_thread () const
void release_one ()
void resize (const size_t new_size)
template<class F, class ... Args>
void operate_on_all (F &&f, Args &&... args)
size_t held_size () const
size_t available_size () const
size_t filled_size () const

Private Member Functions

T & add_one_and_return ()

Private Attributes

std::vector< std::unique_ptr< T > > m_held
std::vector< typename std::thread::id > m_thread_equivs
std::shared_mutex m_mutex

Detailed Description

template<class T>
class CaloRecGPU::Helpers::separate_thread_holder< T >

Manages objects of type T in a thread-safe way, ensuring that there's an object available for each separate thread while minimizing the number of allocations.

Internally uses a std::vector of std::thread::id to manage the different threads, thus it is especially efficient for relatively small numbers of concurrent threads (which matches the use case, e. g. 64 threads )

Definition at line 1683 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

Member Function Documentation

◆ add_one_and_return()

template<class T>
T & CaloRecGPU::Helpers::separate_thread_holder< T >::add_one_and_return ( )
inlineprivate

Definition at line 1701 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1702 {
1704 m_held.emplace_back(std::make_unique<T>());
1706 return *(m_held.back());
1707 }
Manages objects of type T in a thread-safe way, ensuring that there's an object available for each se...

◆ available_size()

template<class T>
size_t CaloRecGPU::Helpers::separate_thread_holder< T >::available_size ( ) const
inline

Definition at line 1795 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1796 {
1798 size_t count = 0;
1800 for (const auto & id : m_thread_equivs)
1801 {
1802 if (id == invalid_id)
1803 {
1804 ++count;
1805 }
1806 }
1807 return count;
1808 }

◆ filled_size()

template<class T>
size_t CaloRecGPU::Helpers::separate_thread_holder< T >::filled_size ( ) const
inline

Definition at line 1810 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1811 {
1813 size_t count = 0;
1815 for (const auto & id : m_thread_equivs)
1816 {
1817 if (id == invalid_id)
1818 {
1819 ++count;
1820 }
1821 }
1822 return m_held.size() - count;
1823 }

◆ get_for_thread()

template<class T>
T & CaloRecGPU::Helpers::separate_thread_holder< T >::get_for_thread ( ) const
inline
Precondition
Assumes the thread already has an allocated object (through get_one).

Definition at line 1729 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1730 {
1733 for (size_t i = 0; i < m_thread_equivs.size(); ++i)
1734 {
1735 if (m_thread_equivs[i] == this_id)
1736 {
1737 return *(m_held[i]);
1738 }
1739 }
1740 //Here would be a good place for an unreachable.
1741 //C++23?
1742 return *(m_held.back());
1743 }

◆ get_one()

template<class T>
T & CaloRecGPU::Helpers::separate_thread_holder< T >::get_one ( )
inline

Definition at line 1710 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1711 {
1712 {
1716 for (size_t i = 0; i < m_thread_equivs.size(); ++i)
1717 {
1719 {
1721 return *(m_held[i]);
1722 }
1723 }
1724 }
1725 return add_one_and_return();
1726 }

◆ held_size()

template<class T>
size_t CaloRecGPU::Helpers::separate_thread_holder< T >::held_size ( ) const
inline

Definition at line 1789 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1790 {
1792 return m_held.size();
1793 }

◆ operate_on_all()

template<class T>
template<class F, class ... Args>
void CaloRecGPU::Helpers::separate_thread_holder< T >::operate_on_all ( F && f,
Args &&... args )
inline

Definition at line 1780 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1781 {
1783 for (std::unique_ptr<T> & obj : m_held)
1784 {
1786 }
1787 }

◆ release_one()

template<class T>
void CaloRecGPU::Helpers::separate_thread_holder< T >::release_one ( )
inline

Definition at line 1745 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1746 {
1750 for (size_t i = 0; i < m_thread_equivs.size(); ++i)
1751 {
1752 if (m_thread_equivs[i] == this_id)
1753 {
1755 }
1756 }
1757 }

◆ resize()

template<class T>
void CaloRecGPU::Helpers::separate_thread_holder< T >::resize ( const size_t new_size)
inline

Definition at line 1759 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1760 {
1762 if (new_size < m_held.size())
1763 {
1764 m_held.resize(new_size);
1765 m_thread_equivs.resize(new_size);
1766 }
1767 else if (new_size > m_held.size())
1768 {
1769 const size_t to_add = new_size - m_held.size();
1771 for (size_t i = 0; i < to_add; ++i)
1772 {
1773 m_held.emplace_back(std::make_unique<T>());
1774 m_thread_equivs.emplace_back(invalid_id);
1775 }
1776 }
1777 }

Member Data Documentation

◆ m_held

template<class T>
std::vector< std::unique_ptr<T> > CaloRecGPU::Helpers::separate_thread_holder< T >::m_held
private

◆ m_mutex

template<class T>
std::shared_mutex CaloRecGPU::Helpers::separate_thread_holder< T >::m_mutex
mutableprivate

◆ m_thread_equivs

template<class T>
std::vector< typename std::thread::id > CaloRecGPU::Helpers::separate_thread_holder< T >::m_thread_equivs
private

The documentation for this class was generated from the following file: