Generated on Tue May 22 09:40:17 2018 for Gecode by doxygen 1.6.3

thread.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2009
00008  *
00009  *  Bugfixes provided by:
00010  *     David Rijsman <david.rijsman@quintiq.com>
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  Permission is hereby granted, free of charge, to any person obtaining
00017  *  a copy of this software and associated documentation files (the
00018  *  "Software"), to deal in the Software without restriction, including
00019  *  without limitation the rights to use, copy, modify, merge, publish,
00020  *  distribute, sublicense, and/or sell copies of the Software, and to
00021  *  permit persons to whom the Software is furnished to do so, subject to
00022  *  the following conditions:
00023  *
00024  *  The above copyright notice and this permission notice shall be
00025  *  included in all copies or substantial portions of the Software.
00026  *
00027  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00028  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00029  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00030  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00031  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00032  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00033  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00034  *
00035  */
00036 
00037 #include <cstddef>
00038 
00039 #ifdef GECODE_THREADS_WINDOWS
00040 
00041 #ifndef NOMINMAX
00042 #  define NOMINMAX
00043 #endif
00044 
00045 #ifndef _WIN32_WINNT
00046 #  define _WIN32_WINNT 0x400
00047 #endif
00048 
00049 #ifndef WIN32_LEAN_AND_MEAN
00050 #  define WIN32_LEAN_AND_MEAN
00051 #endif
00052 
00053 #include <windows.h>
00054 
00055 #endif
00056 
00057 #ifdef GECODE_THREADS_PTHREADS
00058 
00059 #include <pthread.h>
00060 
00061 #ifdef GECODE_THREADS_OSX_UNFAIR
00062 
00063 #include <os/lock.h>
00064 #include <libkern/OSAtomic.h>
00065 
00066 #endif
00067 
00068 #endif
00069 
00085 namespace Gecode { namespace Support {
00086 
00096   class Mutex {
00097   private:
00098 #if defined(GECODE_THREADS_WINDOWS)
00099 
00100     CRITICAL_SECTION w_cs;
00101 #elif defined(GECODE_THREADS_OSX_UNFAIR)
00102 
00103     union {
00104       os_unfair_lock unfair_lck;
00105 #pragma clang diagnostic push
00106 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
00107       OSSpinLock spin_lck;
00108 #pragma clang diagnostic pop
00109     } u;
00110 #elif defined(GECODE_THREADS_PTHREADS)
00111 
00112     pthread_mutex_t p_m;
00113 #else
00114 #error No suitable mutex implementation found
00115 #endif
00116   public:
00118     Mutex(void);
00120     void acquire(void);
00122     bool tryacquire(void);
00124     void release(void);
00126     ~Mutex(void);
00128     static void* operator new(size_t s);
00130     static void  operator delete(void* p);
00131   private:
00133     Mutex(const Mutex&) {}
00135     void operator=(const Mutex&) {}
00136   };
00137 
00138 #ifndef GECODE_THREADS_PTHREADS_SPINLOCK
00139 
00140   typedef Mutex FastMutex;
00141 
00142 #else
00143 
00158   class FastMutex {
00159   private:
00161     pthread_spinlock_t p_s;
00162   public:
00164     FastMutex(void);
00166     void acquire(void);
00168     bool tryacquire(void);
00170     void release(void);
00172     ~FastMutex(void);
00174     static void* operator new(size_t s);
00176     static void  operator delete(void* p);
00177   private:
00179     FastMutex(const FastMutex&) {}
00181     void operator=(const FastMutex&) {}
00182   };
00183 
00184 #endif
00185 
00191   class Lock {
00192   private:
00194     Mutex& m;
00195   public:
00197     Lock(Mutex& m0);
00199     ~Lock(void);
00200   private:
00202     Lock(const Lock& l) : m(l.m) {}
00204     void operator=(const Lock&) {}
00205   };
00206 
00215   class Event {
00216   private:
00217 #ifdef GECODE_THREADS_WINDOWS
00218 
00219     HANDLE w_h;
00220 #endif
00221 #ifdef GECODE_THREADS_PTHREADS
00222 
00223     pthread_mutex_t p_m;
00225     pthread_cond_t p_c;
00227     bool p_s;
00228 #endif
00229   public:
00231     Event(void);
00233     void signal(void);
00235     void wait(void);
00237     ~Event(void);
00238   private:
00240     Event(const Event&) {}
00242     void operator=(const Event&) {}
00243   };
00244 
00251   class Terminator {
00252   public:
00254     virtual ~Terminator() {}
00256     virtual void terminated(void) = 0;
00257   };
00258 
00264   class Runnable {
00265   private:
00267     bool d;
00268   public:
00270     Runnable(bool d=true);
00272     void todelete(bool d);
00274     bool todelete(void) const;
00276     virtual Terminator* terminator(void) const { return NULL; }
00278     virtual void run(void) = 0;
00280     virtual ~Runnable(void) {}
00282     static void* operator new(size_t s);
00284     static void  operator delete(void* p);
00285   };
00286 
00296   class Thread {
00297   public:
00299     class Run {
00300     public:
00302       Run* n;
00304       Runnable* r;
00306       Event e;
00308       Mutex m;
00310       GECODE_SUPPORT_EXPORT Run(Runnable* r);
00312       GECODE_SUPPORT_EXPORT void exec(void);
00314       void run(Runnable* r);
00316       static void* operator new(size_t s);
00318       static void  operator delete(void* p);
00319     };
00321     GECODE_SUPPORT_EXPORT static Mutex* m(void);
00323     GECODE_SUPPORT_EXPORT static Run* idle;
00324   public:
00334     static void run(Runnable* r);
00336     static void sleep(unsigned int ms);
00338     static unsigned int npu(void);
00339   private:
00341     Thread(const Thread&) {}
00343     void operator=(const Thread&) {}
00344   };
00345 
00346 }}
00347 
00348 // STATISTICS: support-any