Generated on Thu Apr 5 2018 19:44:19 for Gecode by doxygen 1.8.13
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  * Last modified:
10  * $Date$ by $Author$
11  * $Revision$
12  *
13  * This file is part of Gecode, the generic constraint
14  * development environment:
15  * http://www.gecode.org
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining
18  * a copy of this software and associated documentation files (the
19  * "Software"), to deal in the Software without restriction, including
20  * without limitation the rights to use, copy, modify, merge, publish,
21  * distribute, sublicense, and/or sell copies of the Software, and to
22  * permit persons to whom the Software is furnished to do so, subject to
23  * the following conditions:
24  *
25  * The above copyright notice and this permission notice shall be
26  * included in all copies or substantial portions of the Software.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35  *
36  */
37 
38 #ifdef GECODE_HAS_UNISTD_H
39 #include <unistd.h>
40 #endif
41 
42 #include <exception>
43 
44 namespace Gecode { namespace Support {
45 
46 #ifdef GECODE_THREADS_OSX_UNFAIR
47 
48  /*
49  * Mutex
50  */
52  Mutex::Mutex(void) : lck(OS_UNFAIR_LOCK_INIT) {}
53  forceinline void
54  Mutex::acquire(void) {
55  os_unfair_lock_lock(&lck);
56  }
57  forceinline bool
58  Mutex::tryacquire(void) {
59  return os_unfair_lock_trylock(&lck);
60  }
61  forceinline void
62  Mutex::release(void) {
63  os_unfair_lock_unlock(&lck);
64  }
66  Mutex::~Mutex(void) {}
67 
68 #else
69 
70  /*
71  * Mutex
72  */
74  Mutex::Mutex(void) {
75  if (pthread_mutex_init(&p_m,NULL) != 0)
76  throw OperatingSystemError("Mutex::Mutex[pthread_mutex_init]");
77  }
78  forceinline void
79  Mutex::acquire(void) {
80  if (pthread_mutex_lock(&p_m) != 0)
81  throw OperatingSystemError("Mutex::acquire[pthread_mutex_lock]");
82  }
83  forceinline bool
84  Mutex::tryacquire(void) {
85  return pthread_mutex_trylock(&p_m) == 0;
86  }
87  forceinline void
88  Mutex::release(void) {
89  if (pthread_mutex_unlock(&p_m) != 0)
90  throw OperatingSystemError("Mutex::release[pthread_mutex_unlock]");
91  }
93  Mutex::~Mutex(void) {
94  if (pthread_mutex_destroy(&p_m) != 0) {
95  std::cerr << "Operating system error: "
96  << "Mutex::~Mutex[pthread_mutex_destroy]";
97  std::terminate();
98  }
99  }
100 #endif
101 
102 #ifdef GECODE_THREADS_PTHREADS_SPINLOCK
103 
104  /*
105  * FastMutex
106  */
108  FastMutex::FastMutex(void) {
109  if (pthread_spin_init(&p_s,PTHREAD_PROCESS_PRIVATE) != 0)
110  throw OperatingSystemError("FastMutex::FastMutex[pthread_spin_init]");
111  }
112  forceinline void
113  FastMutex::acquire(void) {
114  if (pthread_spin_lock(&p_s) != 0)
115  throw OperatingSystemError("FastMutex::acquire[pthread_spin_lock]");
116  }
117  forceinline bool
118  FastMutex::tryacquire(void) {
119  return pthread_spin_trylock(&p_s) == 0;
120  }
121  forceinline void
122  FastMutex::release(void) {
123  if (pthread_spin_unlock(&p_s) != 0)
124  throw OperatingSystemError("FastMutex::release[pthread_spin_unlock]");
125  }
127  FastMutex::~FastMutex(void) {
128  if (pthread_spin_destroy(&p_s) != 0) {
129  std::cerr << "Operating system error: "
130  << "FastMutex::~FastMutex[pthread_spin_destroy]";
131  std::terminate();
132  }
133  }
134 
135 #endif
136 
137  /*
138  * Event
139  */
141  Event::Event(void) : p_s(false) {
142  if (pthread_mutex_init(&p_m,NULL) != 0)
143  throw OperatingSystemError("Event::Event[pthread_mutex_init]");
144  if (pthread_cond_init(&p_c,NULL) != 0)
145  throw OperatingSystemError("Event::Event[pthread_cond_init]");
146  }
147  forceinline void
148  Event::signal(void) {
149  if (pthread_mutex_lock(&p_m) != 0)
150  throw OperatingSystemError("Event::signal[pthread_mutex_lock]");
151  if (!p_s) {
152  p_s = true;
153  if (pthread_cond_signal(&p_c) != 0)
154  throw OperatingSystemError("Event::signal[pthread_cond_signal]");
155  }
156  if (pthread_mutex_unlock(&p_m) != 0)
157  throw OperatingSystemError("Event::signal[pthread_mutex_unlock]");
158  }
159  forceinline void
160  Event::wait(void) {
161  if (pthread_mutex_lock(&p_m) != 0)
162  throw OperatingSystemError("Event::wait[pthread_mutex_lock]");
163  while (!p_s)
164  if (pthread_cond_wait(&p_c,&p_m) != 0)
165  throw OperatingSystemError("Event::wait[pthread_cond_wait]");
166  p_s = false;
167  if (pthread_mutex_unlock(&p_m) != 0)
168  throw OperatingSystemError("Event::wait[pthread_mutex_unlock]");
169  }
171  Event::~Event(void) {
172  if (pthread_cond_destroy(&p_c) != 0) {
173  std::cerr << "Operating system error: "
174  << "Event::~Event[pthread_cond_destroy]";
175  std::terminate();
176  }
177  if (pthread_mutex_destroy(&p_m) != 0) {
178  std::cerr << "Operating system error: "
179  << "Event::~Event[pthread_mutex_destroy]";
180  std::terminate();
181  }
182  }
183 
184 
185  /*
186  * Thread
187  */
188  forceinline void
189  Thread::sleep(unsigned int ms) {
190 #ifdef GECODE_HAS_UNISTD_H
191  unsigned int s = ms / 1000;
192  ms -= 1000 * s;
193  if (s > 0) {
194  // More than one million microseconds, use sleep
195  ::sleep(s);
196  }
197  usleep(ms * 1000);
198 #endif
199  }
200  forceinline unsigned int
201  Thread::npu(void) {
202 #ifdef GECODE_HAS_UNISTD_H
203  int n=static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
204  return (n>1) ? n : 1;
205 #else
206  return 1;
207 #endif
208  }
209 
210 }}
211 
212 // STATISTICS: support-any
static unsigned int npu(void)
Return number of processing units (1 if information not available)
Definition: none.hpp:80
Mutex(void)
Initialize mutex.
Definition: none.hpp:44
void acquire(void)
Acquire the mutex and possibly block.
Definition: none.hpp:46
#define forceinline
Definition: config.hpp:182
void signal(void)
Signal the event.
Definition: none.hpp:63
void release(void)
Release the mutex.
Definition: none.hpp:52
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:238
static void sleep(unsigned int ms)
Put current thread to sleep for ms milliseconds.
Definition: none.hpp:78
bool tryacquire(void)
Try to acquire the mutex, return true if succesful.
Definition: none.hpp:48
~Event(void)
Delete event.
Definition: none.hpp:67
~Mutex(void)
Delete mutex.
Definition: none.hpp:54
Event(void)
Initialize event.
Definition: none.hpp:61
Mutex FastMutex
Definition: thread.hpp:143
Gecode toplevel namespace
void wait(void)
Wait until the event becomes signalled.
Definition: none.hpp:65