mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-03 05:49:41 +03:00
amd64: fix multithread, fix vgui, fix physmodels
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -18,16 +18,21 @@
|
||||
// Purpose: Comparison function for string sorted associative data structures
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool StrLess( const char * const &pszLeft, const char * const &pszRight )
|
||||
bool StrLessInsensitive( const char * const &pszLeft, const char * const &pszRight )
|
||||
{
|
||||
return ( Q_stricmp( pszLeft, pszRight) < 0 );
|
||||
}
|
||||
|
||||
bool StrLessSensitive( const char * const &pszLeft, const char * const &pszRight )
|
||||
{
|
||||
return ( Q_strcmp( pszLeft, pszRight) < 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CStringPool::CStringPool()
|
||||
: m_Strings( 32, 256, StrLess )
|
||||
CStringPool::CStringPool( StringPoolCase_t caseSensitivity )
|
||||
: m_Strings( 32, 256, caseSensitivity == StringPoolCaseInsensitive ? StrLessInsensitive : StrLessSensitive )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -69,9 +74,7 @@ const char * CStringPool::Allocate( const char *pszValue )
|
||||
return m_Strings[i];
|
||||
|
||||
pszNew = strdup( pszValue );
|
||||
|
||||
if ( bNew )
|
||||
m_Strings.Insert( pszNew );
|
||||
m_Strings.Insert( pszNew );
|
||||
|
||||
return pszNew;
|
||||
}
|
||||
@@ -94,217 +97,6 @@ void CStringPool::FreeAll()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
CCountedStringPool::CCountedStringPool()
|
||||
{
|
||||
MEM_ALLOC_CREDIT();
|
||||
m_HashTable.EnsureCount(HASH_TABLE_SIZE);
|
||||
|
||||
for( int i = 0; i < m_HashTable.Count(); i++ )
|
||||
{
|
||||
m_HashTable[i] = INVALID_ELEMENT;
|
||||
}
|
||||
|
||||
m_FreeListStart = INVALID_ELEMENT;
|
||||
m_Elements.AddToTail();
|
||||
m_Elements[0].pString = NULL;
|
||||
m_Elements[0].nReferenceCount = 0;
|
||||
m_Elements[0].nNextElement = INVALID_ELEMENT;
|
||||
}
|
||||
|
||||
CCountedStringPool::~CCountedStringPool()
|
||||
{
|
||||
FreeAll();
|
||||
}
|
||||
|
||||
void CCountedStringPool::FreeAll()
|
||||
{
|
||||
int i;
|
||||
|
||||
// Reset the hash table:
|
||||
for( i = 0; i < m_HashTable.Count(); i++ )
|
||||
{
|
||||
m_HashTable[i] = INVALID_ELEMENT;
|
||||
}
|
||||
|
||||
// Blow away the free list:
|
||||
m_FreeListStart = INVALID_ELEMENT;
|
||||
|
||||
for( i = 0; i < m_Elements.Count(); i++ )
|
||||
{
|
||||
if( m_Elements[i].pString )
|
||||
{
|
||||
delete [] m_Elements[i].pString;
|
||||
m_Elements[i].pString = NULL;
|
||||
m_Elements[i].nReferenceCount = 0;
|
||||
m_Elements[i].nNextElement = INVALID_ELEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all but the invalid element:
|
||||
m_Elements.RemoveAll();
|
||||
m_Elements.AddToTail();
|
||||
m_Elements[0].pString = NULL;
|
||||
m_Elements[0].nReferenceCount = 0;
|
||||
m_Elements[0].nNextElement = INVALID_ELEMENT;
|
||||
}
|
||||
|
||||
|
||||
unsigned short CCountedStringPool::FindStringHandle( const char* pIntrinsic )
|
||||
{
|
||||
if( pIntrinsic == NULL )
|
||||
return INVALID_ELEMENT;
|
||||
|
||||
unsigned short nHashBucketIndex = (HashStringCaseless(pIntrinsic ) %HASH_TABLE_SIZE);
|
||||
unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ];
|
||||
|
||||
// Does the bucket already exist?
|
||||
if( nCurrentBucket != INVALID_ELEMENT )
|
||||
{
|
||||
for( ; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement )
|
||||
{
|
||||
if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) )
|
||||
{
|
||||
return nCurrentBucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
char* CCountedStringPool::FindString( const char* pIntrinsic )
|
||||
{
|
||||
if( pIntrinsic == NULL )
|
||||
return NULL;
|
||||
|
||||
// Yes, this will be NULL on failure.
|
||||
return m_Elements[FindStringHandle(pIntrinsic)].pString;
|
||||
}
|
||||
|
||||
unsigned short CCountedStringPool::ReferenceStringHandle( const char* pIntrinsic )
|
||||
{
|
||||
if( pIntrinsic == NULL )
|
||||
return INVALID_ELEMENT;
|
||||
|
||||
unsigned short nHashBucketIndex = (HashStringCaseless( pIntrinsic ) % HASH_TABLE_SIZE);
|
||||
unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ];
|
||||
|
||||
// Does the bucket already exist?
|
||||
if( nCurrentBucket != INVALID_ELEMENT )
|
||||
{
|
||||
for( ; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement )
|
||||
{
|
||||
if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) )
|
||||
{
|
||||
// Anyone who hits 65k references is permanant
|
||||
if( m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE )
|
||||
{
|
||||
m_Elements[nCurrentBucket].nReferenceCount ++ ;
|
||||
}
|
||||
return nCurrentBucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( m_FreeListStart != INVALID_ELEMENT )
|
||||
{
|
||||
nCurrentBucket = m_FreeListStart;
|
||||
m_FreeListStart = m_Elements[nCurrentBucket].nNextElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
nCurrentBucket = m_Elements.AddToTail();
|
||||
}
|
||||
|
||||
m_Elements[nCurrentBucket].nReferenceCount = 1;
|
||||
|
||||
// Insert at the beginning of the bucket:
|
||||
m_Elements[nCurrentBucket].nNextElement = m_HashTable[ nHashBucketIndex ];
|
||||
m_HashTable[ nHashBucketIndex ] = nCurrentBucket;
|
||||
|
||||
m_Elements[nCurrentBucket].pString = new char[Q_strlen( pIntrinsic ) + 1];
|
||||
Q_strcpy( m_Elements[nCurrentBucket].pString, pIntrinsic );
|
||||
|
||||
return nCurrentBucket;
|
||||
}
|
||||
|
||||
|
||||
char* CCountedStringPool::ReferenceString( const char* pIntrinsic )
|
||||
{
|
||||
if(!pIntrinsic)
|
||||
return NULL;
|
||||
|
||||
return m_Elements[ReferenceStringHandle( pIntrinsic)].pString;
|
||||
}
|
||||
|
||||
void CCountedStringPool::DereferenceString( const char* pIntrinsic )
|
||||
{
|
||||
// If we get a NULL pointer, just return
|
||||
if (!pIntrinsic)
|
||||
return;
|
||||
|
||||
unsigned short nHashBucketIndex = (HashStringCaseless( pIntrinsic ) % m_HashTable.Count());
|
||||
unsigned short nCurrentBucket = m_HashTable[ nHashBucketIndex ];
|
||||
|
||||
// If there isn't anything in the bucket, just return.
|
||||
if ( nCurrentBucket == INVALID_ELEMENT )
|
||||
return;
|
||||
|
||||
for( unsigned short previous = INVALID_ELEMENT; nCurrentBucket != INVALID_ELEMENT ; nCurrentBucket = m_Elements[nCurrentBucket].nNextElement )
|
||||
{
|
||||
if( !Q_stricmp( pIntrinsic, m_Elements[nCurrentBucket].pString ) )
|
||||
{
|
||||
// Anyone who hits 65k references is permanant
|
||||
if( m_Elements[nCurrentBucket].nReferenceCount < MAX_REFERENCE )
|
||||
{
|
||||
m_Elements[nCurrentBucket].nReferenceCount --;
|
||||
}
|
||||
|
||||
if( m_Elements[nCurrentBucket].nReferenceCount == 0 )
|
||||
{
|
||||
if( previous == INVALID_ELEMENT )
|
||||
{
|
||||
m_HashTable[nHashBucketIndex] = m_Elements[nCurrentBucket].nNextElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Elements[previous].nNextElement = m_Elements[nCurrentBucket].nNextElement;
|
||||
}
|
||||
|
||||
delete [] m_Elements[nCurrentBucket].pString;
|
||||
m_Elements[nCurrentBucket].pString = NULL;
|
||||
m_Elements[nCurrentBucket].nReferenceCount = 0;
|
||||
|
||||
m_Elements[nCurrentBucket].nNextElement = m_FreeListStart;
|
||||
m_FreeListStart = nCurrentBucket;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
previous = nCurrentBucket;
|
||||
}
|
||||
}
|
||||
|
||||
char* CCountedStringPool::HandleToString( unsigned short handle )
|
||||
{
|
||||
return m_Elements[handle].pString;
|
||||
}
|
||||
|
||||
void CCountedStringPool::SpewStrings()
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < m_Elements.Count(); i++ )
|
||||
{
|
||||
char* string = m_Elements[i].pString;
|
||||
|
||||
Msg("String %d: ref:%d %s", i, m_Elements[i].nReferenceCount, string == NULL? "EMPTY - ok for slot zero only!" : string);
|
||||
}
|
||||
|
||||
Msg("\n%d total counted strings.", m_Elements.Count());
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
CON_COMMAND( test_stringpool, "Tests the class CStringPool" )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user