From d102cbcda7f040d7491326a6a567ba7fa3773b07 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 29 Aug 2012 14:43:37 -0400 Subject: [PATCH] Add threading support in core lib via boost libraries. --- Core/CMakeLists.txt | 14 ++++++++++ Core/src/TexComp.cpp | 12 +++++++-- Core/src/ThreadGroup.cpp | 58 ++++++++++++++++++++++++++++++++++++++++ Core/src/ThreadGroup.h | 53 ++++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 Core/src/ThreadGroup.cpp create mode 100644 Core/src/ThreadGroup.h diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 6af42b0..99e2d63 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -17,6 +17,16 @@ INCLUDE_DIRECTORIES( ${TexC_BINARY_DIR}/IO/include ) INCLUDE_DIRECTORIES( ${TexC_SOURCE_DIR}/Core/include ) +FIND_PACKAGE( Boost COMPONENTS thread system ) +IF( Boost_FOUND ) + INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} ) + + SET( SOURCES ${SOURCES} "src/ThreadGroup.cpp") + SET( HEADERS ${HEADERS} "src/ThreadGroup.h") + + LINK_DIRECTORIES( ${Boost_LIBRARY_DIR} ) +ENDIF() + ADD_LIBRARY( TexCompCore ${HEADERS} ${SOURCES} @@ -24,3 +34,7 @@ ADD_LIBRARY( TexCompCore TARGET_LINK_LIBRARIES( TexCompCore TexCompIO ) TARGET_LINK_LIBRARIES( TexCompCore BPTCEncoder ) + +IF( Boost_FOUND ) + TARGET_LINK_LIBRARIES( TexCompCore ${Boost_LIBRARIES} ) +ENDIF() diff --git a/Core/src/TexComp.cpp b/Core/src/TexComp.cpp index 99203f5..b0d8c09 100644 --- a/Core/src/TexComp.cpp +++ b/Core/src/TexComp.cpp @@ -1,5 +1,6 @@ #include "BC7Compressor.h" #include "TexComp.h" +#include "ThreadGroup.h" #include #include @@ -55,8 +56,15 @@ CompressedImage * CompressImage( CompressionFunc f = ChooseFuncFromSettings(settings); if(f) { - (*f)(img.GetPixels(), cmpData, img.GetWidth(), img.GetHeight()); - outImg = new CompressedImage(img.GetWidth(), img.GetHeight(), settings.format, cmpData); + if(settings.iNumThreads > 1) { + ThreadGroup tgrp (settings.iNumThreads, img, f, cmpData); + tgrp.Start(); + tgrp.Join(); + } + else { + (*f)(img.GetPixels(), cmpData, img.GetWidth(), img.GetHeight()); + outImg = new CompressedImage(img.GetWidth(), img.GetHeight(), settings.format, cmpData); + } } else { ReportError("Could not find adequate compression function for specified settings"); diff --git a/Core/src/ThreadGroup.cpp b/Core/src/ThreadGroup.cpp new file mode 100644 index 0000000..af43cbf --- /dev/null +++ b/Core/src/ThreadGroup.cpp @@ -0,0 +1,58 @@ +#include "ThreadGroup.h" + +#include +#include + +CmpThread::CmpThread() + : m_Barrier(NULL) + , m_Width(0) + , m_Height(0) + , m_CmpFunc(NULL) + , m_OutBuf(NULL) + , m_InBuf(NULL) +{ } + +void CmpThread::operator()() { + if(!m_Barrier || !m_CmpFunc || !m_OutBuf || !m_InBuf ) { + fprintf(stderr, "Incorrect thread initialization.\n"); + return; + } + + m_Barrier->wait(); +} + + +ThreadGroup::ThreadGroup( int numThreads, const ImageFile &, CompressionFunc func, unsigned char *outBuf ) + : m_Barrier(new boost::barrier(numThreads)) + , m_NumThreads(numThreads) + , m_ActiveThreads(0) +{ } + +ThreadGroup::~ThreadGroup() { + delete m_Barrier; +} + +void ThreadGroup::Start() { + + for(int i = 0; i < m_NumThreads; i++) { + + if(m_ActiveThreads >= kMaxNumThreads) + break; + + CmpThread &t = m_Threads[m_ActiveThreads]; + m_ThreadHandles[m_ActiveThreads] = new boost::thread(t); + + m_ActiveThreads++; + } + +} + +void ThreadGroup::Join() { + + for(int i = 0; i < m_ActiveThreads; i++) { + m_ThreadHandles[i]->join(); + delete m_ThreadHandles[i]; + } + + m_ActiveThreads = 0; +} diff --git a/Core/src/ThreadGroup.h b/Core/src/ThreadGroup.h new file mode 100644 index 0000000..8a08d05 --- /dev/null +++ b/Core/src/ThreadGroup.h @@ -0,0 +1,53 @@ +#ifndef _THREAD_GROUP_H_ +#define _THREAD_GROUP_H_ + +#include "TexComp.h" + +// forward declare +namespace boost { + class barrier; + class thread; +} + +struct CmpThread { + friend class ThreadGroup; + +private: + boost::barrier *m_Barrier; + + int m_Width; + int m_Height; + + CompressionFunc m_CmpFunc; + + unsigned char *m_OutBuf; + const unsigned char *m_InBuf; + + CmpThread(); + +public: + void operator ()(); +}; + + +class ThreadGroup { + public: + ThreadGroup( int numThreads, const ImageFile &, CompressionFunc func, unsigned char *outBuf ); + ~ThreadGroup(); + + void Start(); + void Join(); + + private: + boost::barrier *m_Barrier; + + static const int kMaxNumThreads = 256; + const int m_NumThreads; + + int m_ActiveThreads; + + CmpThread m_Threads[kMaxNumThreads]; + boost::thread *m_ThreadHandles[kMaxNumThreads]; +}; + +#endif // _THREAD_GROUP_H_