From fcbca9ca8d82dfa360ed0c06da61722ca40dc1e3 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sat, 6 Oct 2012 17:52:26 -0400 Subject: [PATCH] Add files for new block stats in order to track things in our compression algorithms --- Core/CMakeLists.txt | 4 +- Core/include/BlockStats.h | 59 ++++++++++++++++ Core/include/ReferenceCounter.h | 49 ++++++++++++++ Core/{src => include}/Thread.h | 0 Core/src/BlockStats.cpp | 115 ++++++++++++++++++++++++++++++++ 5 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 Core/include/BlockStats.h create mode 100644 Core/include/ReferenceCounter.h rename Core/{src => include}/Thread.h (100%) create mode 100644 Core/src/BlockStats.cpp diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 9ab1535..9ad6d03 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -3,6 +3,7 @@ SET( SOURCES "src/TexComp.cpp" "src/CompressedImage.cpp" "src/Image.cpp" + "src/BlockStats.cpp" ) SET( HEADERS @@ -10,6 +11,7 @@ SET( HEADERS "include/CompressedImage.h" "include/TexCompTypes.h" "include/Image.h" + "include/BlockStats.h" ) # Make sure to add the appropriate stopwatch files... @@ -82,7 +84,7 @@ ELSE() SET( SOURCES ${SOURCES} "src/ThreadGroup.cpp" ) SET( SOURCES ${SOURCES} "src/WorkerQueue.cpp" ) - SET( HEADERS ${HEADERS} "src/Thread.h" ) + SET( HEADERS ${HEADERS} "include/Thread.h" ) SET( HEADERS ${HEADERS} "src/ThreadGroup.h" ) SET( HEADERS ${HEADERS} "src/WorkerQueue.h" ) ENDIF() diff --git a/Core/include/BlockStats.h b/Core/include/BlockStats.h new file mode 100644 index 0000000..23af5e8 --- /dev/null +++ b/Core/include/BlockStats.h @@ -0,0 +1,59 @@ +#ifndef __BLOCK_STATS_H__ +#define __BLOCK_STATS_H__ + +#include "TexCompTypes.h" +#include "ReferenceCounter.h" +#include "Thread.h" + +struct BlockStat { + friend class BlockStatManager; +public: + BlockStat(const CHAR *statName, uint64 stat); + BlockStat(const CHAR *statName, double stat); + + BlockStat(const BlockStat &); + BlockStat &operator=(const BlockStat &); + +private: + static const int kStatNameSz = 32; + char m_StatName[kStatNameSz]; + union { + uint64 m_IntStat; + double m_FloatStat; + }; +}; + +class BlockStatManager { + + public: + BlockStatManager(int nBlocks); + ~BlockStatManager(); + + uint32 BeginBlock(); + void AddStat(uint32 blockIdx, const BlockStat &stat); + + private: + + class BlockStatList { + public: + BlockStatList(); + ~BlockStatList(); + + void AddStat(const BlockStat &stat); + + private: + BlockStatList(const BlockStat &stat); + + BlockStat m_Stat; + BlockStatList *m_Tail; + + ReferenceCounter m_Counter; + } *m_BlockStatList; + uint32 m_BlockStatListSz; + + TCMutex m_Mutex; + uint32 m_NextBlock; + ReferenceCounter m_Counter; +}; + +#endif // __BLOCK_STATS_H__ diff --git a/Core/include/ReferenceCounter.h b/Core/include/ReferenceCounter.h new file mode 100644 index 0000000..85c1f8f --- /dev/null +++ b/Core/include/ReferenceCounter.h @@ -0,0 +1,49 @@ +#ifndef __REFERENCE_COUNTER_H__ +#define __REFERENCE_COUNTER_H__ + +#include "TexCompTypes.h" + +class ReferenceCounter { + public: + ReferenceCounter() : m_ReferenceCount( new uint32 ) { + *m_ReferenceCount = 1; + } + ReferenceCounter(const ReferenceCounter &other) + : m_ReferenceCount(other.m_ReferenceCount) { + IncRefCount(); + } + + ReferenceCounter &operator=(const ReferenceCounter &other) { + DecRefCount(); + m_ReferenceCount = other.m_ReferenceCount; + IncRefCount(); + } + + uint32 GetRefCount() const { + if(m_ReferenceCount) + return *m_ReferenceCount; + else + return 0; + } + + void DecRefCount() { + if(!m_ReferenceCount) return; + + (*m_ReferenceCount)--; + + if(*m_ReferenceCount == 0) { + delete m_ReferenceCount; + m_ReferenceCount = 0; + } + } + + void IncRefCount() { + if(!m_ReferenceCount) return; + (*m_ReferenceCount)++; + } + + private: + uint32 *m_ReferenceCount; +}; + +#endif // __REFERENCE_COUNTER_H__ diff --git a/Core/src/Thread.h b/Core/include/Thread.h similarity index 100% rename from Core/src/Thread.h rename to Core/include/Thread.h diff --git a/Core/src/BlockStats.cpp b/Core/src/BlockStats.cpp new file mode 100644 index 0000000..ce29d57 --- /dev/null +++ b/Core/src/BlockStats.cpp @@ -0,0 +1,115 @@ +#include "BlockStats.h" + +#include +#include +#include +#include + +template +static T max(const T &a, const T &b) { + return (a > b)? a : b; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// BlockStat implementation +// +//////////////////////////////////////////////////////////////////////////////// + +BlockStat::BlockStat(const CHAR *statName, double stat) : + m_FloatStat(stat) +{ + strncpy(m_StatName, statName, kStatNameSz); +} + +BlockStat::BlockStat(const BlockStat &other) { + memcpy(this, &other, sizeof(*this)); +} + +BlockStat &BlockStat::operator=(const BlockStat &other) { + memcpy(this, &other, sizeof(*this)); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// BlockStat Manager Implementation +// +//////////////////////////////////////////////////////////////////////////////// + +BlockStatManager::BlockStatManager(int nBlocks) + : m_BlockStatListSz(max(nBlocks, 0)) + , m_NextBlock(0) +{ + m_BlockStatList = new BlockStatList[m_BlockStatListSz]; + if(!m_BlockStatList) { + fprintf(stderr, "Out of memory!\n"); + assert(false); + exit(1); + } +} + +BlockStatManager::~BlockStatManager() { + if(m_Counter.GetRefCount() == 0) { + delete [] m_BlockStatList; + } +} + +uint32 BlockStatManager::BeginBlock() { + if((m_NextBlock + 1) == m_BlockStatListSz) { + fprintf(stderr, "WARNING -- BlockStatManager::BeginBlock(), reached end of block list.\n"); + assert(false); + return m_NextBlock; + } + + TCLock lock(m_Mutex); + return m_NextBlock++; +} + +void BlockStatManager::AddStat(uint32 blockIdx, const BlockStat &stat) { + if(blockIdx >= m_BlockStatListSz) { + fprintf(stderr, "WARNING -- BlockStatManager::AddStat(), block index out of bounds!\n"); + assert(false); + return; + } + + m_BlockStatList[blockIdx].AddStat(stat); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// BlockStat List Implementation +// +//////////////////////////////////////////////////////////////////////////////// +static const CHAR *kNullBlockString = "NULL_BLOCK_STAT"; +static const uint32 kNullBlockStringLength = strlen(kNullBlockString); + +BlockStatManager::BlockStatList::BlockStatList() + : m_Tail(0) + , m_Stat(kNullBlockString, 0.0) +{ } + +BlockStatManager::BlockStatList::BlockStatList(const BlockStat &stat) + : m_Tail(0) + , m_Stat(stat) +{ +} + +BlockStatManager::BlockStatList::~BlockStatList() { + if(m_Counter.GetRefCount() == 0 && m_Tail) { + delete m_Tail; + } +} + +void BlockStatManager::BlockStatList::AddStat(const BlockStat &stat) { + if(!m_Tail) { + m_Tail->AddStat(stat); + } + else { + if(strncmp(m_Stat.m_StatName, kNullBlockString, kNullBlockStringLength) == 0) { + m_Stat = stat; + } + else { + m_Tail = new BlockStatList(stat); + } + } +}