# define cond_signal(x) pthread_cond_signal(&(x))
# define cond_wait(x,y) pthread_cond_wait(&(x),&(y))
# define cond_timedwait(x,y,z) pthread_cond_timedwait(&(x),&(y),z)
-# define thread_create(x,f,t) !pthread_create(&(x),NULL,(pt_start_fn)f,t)
+# define thread_create(x,f,t) pthread_create(&(x),NULL,(pt_start_fn)f,t)
# define thread_join(x) pthread_join(x, NULL)
#else // Windows and MinGW
# define cond_signal(x) SetEvent(x)
# define cond_wait(x,y) { lock_release(y); WaitForSingleObject(x, INFINITE); lock_grab(y); }
# define cond_timedwait(x,y,z) { lock_release(y); WaitForSingleObject(x,z); lock_grab(y); }
-# define thread_create(x,f,t) (x = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)f,t,0,dwWin9xKludge()), x != NULL)
+# define thread_create(x,f,t) (x = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)f,t,0,dwWin9xKludge()))
# define thread_join(x) { WaitForSingleObject(x, INFINITE); CloseHandle(x); }
#endif
#include <algorithm> // For std::count
#include <cassert>
-#include <iostream>
#include "movegen.h"
#include "search.h"
ThreadPool Threads; // Global object
-namespace { extern "C" {
+namespace {
// start_routine() is the C function which is called when a new thread
// is launched. It is a wrapper to the virtual function idle_loop().
- long start_routine(Thread* th) { th->idle_loop(); return 0; }
+ extern "C" { long start_routine(Thread* th) { th->idle_loop(); return 0; } }
-} }
+
+ // Helpers to launch a thread after creation and joining before delete. Must be
+ // outside Thread c'tor and d'tor because object shall be fully initialized
+ // when start_routine (and hence virtual idle_loop) is called and when joining.
+
+ template<typename T> T* new_thread() {
+ T* th = new T();
+ thread_create(th->handle, start_routine, th);
+ return th;
+ }
+
+ void delete_thread(Thread* th) {
+ th->exit = true; // Search must be already finished
+ th->notify_one();
+ thread_join(th->handle); // Wait for thread termination
+ delete th;
+ }
+
+}
// Thread c'tor starts a newly-created thread of execution that will call
activeSplitPoint = NULL;
activePosition = NULL;
idx = Threads.size();
-
- if (!thread_create(handle, start_routine, this))
- {
- std::cerr << "Failed to create thread number " << idx << std::endl;
- ::exit(EXIT_FAILURE);
- }
-}
-
-
-// Thread d'tor waits for thread termination before to return
-
-Thread::~Thread() {
-
- exit = true; // Search must be already finished
- notify_one();
- thread_join(handle); // Wait for thread termination
}
void ThreadPool::init() {
sleepWhileIdle = true;
- timer = new TimerThread();
- push_back(new MainThread());
+ timer = new_thread<TimerThread>();
+ push_back(new_thread<MainThread>());
read_uci_options();
}
void ThreadPool::exit() {
- delete timer; // As first because check_time() accesses threads data
+ delete_thread(timer); // As first because check_time() accesses threads data
for (iterator it = begin(); it != end(); ++it)
- delete *it;
+ delete_thread(*it);
}
assert(requested > 0);
while (size() < requested)
- push_back(new Thread());
+ push_back(new_thread<Thread>());
while (size() > requested)
{
- delete back();
+ delete_thread(back());
pop_back();
}
}