this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * 6 * Copyright: 7 * Christian Schulte, 2009 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34#ifdef GECODE_HAS_UNISTD_H 35#include <unistd.h> 36#endif 37 38#include <exception> 39 40namespace Gecode { namespace Support { 41 42#ifdef GECODE_THREADS_OSX_UNFAIR 43 44#pragma clang diagnostic push 45#pragma clang diagnostic ignored "-Wdeprecated-declarations" 46 /* 47 * Mutex 48 */ 49 forceinline 50 Mutex::Mutex(void) { 51 if (&os_unfair_lock_lock != nullptr) 52 u.unfair_lck = OS_UNFAIR_LOCK_INIT; 53 else 54 u.spin_lck = OS_SPINLOCK_INIT; 55 } 56 forceinline void 57 Mutex::acquire(void) { 58 if (&os_unfair_lock_lock != nullptr) { 59 os_unfair_lock_lock(&u.unfair_lck); 60 } else { 61 OSSpinLockLock(&u.spin_lck); 62 } 63 } 64 forceinline bool 65 Mutex::tryacquire(void) { 66 if (&os_unfair_lock_trylock != nullptr) 67 return os_unfair_lock_trylock(&u.unfair_lck); 68 else 69 return OSSpinLockTry(&u.spin_lck); 70 } 71 forceinline void 72 Mutex::release(void) { 73 if (&os_unfair_lock_unlock != nullptr) 74 os_unfair_lock_unlock(&u.unfair_lck); 75 else 76 OSSpinLockUnlock(&u.spin_lck); 77 } 78 forceinline 79 Mutex::~Mutex(void) {} 80 81#pragma clang diagnostic pop 82 83#else 84 85 /* 86 * Mutex 87 */ 88 forceinline 89 Mutex::Mutex(void) { 90 if (pthread_mutex_init(&p_m,nullptr) != 0) 91 throw OperatingSystemError("Mutex::Mutex[pthread_mutex_init]"); 92 } 93 forceinline void 94 Mutex::acquire(void) { 95 if (pthread_mutex_lock(&p_m) != 0) 96 throw OperatingSystemError("Mutex::acquire[pthread_mutex_lock]"); 97 } 98 forceinline bool 99 Mutex::tryacquire(void) { 100 return pthread_mutex_trylock(&p_m) == 0; 101 } 102 forceinline void 103 Mutex::release(void) { 104 if (pthread_mutex_unlock(&p_m) != 0) 105 throw OperatingSystemError("Mutex::release[pthread_mutex_unlock]"); 106 } 107 forceinline 108 Mutex::~Mutex(void) { 109 if (pthread_mutex_destroy(&p_m) != 0) { 110 std::cerr << "Operating system error: " 111 << "Mutex::~Mutex[pthread_mutex_destroy]"; 112 std::terminate(); 113 } 114 } 115#endif 116 117#ifdef GECODE_THREADS_PTHREADS_SPINLOCK 118 119 /* 120 * FastMutex 121 */ 122 forceinline 123 FastMutex::FastMutex(void) { 124 if (pthread_spin_init(&p_s,PTHREAD_PROCESS_PRIVATE) != 0) 125 throw OperatingSystemError("FastMutex::FastMutex[pthread_spin_init]"); 126 } 127 forceinline void 128 FastMutex::acquire(void) { 129 if (pthread_spin_lock(&p_s) != 0) 130 throw OperatingSystemError("FastMutex::acquire[pthread_spin_lock]"); 131 } 132 forceinline bool 133 FastMutex::tryacquire(void) { 134 return pthread_spin_trylock(&p_s) == 0; 135 } 136 forceinline void 137 FastMutex::release(void) { 138 if (pthread_spin_unlock(&p_s) != 0) 139 throw OperatingSystemError("FastMutex::release[pthread_spin_unlock]"); 140 } 141 forceinline 142 FastMutex::~FastMutex(void) { 143 if (pthread_spin_destroy(&p_s) != 0) { 144 std::cerr << "Operating system error: " 145 << "FastMutex::~FastMutex[pthread_spin_destroy]"; 146 std::terminate(); 147 } 148 } 149 150#endif 151 152 /* 153 * Event 154 */ 155 forceinline 156 Event::Event(void) : p_s(false) { 157 if (pthread_mutex_init(&p_m,nullptr) != 0) 158 throw OperatingSystemError("Event::Event[pthread_mutex_init]"); 159 if (pthread_cond_init(&p_c,nullptr) != 0) 160 throw OperatingSystemError("Event::Event[pthread_cond_init]"); 161 } 162 forceinline void 163 Event::signal(void) { 164 if (pthread_mutex_lock(&p_m) != 0) 165 throw OperatingSystemError("Event::signal[pthread_mutex_lock]"); 166 if (!p_s) { 167 p_s = true; 168 if (pthread_cond_signal(&p_c) != 0) 169 throw OperatingSystemError("Event::signal[pthread_cond_signal]"); 170 } 171 if (pthread_mutex_unlock(&p_m) != 0) 172 throw OperatingSystemError("Event::signal[pthread_mutex_unlock]"); 173 } 174 forceinline void 175 Event::wait(void) { 176 if (pthread_mutex_lock(&p_m) != 0) 177 throw OperatingSystemError("Event::wait[pthread_mutex_lock]"); 178 while (!p_s) 179 if (pthread_cond_wait(&p_c,&p_m) != 0) 180 throw OperatingSystemError("Event::wait[pthread_cond_wait]"); 181 p_s = false; 182 if (pthread_mutex_unlock(&p_m) != 0) 183 throw OperatingSystemError("Event::wait[pthread_mutex_unlock]"); 184 } 185 forceinline 186 Event::~Event(void) { 187 if (pthread_cond_destroy(&p_c) != 0) { 188 std::cerr << "Operating system error: " 189 << "Event::~Event[pthread_cond_destroy]"; 190 std::terminate(); 191 } 192 if (pthread_mutex_destroy(&p_m) != 0) { 193 std::cerr << "Operating system error: " 194 << "Event::~Event[pthread_mutex_destroy]"; 195 std::terminate(); 196 } 197 } 198 199 200 /* 201 * Thread 202 */ 203 forceinline void 204 Thread::sleep(unsigned int ms) { 205#ifdef GECODE_HAS_UNISTD_H 206 unsigned int s = ms / 1000; 207 ms -= 1000 * s; 208 if (s > 0) { 209 // More than one million microseconds, use sleep 210 ::sleep(s); 211 } 212 usleep(ms * 1000); 213#endif 214 } 215 forceinline unsigned int 216 Thread::npu(void) { 217#ifdef GECODE_HAS_UNISTD_H 218 unsigned int n=static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN)); 219 return (n>1U) ? n : 1U; 220#else 221 return 1U; 222#endif 223 } 224 225}} 226 227// STATISTICS: support-any