[Orxonox-commit 694] r3226 - branches/netp6/src/util

scheusso at orxonox.net scheusso at orxonox.net
Tue Jun 23 20:53:34 CEST 2009


Author: scheusso
Date: 2009-06-23 20:53:34 +0200 (Tue, 23 Jun 2009)
New Revision: 3226

Added:
   branches/netp6/src/util/Thread.cc
   branches/netp6/src/util/Thread.h
   branches/netp6/src/util/ThreadPool.cc
   branches/netp6/src/util/ThreadPool.h
Modified:
   branches/netp6/src/util/CMakeLists.txt
   branches/netp6/src/util/UtilPrereqs.h
Log:
added 2 classes:
Thread: implementation of a worker thread (you can pass (threadsafe) functions to it by wrapping them into a functor)
ThreadPool: pool of Threads. dispatches work (functors) to a thread with no work and coordinates the finishing of all threads (ideal for parallel work and synchronisation of the threads afterwards)


Modified: branches/netp6/src/util/CMakeLists.txt
===================================================================
--- branches/netp6/src/util/CMakeLists.txt	2009-06-23 18:16:29 UTC (rev 3225)
+++ branches/netp6/src/util/CMakeLists.txt	2009-06-23 18:53:34 UTC (rev 3226)
@@ -30,6 +30,8 @@
   Sleep.cc
   String.cc
   SubString.cc
+  Thread.cc
+  ThreadPool.cc
 )
 
 IF(GCC_NO_SYSTEM_HEADER_SUPPORT)

Added: branches/netp6/src/util/Thread.cc
===================================================================
--- branches/netp6/src/util/Thread.cc	                        (rev 0)
+++ branches/netp6/src/util/Thread.cc	2009-06-23 18:53:34 UTC (rev 3226)
@@ -0,0 +1,105 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Thread.h"
+
+#include <cassert>
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+
+#include "core/Functor.h"
+#include "util/Sleep.h"
+
+namespace orxonox
+{
+    boost::posix_time::millisec THREAD_WAIT_BEFORE_DETACH(1000);
+    
+    
+    Thread::Thread():
+        functor_(0),
+        isWorking_(false),
+        stopThread_(false)
+    {
+        this->communicationMutex_ = new boost::mutex;
+        this->workerThread_ = new boost::thread( boost::bind(&Thread::threadLoop, this) );
+    }
+    
+    Thread::~Thread()
+    {
+        this->stopThread_ = true;
+        if( !this->workerThread_->timed_join( THREAD_WAIT_BEFORE_DETACH ) )
+            assert(0); // this should not happen
+        delete this->workerThread_;
+        delete this->communicationMutex_;
+    }
+    
+    bool Thread::evaluateFunctor( Functor* functor )
+    {
+        if( this->communicationMutex_->try_lock() )
+        {
+            this->functor_ = functor;
+            this->communicationMutex_->unlock();
+            return true;
+        }
+        else
+            return false;
+    }
+    
+    void Thread::threadLoop()
+    {
+        while( !this->stopThread_ )
+        {
+            this->communicationMutex_->lock();
+            if( this->functor_ )
+            {
+                (*this->functor_)();
+                this->communicationMutex_->unlock();
+            }
+            else
+            {
+                this->communicationMutex_->unlock();
+                this->workerThread_->yield();
+            }
+        }
+    }
+    
+    void Thread::waitUntilFinished()
+    {
+        bool stillWorking = true;
+        while( stillWorking )
+        {
+            this->communicationMutex_->lock();
+            stillWorking = this->isWorking_;
+            this->communicationMutex_->unlock();
+            if( stillWorking )
+                msleep( 1 );
+        }
+    }
+}

Added: branches/netp6/src/util/Thread.h
===================================================================
--- branches/netp6/src/util/Thread.h	                        (rev 0)
+++ branches/netp6/src/util/Thread.h	2009-06-23 18:53:34 UTC (rev 3226)
@@ -0,0 +1,62 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Thread_H__
+#define _Thread_H__
+
+
+#include "UtilPrereqs.h"
+#include "core/CorePrereqs.h"
+
+ namespace orxonox
+{
+    
+    class Thread
+    {
+    public:
+        Thread();
+        virtual ~Thread();
+        
+        inline  bool isWorking(){ return this->isWorking_; }
+        void waitUntilFinished();
+        bool evaluateFunctor( Functor* functor );
+        
+    private:
+        void            threadLoop();
+        
+        Functor*        functor_;
+        bool            isWorking_;
+        bool            stopThread_;
+        boost::thread*  workerThread_;
+        boost::mutex*   communicationMutex_;
+    };
+    
+}
+
+
+#endif

Added: branches/netp6/src/util/ThreadPool.cc
===================================================================
--- branches/netp6/src/util/ThreadPool.cc	                        (rev 0)
+++ branches/netp6/src/util/ThreadPool.cc	2009-06-23 18:53:34 UTC (rev 3226)
@@ -0,0 +1,109 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ThreadPool.h"
+
+#include <cassert>
+
+
+namespace orxonox
+{
+    
+    
+    ThreadPool::ThreadPool()
+    {
+    }
+    
+    ThreadPool::~ThreadPool()
+    {
+    }
+    
+    void ThreadPool::addThreads( unsigned int nr )
+    {
+        for( unsigned int i=0; i<nr; i++ )
+            this->threadPool_.push_back(Thread());
+    }
+    unsigned int ThreadPool::removeThreads( unsigned int nr )
+    {
+        unsigned int i=0;
+        std::vector<Thread>::iterator it;
+        for( it = this->threadPool_.begin(); it != threadPool_.end() && i<nr; ++it )
+        {
+            if( ! it->isWorking() )
+            {
+                this->threadPool_.erase( it++ );
+                ++i;
+            }
+        }
+    }
+    unsigned int ThreadPool::setNrOfThreads( unsigned int nr )
+    {
+        unsigned int currentsize = this->threadPool_.size();
+        if ( nr < currentsize )
+            return currentsize - removeThreads( currentsize - nr );
+        else if ( nr == currentsize )
+            return currentsize;
+        else
+        {
+            addThreads( nr - currentsize );
+            return nr;
+        }
+    }
+    
+    bool ThreadPool::passFunction( Functor* functor, bool addThread )
+    {
+        std::vector<Thread>::iterator it;
+        for ( it=this->threadPool_.begin(); it!=this->threadPool_.end(); ++it )
+        {
+            if ( ! it->isWorking() )
+            {
+                bool b = it->evaluateFunctor( functor );
+                assert(b); // if b is false then there is some code error
+                return true;
+            }
+        }
+        if ( addThread )
+        {
+            addThreads( 1 );
+            this->threadPool_.back().evaluateFunctor( functor ); // access the last element
+            return true;
+        }
+        else
+            return false;
+    }
+    
+    void ThreadPool::synchronise()
+    {
+        std::vector<Thread>::iterator it;
+        for ( it=this->threadPool_.begin(); it!=this->threadPool_.end(); ++it )
+        {
+            it->waitUntilFinished();
+        }
+    }
+
+}

Added: branches/netp6/src/util/ThreadPool.h
===================================================================
--- branches/netp6/src/util/ThreadPool.h	                        (rev 0)
+++ branches/netp6/src/util/ThreadPool.h	2009-06-23 18:53:34 UTC (rev 3226)
@@ -0,0 +1,61 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ThreadPool_H__
+#define _ThreadPool_H__
+
+#include <vector>
+
+#include "UtilPrereqs.h"
+#include "Thread.h"
+
+ namespace orxonox
+{
+    
+    class ThreadPool
+    {
+    public:
+        ThreadPool();
+        virtual ~ThreadPool();
+        
+        void addThreads( unsigned int nr );
+        unsigned int removeThreads( unsigned int nr );
+        unsigned int setNrOfThreads( unsigned int nr );
+        
+        bool passFunction( Functor* functor, bool addThread=false );
+        void synchronise();
+        
+    private:
+        std::vector<Thread>     threadPool_;
+        
+    };
+    
+}
+
+
+#endif

Modified: branches/netp6/src/util/UtilPrereqs.h
===================================================================
--- branches/netp6/src/util/UtilPrereqs.h	2009-06-23 18:16:29 UTC (rev 3225)
+++ branches/netp6/src/util/UtilPrereqs.h	2009-06-23 18:53:34 UTC (rev 3226)
@@ -59,6 +59,12 @@
 //-----------------------------------------------------------------------
 // Forward declarations
 //-----------------------------------------------------------------------
+namespace boost
+{
+    class thread;
+    class mutex;
+}
+
 namespace Ogre
 {
     class Radian;
@@ -94,6 +100,8 @@
     class OutputHandler;
     class SignalHandler;
     class SubString;
+    class Thread;
+    class ThreadPool;
 }
 
 #endif /* _UtilPrereqs_H__ */




More information about the Orxonox-commit mailing list