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 * get_pointer_if_available () const
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 1718 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1719 {
1721
1724
1725 bool empty_found = false;
1726
1727 size_t first_empty;
1728
1729 for (size_t i = 0; i < m_thread_equivs.size(); ++i)
1730 {
1731 if (m_thread_equivs[i] == this_id)
1732 {
1733 return *(m_held[i]);
1734 }
1735 else if (!empty_found && m_thread_equivs[i] == invalid_id)
1736 {
1737 empty_found = true;
1738 first_empty = i;
1739 }
1740 }
1741
1742 if (empty_found)
1743 {
1745 return *(m_held[first_empty]);
1746 }
1747 else
1748 {
1749 m_held.emplace_back(std::make_unique<T>());
1751 return *(m_held.back());
1752 }
1753 }
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 1840 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1841 {
1843 size_t count = 0;
1845 for (const auto & id : m_thread_equivs)
1846 {
1847 if (id == invalid_id)
1848 {
1849 ++count;
1850 }
1851 }
1852 return count;
1853 }

◆ filled_size()

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

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

1856 {
1858 size_t count = 0;
1860 for (const auto & id : m_thread_equivs)
1861 {
1862 if (id == invalid_id)
1863 {
1864 ++count;
1865 }
1866 }
1867 return m_held.size() - count;
1868 }

◆ 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 1772 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1773 {
1775
1777
1778 if (to_return != nullptr)
1779 {
1780 return *to_return;
1781 }
1782 else
1783 {
1784 //Here would be a good place for an unreachable.
1785 //C++23?
1786 return *(m_held.back());
1787 }
1788 }

◆ get_one()

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

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

1757 {
1758 {
1760
1762
1763 if (to_return != nullptr)
1764 {
1765 return *to_return;
1766 }
1767 }
1768 return add_one_and_return();
1769 }

◆ get_pointer_if_available()

template<class T>
T * CaloRecGPU::Helpers::separate_thread_holder< T >::get_pointer_if_available ( ) const
inlineprivate

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

1705 {
1707
1708 for (size_t i = 0; i < m_thread_equivs.size(); ++i)
1709 {
1710 if (m_thread_equivs[i] == this_id)
1711 {
1712 return m_held[i].get();
1713 }
1714 }
1715 return nullptr;
1716 }

◆ held_size()

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

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

1835 {
1837 return m_held.size();
1838 }

◆ 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 1825 of file Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h.

1826 {
1828 for (std::unique_ptr<T> & obj : m_held)
1829 {
1831 }
1832 }

◆ release_one()

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

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

1791 {
1795 for (size_t i = 0; i < m_thread_equivs.size(); ++i)
1796 {
1797 if (m_thread_equivs[i] == this_id)
1798 {
1800 }
1801 }
1802 }

◆ resize()

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

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

1805 {
1807 if (new_size < m_held.size())
1808 {
1809 m_held.resize(new_size);
1810 m_thread_equivs.resize(new_size);
1811 }
1812 else if (new_size > m_held.size())
1813 {
1814 const size_t to_add = new_size - m_held.size();
1816 for (size_t i = 0; i < to_add; ++i)
1817 {
1818 m_held.emplace_back(std::make_unique<T>());
1819 m_thread_equivs.emplace_back(invalid_id);
1820 }
1821 }
1822 }

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: