Generated on Sun Aug 9 2020 05:34:08 for Gecode by doxygen 1.8.18
pthreads.hpp
Go to the documentation of this file.
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 
40 namespace 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  */
50  Mutex::Mutex(void) {
51  if (&os_unfair_lock_lock != NULL)
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 != NULL) {
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 != NULL)
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 != NULL)
74  os_unfair_lock_unlock(&u.unfair_lck);
75  else
76  OSSpinLockUnlock(&u.spin_lck);
77  }
79  Mutex::~Mutex(void) {}
80 
81 #pragma clang diagnostic pop
82 
83 #else
84 
85  /*
86  * Mutex
87  */
89  Mutex::Mutex(void) {
90  if (pthread_mutex_init(&p_m,NULL) != 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  }
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  */
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  }
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  */
156  Event::Event(void) : p_s(false) {
157  if (pthread_mutex_init(&p_m,NULL) != 0)
158  throw OperatingSystemError("Event::Event[pthread_mutex_init]");
159  if (pthread_cond_init(&p_c,NULL) != 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  }
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  int n=static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
219  return (n>1) ? n : 1;
220 #else
221  return 1;
222 #endif
223  }
224 
225 }}
226 
227 // STATISTICS: support-any
void acquire(void)
Acquire the mutex and possibly block.
Definition: none.hpp:42
Mutex FastMutex
Definition: thread.hpp:140
Event(void)
Initialize event.
Definition: none.hpp:57
Gecode toplevel namespace
union Gecode::@602::NNF::@65 u
Union depending on nodetype t.
Mutex(void)
Initialize mutex.
Definition: none.hpp:40
bool tryacquire(void)
Try to acquire the mutex, return true if succesful.
Definition: none.hpp:44
~Mutex(void)
Delete mutex.
Definition: none.hpp:50
void wait(Home home, FloatVar x, std::function< void(Space &home)> c)
Execute c when x becomes assigned.
Definition: exec.cpp:39
#define forceinline
Definition: config.hpp:185
void release(void)
Release the mutex.
Definition: none.hpp:48
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:234