Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions public/tier1/mempool.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,30 @@ class CClassMemoryPool : public CUtlMemoryPool
void Clear();
};

template< class T >
class CClassMemoryPoolMT : private CClassMemoryPool< T >
{
public:
// dimhotepus: Alignment should derive from class.
CClassMemoryPoolMT( intp numElements, int growMode = GROW_FAST, unsigned short nAlignment = alignof(T) ) :
CClassMemoryPool<T>( numElements, growMode, nAlignment ) {
#ifdef PLATFORM_64BITS
COMPILE_TIME_ASSERT( sizeof(CUtlMemoryPool) == 96 );
#else
COMPILE_TIME_ASSERT( sizeof(CUtlMemoryPool) == 48 );
#endif
}

[[nodiscard]] T* Alloc() { AUTO_LOCK(m_lock); return CClassMemoryPool::Alloc(); };
[[nodiscard]] T* AllocZero() { AUTO_LOCK(m_lock); return CClassMemoryPool::AllocZero(); };
void Free( T *pMem ) { AUTO_LOCK(m_lock); CClassMemoryPool::Free( pMem ); };

void Clear() { AUTO_LOCK(m_lock); CClassMemoryPool::Clear(); };

private:
CThreadMutex m_lock;
};


//-----------------------------------------------------------------------------
// Specialized pool for aligned data management (e.g., Xbox cubemaps)
Expand Down
102 changes: 51 additions & 51 deletions public/tier1/utldict.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ enum EDictCompareType
//-----------------------------------------------------------------------------
// A dictionary mapping from symbol to structure
//-----------------------------------------------------------------------------
template <class T, class I = intp >
template <class T, class I = intp, template <typename, typename, typename> class MapType = CUtlMap>
class CUtlDict
{
public:
Expand Down Expand Up @@ -99,16 +99,16 @@ class CUtlDict
using IndexType_t = I;

protected:
using DictElementMap_t = CUtlMap<const char *, T, I>;
using DictElementMap_t = MapType<const char *, T, I>;
DictElementMap_t m_Elements;
};


//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template <class T, class I>
CUtlDict<T, I>::CUtlDict( int compareType, intp growSize, intp initSize ) : m_Elements( growSize, initSize )
template <class T, class I, template <typename, typename, typename> class MapType>
CUtlDict<T, I, MapType>::CUtlDict( int compareType, intp growSize, intp initSize ) : m_Elements( growSize, initSize )
{
if ( compareType == k_eDictCompareTypeFilenames )
{
Expand All @@ -124,62 +124,62 @@ CUtlDict<T, I>::CUtlDict( int compareType, intp growSize, intp initSize ) : m_El
}
}

template <class T, class I>
CUtlDict<T, I>::~CUtlDict()
template <class T, class I, template <typename, typename, typename> class MapType>
CUtlDict<T, I, MapType>::~CUtlDict()
{
Purge();
}

template <class T, class I>
inline void CUtlDict<T, I>::EnsureCapacity( intp num )
template <class T, class I, template <typename, typename, typename> class MapType>
inline void CUtlDict<T, I, MapType>::EnsureCapacity( intp num )
{
return m_Elements.EnsureCapacity( num );
}

//-----------------------------------------------------------------------------
// gets particular elements
//-----------------------------------------------------------------------------
template <class T, class I>
inline T& CUtlDict<T, I>::Element( I i )
template <class T, class I, template <typename, typename, typename> class MapType>
inline T& CUtlDict<T, I, MapType>::Element( I i )
{
return m_Elements[i];
}

template <class T, class I>
inline const T& CUtlDict<T, I>::Element( I i ) const
template <class T, class I, template <typename, typename, typename> class MapType>
inline const T& CUtlDict<T, I, MapType>::Element( I i ) const
{
return m_Elements[i];
}

//-----------------------------------------------------------------------------
// gets element names
//-----------------------------------------------------------------------------
template <class T, class I>
inline char *CUtlDict<T, I>::GetElementName( I i )
template <class T, class I, template <typename, typename, typename> class MapType>
inline char *CUtlDict<T, I, MapType>::GetElementName( I i )
{
return (char *)m_Elements.Key( i );
}

template <class T, class I>
inline char const *CUtlDict<T, I>::GetElementName( I i ) const
template <class T, class I, template <typename, typename, typename> class MapType>
inline char const *CUtlDict<T, I, MapType>::GetElementName( I i ) const
{
return m_Elements.Key( i );
}

template <class T, class I>
inline T& CUtlDict<T, I>::operator[]( I i )
template <class T, class I, template <typename, typename, typename> class MapType>
inline T& CUtlDict<T, I, MapType>::operator[]( I i )
{
return Element(i);
}

template <class T, class I>
inline const T & CUtlDict<T, I>::operator[]( I i ) const
template <class T, class I, template <typename, typename, typename> class MapType>
inline const T & CUtlDict<T, I, MapType>::operator[]( I i ) const
{
return Element(i);
}

template <class T, class I>
inline void CUtlDict<T, I>::SetElementName( I i, char const *pName )
template <class T, class I, template <typename, typename, typename> class MapType>
inline void CUtlDict<T, I, MapType>::SetElementName( I i, char const *pName )
{
MEM_ALLOC_CREDIT_CLASS();
// TODO: This makes a copy of the old element
Expand All @@ -192,26 +192,26 @@ inline void CUtlDict<T, I>::SetElementName( I i, char const *pName )
//-----------------------------------------------------------------------------
// Num elements
//-----------------------------------------------------------------------------
template <class T, class I>
inline I CUtlDict<T, I>::Count() const
template <class T, class I, template <typename, typename, typename> class MapType>
inline I CUtlDict<T, I, MapType>::Count() const
{
return m_Elements.Count();
}

//-----------------------------------------------------------------------------
// Number of allocated slots
//-----------------------------------------------------------------------------
template <class T, class I>
inline I CUtlDict<T, I>::MaxElement() const
template <class T, class I, template <typename, typename, typename> class MapType>
inline I CUtlDict<T, I, MapType>::MaxElement() const
{
return m_Elements.MaxElement();
}

//-----------------------------------------------------------------------------
// Checks if a node is valid and in the tree
//-----------------------------------------------------------------------------
template <class T, class I>
inline bool CUtlDict<T, I>::IsValidIndex( I i ) const
template <class T, class I, template <typename, typename, typename> class MapType>
inline bool CUtlDict<T, I, MapType>::IsValidIndex( I i ) const
{
return m_Elements.IsValidIndex(i);
}
Expand All @@ -220,8 +220,8 @@ inline bool CUtlDict<T, I>::IsValidIndex( I i ) const
//-----------------------------------------------------------------------------
// Invalid index
//-----------------------------------------------------------------------------
template <class T, class I>
inline constexpr I CUtlDict<T, I>::InvalidIndex()
template <class T, class I, template <typename, typename, typename> class MapType>
inline constexpr I CUtlDict<T, I, MapType>::InvalidIndex()
{
return DictElementMap_t::InvalidIndex();
}
Expand All @@ -230,8 +230,8 @@ inline constexpr I CUtlDict<T, I>::InvalidIndex()
//-----------------------------------------------------------------------------
// Delete a node from the tree
//-----------------------------------------------------------------------------
template <class T, class I>
void CUtlDict<T, I>::RemoveAt(I elem)
template <class T, class I, template <typename, typename, typename> class MapType>
void CUtlDict<T, I, MapType>::RemoveAt(I elem)
{
free( (void *)m_Elements.Key( elem ) );
m_Elements.RemoveAt(elem);
Expand All @@ -241,7 +241,7 @@ void CUtlDict<T, I>::RemoveAt(I elem)
//-----------------------------------------------------------------------------
// remove a node in the tree
//-----------------------------------------------------------------------------
template <class T, class I> void CUtlDict<T, I>::Remove( const char *search )
template <class T, class I, template <typename, typename, typename> class MapType> void CUtlDict<T, I, MapType>::Remove( const char *search )
{
I node = Find( search );
if (node != InvalidIndex())
Expand All @@ -254,8 +254,8 @@ template <class T, class I> void CUtlDict<T, I>::Remove( const char *search )
//-----------------------------------------------------------------------------
// Removes all nodes from the tree
//-----------------------------------------------------------------------------
template <class T, class I>
void CUtlDict<T, I>::RemoveAll()
template <class T, class I, template <typename, typename, typename> class MapType>
void CUtlDict<T, I, MapType>::RemoveAll()
{
typename DictElementMap_t::IndexType_t index = m_Elements.FirstInorder();
while ( index != m_Elements.InvalidIndex() )
Expand All @@ -267,15 +267,15 @@ void CUtlDict<T, I>::RemoveAll()
m_Elements.RemoveAll();
}

template <class T, class I>
void CUtlDict<T, I>::Purge()
template <class T, class I, template <typename, typename, typename> class MapType>
void CUtlDict<T, I, MapType>::Purge()
{
RemoveAll();
}


template <class T, class I>
void CUtlDict<T, I>::PurgeAndDeleteElements()
template <class T, class I, template <typename, typename, typename> class MapType>
void CUtlDict<T, I, MapType>::PurgeAndDeleteElements()
{
// Delete all the elements.
I index = m_Elements.FirstInorder();
Expand All @@ -293,15 +293,15 @@ void CUtlDict<T, I>::PurgeAndDeleteElements()
//-----------------------------------------------------------------------------
// inserts a node into the tree
//-----------------------------------------------------------------------------
template <class T, class I>
I CUtlDict<T, I>::Insert( const char *pName, const T &element )
template <class T, class I, template <typename, typename, typename> class MapType>
I CUtlDict<T, I, MapType>::Insert( const char *pName, const T &element )
{
MEM_ALLOC_CREDIT_CLASS();
return m_Elements.Insert( strdup( pName ), element );
}

template <class T, class I>
I CUtlDict<T, I>::Insert( const char *pName )
template <class T, class I, template <typename, typename, typename> class MapType>
I CUtlDict<T, I, MapType>::Insert( const char *pName )
{
MEM_ALLOC_CREDIT_CLASS();
return m_Elements.Insert( strdup( pName ) );
Expand All @@ -311,8 +311,8 @@ I CUtlDict<T, I>::Insert( const char *pName )
//-----------------------------------------------------------------------------
// finds a node in the tree
//-----------------------------------------------------------------------------
template <class T, class I>
I CUtlDict<T, I>::Find( const char *pName ) const
template <class T, class I, template <typename, typename, typename> class MapType>
I CUtlDict<T, I, MapType>::Find( const char *pName ) const
{
MEM_ALLOC_CREDIT_CLASS();
if ( pName )
Expand All @@ -324,8 +324,8 @@ I CUtlDict<T, I>::Find( const char *pName ) const
//-----------------------------------------------------------------------------
// returns true if we already have this node
//-----------------------------------------------------------------------------
template <class T, class I>
bool CUtlDict<T, I>::HasElement( const char *pName ) const
template <class T, class I, template <typename, typename, typename> class MapType>
bool CUtlDict<T, I, MapType>::HasElement( const char *pName ) const
{
if ( pName )
return m_Elements.IsValidIndex( m_Elements.Find( pName ) );
Expand All @@ -337,14 +337,14 @@ bool CUtlDict<T, I>::HasElement( const char *pName ) const
//-----------------------------------------------------------------------------
// Iteration methods
//-----------------------------------------------------------------------------
template <class T, class I>
I CUtlDict<T, I>::First() const
template <class T, class I, template <typename, typename, typename> class MapType>
I CUtlDict<T, I, MapType>::First() const
{
return m_Elements.FirstInorder();
}

template <class T, class I>
I CUtlDict<T, I>::Next( I i ) const
template <class T, class I, template <typename, typename, typename> class MapType>
I CUtlDict<T, I, MapType>::Next( I i ) const
{
return m_Elements.NextInorder(i);
}
Expand Down
91 changes: 91 additions & 0 deletions public/tier1/utlmapmt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#ifndef UTLMAPMT_H
#define UTLMAPMT_H

#ifdef _WIN32
#pragma once
#endif

#include "tier0/dbg.h"
#include "utlmap.h"

//-----------------------------------------------------------------------------
//
// Purpose: Same as CUtlMap but threadsafe
//
//-----------------------------------------------------------------------------

template <typename K, typename T, typename I = unsigned short>
class CUtlMapMT : public CUtlMap<K, T, I>
{
public:
using Base = CUtlMap<K, T, I>;
using KeyType_t = typename Base::KeyType_t;
using ElemType_t = typename Base::ElemType_t;
using IndexType_t = typename Base::IndexType_t;
using LessFunc_t = typename Base::LessFunc_t;

// Constructors
CUtlMapMT(intp growSize = 0, intp initSize = 0, LessFunc_t lessfunc = 0)
: Base(growSize, initSize, lessfunc) {}

CUtlMapMT(LessFunc_t lessfunc) : Base(lessfunc) {}

void EnsureCapacity(intp num) { AUTO_LOCK_WRITE(m_lock); Base::EnsureCapacity(num); }

ElemType_t &Element(IndexType_t i) { AUTO_LOCK_READ(m_lock); return Base::Element(i); }
const ElemType_t &Element(IndexType_t i) const { AUTO_LOCK_READ(m_lock); return Base::Element(i); }

ElemType_t &operator[](IndexType_t i) { AUTO_LOCK_READ(m_lock); return Base::operator[](i); }
const ElemType_t &operator[](IndexType_t i) const { AUTO_LOCK_READ(m_lock); return Base::operator[](i); }

KeyType_t &Key(IndexType_t i) { AUTO_LOCK_READ(m_lock); return Base::Key(i); }
const KeyType_t &Key(IndexType_t i) const { AUTO_LOCK_READ(m_lock); return Base::Key(i); }

size_t Count() const { AUTO_LOCK_READ(m_lock); return Base::Count(); }
IndexType_t MaxElement() const { AUTO_LOCK_READ(m_lock); return Base::MaxElement(); }
bool IsValidIndex(IndexType_t i) const { AUTO_LOCK_READ(m_lock); return Base::IsValidIndex(i); }
bool IsValid() const { AUTO_LOCK_READ(m_lock); return Base::IsValid(); }

void SetLessFunc(LessFunc_t func) { AUTO_LOCK_WRITE(m_lock); Base::SetLessFunc(func); }

IndexType_t Insert(const KeyType_t &key, const ElemType_t &insert) { AUTO_LOCK_WRITE(m_lock); return Base::Insert(key, insert); }
IndexType_t Insert(const KeyType_t &key) { AUTO_LOCK_WRITE(m_lock); return Base::Insert(key); }

IndexType_t Find(const KeyType_t &key) const { AUTO_LOCK_READ(m_lock); return Base::Find(key); }

void RemoveAt(IndexType_t i) { AUTO_LOCK_WRITE(m_lock); Base::RemoveAt(i); }
bool Remove(const KeyType_t &key) { AUTO_LOCK_WRITE(m_lock); return Base::Remove(key); }
void RemoveAll() { AUTO_LOCK_WRITE(m_lock); Base::RemoveAll(); }
void Purge() { AUTO_LOCK_WRITE(m_lock); Base::Purge(); }
void PurgeAndDeleteElements() { AUTO_LOCK_WRITE(m_lock); Base::PurgeAndDeleteElements(); }

IndexType_t FirstInorder() const { AUTO_LOCK_READ(m_lock); return Base::FirstInorder(); }
IndexType_t NextInorder(IndexType_t i) const { AUTO_LOCK_READ(m_lock); return Base::NextInorder(i); }
IndexType_t PrevInorder(IndexType_t i) const { AUTO_LOCK_READ(m_lock); return Base::PrevInorder(i); }
IndexType_t LastInorder() const { AUTO_LOCK_READ(m_lock); return Base::LastInorder(); }

void Reinsert(const KeyType_t &key, IndexType_t i) { AUTO_LOCK_WRITE(m_lock); Base::Reinsert(key, i); }

IndexType_t InsertOrReplace(const KeyType_t &key, const ElemType_t &insert)
{
AUTO_LOCK_WRITE(m_lock);
return Base::InsertOrReplace(key, insert);
}

void Swap(CUtlMap<K, T, I> &that)
{
// Lock both maps to avoid race
AUTO_LOCK_WRITE(m_lock);
AUTO_LOCK_WRITE(static_cast<CUtlMapMT<K,T,I>&>(that).m_lock);
Base::Swap(that);
}

private:
#if defined(WIN32) || defined(_WIN32)
mutable CThreadSpinRWLock m_lock;
#else
mutable CThreadRWLock m_lock;
#endif
};

#endif // UTLMAPMT_H
Loading