Skip to content

Commit 89166a4

Browse files
committed
Merge branch 'master' of /Volumes/GecodeGitMigration/gecode-git
2 parents 8af0f15 + 3711622 commit 89166a4

File tree

12 files changed

+98
-90
lines changed

12 files changed

+98
-90
lines changed

changelog.in

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868

6969
[RELEASE]
7070
Version: 6.0.0
71-
Date: 2018-02-07
71+
Date: 2018-02-�23
7272
[DESCRIPTION]
7373
This major release fixes many bugs, adds quite some new
7474
functionality, and changes how cloning works (most likely the
@@ -81,6 +81,21 @@ by an array of variables), a new much faster implementation of
8181
extensional constraints using tuple sets, and support for tracing
8282
search engines.
8383

84+
[ENTRY]
85+
Module: search
86+
What: bug
87+
Rank: minor
88+
[DESCRIPTION]
89+
The statistics for parallel search engines was wrong.
90+
91+
[ENTRY]
92+
Module: search
93+
What: bug
94+
Rank: major
95+
[DESCRIPTION]
96+
Fixed several race conditions during the termination of parallel
97+
search engines.
98+
8499
[ENTRY]
85100
Module: support
86101
What: change

gecode/kernel/memory/manager.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@
3939

4040
namespace Gecode { namespace Kernel {
4141

42-
Support::Mutex SharedMemory::m;
42+
Support::Mutex& SharedMemory::m(void) {
43+
static Support::Mutex _m;
44+
return _m;
45+
}
4346

4447
void
4548
MemoryManager::alloc_refill(SharedMemory& sm, size_t sz) {

gecode/kernel/memory/manager.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ namespace Gecode { namespace Kernel {
7171
HeapChunk* hc;
7272
} heap;
7373
/// A mutex for access
74-
GECODE_KERNEL_EXPORT static Support::Mutex m;
74+
GECODE_KERNEL_EXPORT static Support::Mutex& m(void);
7575
public:
7676
/// Initialize
7777
SharedMemory(void);
@@ -200,7 +200,7 @@ namespace Gecode { namespace Kernel {
200200

201201
forceinline HeapChunk*
202202
SharedMemory::alloc(size_t s, size_t l) {
203-
m.acquire();
203+
m().acquire();
204204
while ((heap.hc != NULL) && (heap.hc->size < l)) {
205205
heap.n_hc--;
206206
HeapChunk* hc = heap.hc;
@@ -217,19 +217,19 @@ namespace Gecode { namespace Kernel {
217217
hc = heap.hc;
218218
heap.hc = static_cast<HeapChunk*>(hc->next);
219219
}
220-
m.release();
220+
m().release();
221221
return hc;
222222
}
223223
forceinline void
224224
SharedMemory::free(HeapChunk* hc) {
225-
m.acquire();
225+
m().acquire();
226226
if (heap.n_hc == MemoryConfig::n_hc_cache) {
227227
Gecode::heap.rfree(hc);
228228
} else {
229229
heap.n_hc++;
230230
hc->next = heap.hc; heap.hc = hc;
231231
}
232-
m.release();
232+
m().release();
233233
}
234234

235235

gecode/kernel/memory/region.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ namespace Gecode {
9292
~Pool(void);
9393
};
9494
/// Just use a single static pool for heap chunks
95-
GECODE_KERNEL_EXPORT Pool& pool();
95+
GECODE_KERNEL_EXPORT static Pool& pool();
9696
/// Heap information data structure
9797
class HeapInfo {
9898
public:

gecode/search/par/bab.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ namespace Gecode { namespace Search { namespace Par {
165165
mark = 0;
166166
if (best != NULL)
167167
cur->constrain(*best);
168+
Statistics t = *this;
168169
Search::Worker::reset(r_d);
170+
(*this) += t;
169171
m.release();
170172
return;
171173
}
@@ -240,8 +242,7 @@ namespace Gecode { namespace Search { namespace Par {
240242
engine().ack_terminate();
241243
// Wait until termination can proceed
242244
engine().wait_terminate();
243-
// Terminate thread
244-
engine().terminated();
245+
// Thread will be terminated by returning from run
245246
return;
246247
case C_RESET:
247248
// Acknowledge reset request

gecode/search/par/dfs.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ namespace Gecode { namespace Search { namespace Par {
136136
path.ngdl(0);
137137
d = 0;
138138
cur = s;
139+
Statistics t = *this;
139140
Search::Worker::reset(r_d);
141+
(*this) += t;
140142
m.release();
141143
return;
142144
}
@@ -188,8 +190,7 @@ namespace Gecode { namespace Search { namespace Par {
188190
engine().ack_terminate();
189191
// Wait until termination can proceed
190192
engine().wait_terminate();
191-
// Terminate thread
192-
engine().terminated();
193+
// Thread will be terminated by returning from run
193194
return;
194195
case C_RESET:
195196
// Acknowledge reset request

gecode/search/par/engine.hh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace Gecode { namespace Search { namespace Par {
4747

4848
/// %Parallel depth-first search engine
4949
template<class Tracer>
50-
class Engine : public Search::Engine {
50+
class Engine : public Search::Engine, public Support::Terminator {
5151
protected:
5252
/// %Parallel depth-first search worker
5353
class Worker : public Search::Worker, public Support::Runnable {
@@ -80,6 +80,8 @@ namespace Gecode { namespace Search { namespace Par {
8080
NoGoods& nogoods(void);
8181
/// Destructor
8282
virtual ~Worker(void);
83+
/// Terminator (engine)
84+
virtual Support::Terminator* terminator(void) const;
8385
};
8486
/// Search options
8587
Options _opt;
@@ -133,7 +135,7 @@ namespace Gecode { namespace Search { namespace Par {
133135
/// For worker to acknowledge termination command
134136
void ack_terminate(void);
135137
/// For worker to register termination
136-
void terminated(void);
138+
virtual void terminated(void);
137139
/// For worker to wait until termination is legal
138140
void wait_terminate(void);
139141
/// For engine to peform thread termination

gecode/search/par/engine.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,6 @@ namespace Gecode { namespace Search { namespace Par {
231231
// Now all threads are terminated!
232232
}
233233

234-
235-
236234
/*
237235
* Engine: reset control
238236
*/
@@ -351,6 +349,12 @@ namespace Gecode { namespace Search { namespace Par {
351349
return NULL;
352350
}
353351

352+
template<class Tracer>
353+
Support::Terminator*
354+
Engine<Tracer>::Worker::terminator(void) const {
355+
return &_engine;
356+
}
357+
354358
/*
355359
* Termination and deletion
356360
*/

gecode/support/thread.hpp

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,17 @@ namespace Gecode { namespace Support {
104104
*/
105105
class Mutex {
106106
private:
107-
#ifdef GECODE_THREADS_WINDOWS
107+
#if defined(GECODE_THREADS_WINDOWS)
108108
/// Use a simple but more efficient critical section on Windows
109109
CRITICAL_SECTION w_cs;
110-
#endif
111-
#ifdef GECODE_THREADS_PTHREADS
110+
#elif defined(GECODE_THREADS_OSX_UNFAIR)
111+
/// Use unfair lock on macOS
112+
os_unfair_lock lck;
113+
#elif defined(GECODE_THREADS_PTHREADS)
112114
/// The Pthread mutex
113115
pthread_mutex_t p_m;
116+
#else
117+
#error No suitable mutex implementation found
114118
#endif
115119
public:
116120
/// Initialize mutex
@@ -134,15 +138,11 @@ namespace Gecode { namespace Support {
134138
void operator=(const Mutex&) {}
135139
};
136140

137-
#if defined(GECODE_THREADS_WINDOWS) || !defined(GECODE_THREADS_PTHREADS)
141+
#ifndef GECODE_THREADS_PTHREADS_SPINLOCK
138142

139143
typedef Mutex FastMutex;
140144

141-
#endif
142-
143-
#ifdef GECODE_THREADS_PTHREADS
144-
145-
#if defined(GECODE_THREADS_OSX) || defined(GECODE_THREADS_OSX_UNFAIR) || defined(GECODE_THREADS_PTHREADS_SPINLOCK)
145+
#else
146146

147147
/**
148148
* \brief A fast mutex for mutual exclausion among several threads
@@ -160,16 +160,8 @@ namespace Gecode { namespace Support {
160160
*/
161161
class FastMutex {
162162
private:
163-
#ifdef GECODE_THREADS_OSX
164-
/// The OSX spin lock
165-
OSSpinLock lck;
166-
#elif defined(GECODE_THREADS_OSX_UNFAIR)
167-
/// The OSX spin lock
168-
os_unfair_lock lck;
169-
#else
170163
/// The Pthread spinlock
171164
pthread_spinlock_t p_s;
172-
#endif
173165
public:
174166
/// Initialize mutex
175167
FastMutex(void);
@@ -192,12 +184,6 @@ namespace Gecode { namespace Support {
192184
void operator=(const FastMutex&) {}
193185
};
194186

195-
#else
196-
197-
typedef Mutex FastMutex;
198-
199-
#endif
200-
201187
#endif
202188

203189
/**
@@ -259,6 +245,20 @@ namespace Gecode { namespace Support {
259245
void operator=(const Event&) {}
260246
};
261247

248+
/**
249+
* \brief An interface for objects that can be called after a
250+
* thread has terminated (after running the thread's destructor)
251+
*
252+
* \ingroup FuncSupportThread
253+
*/
254+
class Terminator {
255+
public:
256+
/// Destructor
257+
virtual ~Terminator() {}
258+
/// The function that is called when the thread has terminated
259+
virtual void terminated(void) = 0;
260+
};
261+
262262
/**
263263
* \brief An interface for objects that can be run by a thread
264264
*
@@ -275,6 +275,8 @@ namespace Gecode { namespace Support {
275275
void todelete(bool d);
276276
/// Return whether to be deleted upon termination
277277
bool todelete(void) const;
278+
/// Return terminator object
279+
virtual Terminator* terminator(void) const { return NULL; }
278280
/// The function that is executed when the thread starts
279281
virtual void run(void) = 0;
280282
/// Destructor

gecode/support/thread/pthreads.hpp

Lines changed: 25 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,30 @@
4343

4444
namespace Gecode { namespace Support {
4545

46+
#ifdef GECODE_THREADS_OSX_UNFAIR
47+
48+
/*
49+
* Mutex
50+
*/
51+
forceinline
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+
}
65+
forceinline
66+
Mutex::~Mutex(void) {}
67+
68+
#else
69+
4670
/*
4771
* Mutex
4872
*/
@@ -73,55 +97,8 @@ namespace Gecode { namespace Support {
7397
std::terminate();
7498
}
7599
}
76-
77-
#ifdef GECODE_THREADS_OSX
78-
79-
/*
80-
* FastMutex
81-
*/
82-
forceinline
83-
FastMutex::FastMutex(void) : lck(OS_SPINLOCK_INIT) {}
84-
forceinline void
85-
FastMutex::acquire(void) {
86-
OSSpinLockLock(&lck);
87-
}
88-
forceinline bool
89-
FastMutex::tryacquire(void) {
90-
return OSSpinLockTry(&lck);
91-
}
92-
forceinline void
93-
FastMutex::release(void) {
94-
OSSpinLockUnlock(&lck);
95-
}
96-
forceinline
97-
FastMutex::~FastMutex(void) {}
98-
99-
#endif
100-
101-
#ifdef GECODE_THREADS_OSX_UNFAIR
102-
103-
/*
104-
* FastMutex
105-
*/
106-
forceinline
107-
FastMutex::FastMutex(void) {}
108-
forceinline void
109-
FastMutex::acquire(void) {
110-
os_unfair_lock_lock(&lck);
111-
}
112-
forceinline bool
113-
FastMutex::tryacquire(void) {
114-
return os_unfair_lock_trylock(&lck);
115-
}
116-
forceinline void
117-
FastMutex::release(void) {
118-
os_unfair_lock_unlock(&lck);
119-
}
120-
forceinline
121-
FastMutex::~FastMutex(void) {}
122-
123100
#endif
124-
101+
125102
#ifdef GECODE_THREADS_PTHREADS_SPINLOCK
126103

127104
/*

0 commit comments

Comments
 (0)