Generated on Thu Apr 11 13:59:20 2019 for Gecode by doxygen 1.6.3

pthreads.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  *  This file is part of Gecode, the generic constraint
00010  *  development environment:
00011  *     http://www.gecode.org
00012  *
00013  *  Permission is hereby granted, free of charge, to any person obtaining
00014  *  a copy of this software and associated documentation files (the
00015  *  "Software"), to deal in the Software without restriction, including
00016  *  without limitation the rights to use, copy, modify, merge, publish,
00017  *  distribute, sublicense, and/or sell copies of the Software, and to
00018  *  permit persons to whom the Software is furnished to do so, subject to
00019  *  the following conditions:
00020  *
00021  *  The above copyright notice and this permission notice shall be
00022  *  included in all copies or substantial portions of the Software.
00023  *
00024  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00028  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00029  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00030  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00031  *
00032  */
00033 
00034 #ifdef GECODE_HAS_UNISTD_H
00035 #include <unistd.h>
00036 #endif
00037 
00038 #include <exception>
00039 
00040 namespace Gecode { namespace Support {
00041 
00042 #ifdef GECODE_THREADS_OSX_UNFAIR
00043 
00044 #pragma clang diagnostic push
00045 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
00046   /*
00047   * Mutex
00048   */
00049   forceinline
00050   Mutex::Mutex(void) {
00051     if (&os_unfair_lock_lock != NULL)
00052       u.unfair_lck = OS_UNFAIR_LOCK_INIT;
00053     else
00054       u.spin_lck = OS_SPINLOCK_INIT;
00055   }
00056   forceinline void
00057   Mutex::acquire(void) {
00058     if (&os_unfair_lock_lock != NULL) {
00059       os_unfair_lock_lock(&u.unfair_lck);
00060     } else {
00061       OSSpinLockLock(&u.spin_lck);
00062     }
00063   }
00064   forceinline bool
00065   Mutex::tryacquire(void) {
00066     if (&os_unfair_lock_trylock != NULL)
00067       return os_unfair_lock_trylock(&u.unfair_lck);
00068     else
00069       return OSSpinLockTry(&u.spin_lck);
00070   }
00071   forceinline void
00072   Mutex::release(void) {
00073     if (&os_unfair_lock_unlock != NULL)
00074       os_unfair_lock_unlock(&u.unfair_lck);
00075     else
00076       OSSpinLockUnlock(&u.spin_lck);
00077   }
00078   forceinline
00079   Mutex::~Mutex(void) {}
00080 
00081 #pragma clang diagnostic pop
00082 
00083 #else
00084 
00085   /*
00086    * Mutex
00087    */
00088   forceinline
00089   Mutex::Mutex(void) {
00090     if (pthread_mutex_init(&p_m,NULL) != 0)
00091       throw OperatingSystemError("Mutex::Mutex[pthread_mutex_init]");
00092   }
00093   forceinline void
00094   Mutex::acquire(void) {
00095     if (pthread_mutex_lock(&p_m) != 0)
00096       throw OperatingSystemError("Mutex::acquire[pthread_mutex_lock]");
00097   }
00098   forceinline bool
00099   Mutex::tryacquire(void) {
00100     return pthread_mutex_trylock(&p_m) == 0;
00101   }
00102   forceinline void
00103   Mutex::release(void) {
00104     if (pthread_mutex_unlock(&p_m) != 0)
00105       throw OperatingSystemError("Mutex::release[pthread_mutex_unlock]");
00106   }
00107   forceinline
00108   Mutex::~Mutex(void) {
00109     if (pthread_mutex_destroy(&p_m) != 0) {
00110       std::cerr << "Operating system error: "
00111                 << "Mutex::~Mutex[pthread_mutex_destroy]";
00112       std::terminate();
00113     }
00114   }
00115 #endif
00116   
00117 #ifdef GECODE_THREADS_PTHREADS_SPINLOCK
00118 
00119   /*
00120    * FastMutex
00121    */
00122   forceinline
00123   FastMutex::FastMutex(void) {
00124     if (pthread_spin_init(&p_s,PTHREAD_PROCESS_PRIVATE) != 0)
00125       throw OperatingSystemError("FastMutex::FastMutex[pthread_spin_init]");
00126   }
00127   forceinline void
00128   FastMutex::acquire(void) {
00129     if (pthread_spin_lock(&p_s) != 0)
00130       throw OperatingSystemError("FastMutex::acquire[pthread_spin_lock]");
00131   }
00132   forceinline bool
00133   FastMutex::tryacquire(void) {
00134     return pthread_spin_trylock(&p_s) == 0;
00135   }
00136   forceinline void
00137   FastMutex::release(void) {
00138     if (pthread_spin_unlock(&p_s) != 0)
00139       throw OperatingSystemError("FastMutex::release[pthread_spin_unlock]");
00140   }
00141   forceinline
00142   FastMutex::~FastMutex(void) {
00143     if (pthread_spin_destroy(&p_s) != 0) {
00144       std::cerr << "Operating system error: "
00145                 << "FastMutex::~FastMutex[pthread_spin_destroy]";
00146       std::terminate();
00147     }
00148   }
00149 
00150 #endif
00151 
00152   /*
00153    * Event
00154    */
00155   forceinline
00156   Event::Event(void) : p_s(false) {
00157     if (pthread_mutex_init(&p_m,NULL) != 0)
00158       throw OperatingSystemError("Event::Event[pthread_mutex_init]");
00159     if (pthread_cond_init(&p_c,NULL) != 0)
00160       throw OperatingSystemError("Event::Event[pthread_cond_init]");
00161   }
00162   forceinline void
00163   Event::signal(void) {
00164     if (pthread_mutex_lock(&p_m) != 0)
00165       throw OperatingSystemError("Event::signal[pthread_mutex_lock]");
00166     if (!p_s) {
00167       p_s = true;
00168       if (pthread_cond_signal(&p_c) != 0)
00169         throw OperatingSystemError("Event::signal[pthread_cond_signal]");
00170     }
00171     if (pthread_mutex_unlock(&p_m) != 0)
00172       throw OperatingSystemError("Event::signal[pthread_mutex_unlock]");
00173   }
00174   forceinline void
00175   Event::wait(void) {
00176     if (pthread_mutex_lock(&p_m) != 0)
00177       throw OperatingSystemError("Event::wait[pthread_mutex_lock]");
00178     while (!p_s)
00179       if (pthread_cond_wait(&p_c,&p_m) != 0)
00180         throw OperatingSystemError("Event::wait[pthread_cond_wait]");
00181     p_s = false;
00182     if (pthread_mutex_unlock(&p_m) != 0)
00183       throw OperatingSystemError("Event::wait[pthread_mutex_unlock]");
00184   }
00185   forceinline
00186   Event::~Event(void) {
00187     if (pthread_cond_destroy(&p_c) != 0) {
00188       std::cerr << "Operating system error: "
00189                 << "Event::~Event[pthread_cond_destroy]";
00190       std::terminate();
00191     }
00192     if (pthread_mutex_destroy(&p_m) != 0) {
00193       std::cerr << "Operating system error: "
00194                 << "Event::~Event[pthread_mutex_destroy]";
00195       std::terminate();
00196     }
00197   }
00198 
00199 
00200   /*
00201    * Thread
00202    */
00203   forceinline void
00204   Thread::sleep(unsigned int ms) {
00205 #ifdef GECODE_HAS_UNISTD_H
00206     unsigned int s = ms / 1000;
00207     ms -= 1000 * s;
00208     if (s > 0) {
00209       // More than one million microseconds, use sleep
00210       ::sleep(s);
00211     }
00212     usleep(ms * 1000);
00213 #endif
00214   }
00215   forceinline unsigned int
00216   Thread::npu(void) {
00217 #ifdef GECODE_HAS_UNISTD_H
00218     int n=static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
00219     return (n>1) ? n : 1;
00220 #else
00221     return 1;
00222 #endif
00223   }
00224 
00225 }}
00226 
00227 // STATISTICS: support-any