src/threading.hpp

Go to the documentation of this file.
00001 //
00002 // Ephi - simulation of magnetic fields and particles
00003 // Copyright (C) 2007 Indrek Mandre <indrek(at)mare.ee>
00004 // For more information please see http://www.mare.ee/indrek/
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // This program is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License along
00017 // with this program; if not, write to the Free Software Foundation, Inc.,
00018 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019 //
00020 
00021 #ifndef __threading_hpp__
00022 #define __threading_hpp__
00023 
00024 #ifdef THREADS_CPUCOUNT
00025   #define PTHREADS
00026 #else
00027   #define THREADS_CPUCOUNT 1
00028 #endif
00029 
00030 #ifdef PTHREADS
00031   #include <pthread.h>
00032   #define HAVE_THREADS
00033 #endif
00034 
00035 #include <vector>
00036 
00037 class Task
00038 {
00039 protected:
00040   virtual void execute () = 0;
00041   virtual ~Task () { }
00042 
00043   friend class TaskManager;
00044 
00045 private:
00046   Task *next;
00047 };
00048 
00049 class Mutex
00050 {
00051 public:
00052   Mutex ();
00053   ~Mutex ();
00054 
00055   void lock ();
00056   void unlock ();
00057   bool trylock ();
00058 
00059 private:
00060 #ifdef PTHREADS
00061   pthread_mutex_t m;
00062 #endif
00063   friend class Condition;
00064 };
00065 
00066 class AutoMutex
00067 {
00068 public:
00069   inline AutoMutex (Mutex& m) : m(m) { this->m.lock(); }
00070   inline AutoMutex (Mutex* m) : m(*m) { this->m.lock(); }
00071   inline ~AutoMutex () { m.unlock(); }
00072 
00073 private:
00074   Mutex& m;
00075 
00076   // don't allow silly stuff
00077   AutoMutex (const AutoMutex& m);
00078   AutoMutex& operator= (const AutoMutex&);
00079 };
00080 
00081 class Condition
00082 {
00083 public:
00084   Condition (Mutex& m);
00085   ~Condition ();
00086 
00087   void wait ();
00088 
00089   void signal ();
00090   void broadcast ();
00091 
00092 private:
00093   Mutex& m;
00094 #ifdef PTHREADS
00095   pthread_cond_t cond;
00096 #endif
00097 };
00098 
00099 class TaskManager
00100 {
00101 public:
00102   TaskManager (int threads = THREADS_CPUCOUNT);
00103   ~TaskManager ();
00104 
00105   void addTask (Task *task);
00106 
00107   Task *run();
00108 
00109 private:
00110   Task *queue;
00111   Task *complete;
00112   Mutex lock;
00113   Condition work_cond;
00114   Condition ready_cond;
00115   volatile bool terminate;
00116   size_t working;
00117 
00118 #ifdef PTHREADS
00119   typedef std::vector<pthread_t> threads_t;
00120   threads_t threads;
00121 #endif
00122 
00123   static void *run_thread (void *ptr);
00124 };
00125 
00126 #endif // __threading_hpp__
00127 

Generated on Thu Dec 6 20:31:14 2007 for Ephi by  doxygen 1.5.0