From c483ffc773c012b49f4ea2f5bd1d788c1f0dc4ac Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 25 Mar 2012 12:01:56 +0100 Subject: [PATCH 1/1] Try to mimic std::thread API No functional change. Signed-off-by: Marco Costalba --- src/platform.h | 4 ++-- src/thread.cpp | 40 +++++++++++++++------------------------- src/thread.h | 8 ++++++-- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/src/platform.h b/src/platform.h index f9739c69..64122618 100644 --- a/src/platform.h +++ b/src/platform.h @@ -53,7 +53,7 @@ inline uint64_t time_to_msec(const sys_time_t& t) { return t.tv_sec * 1000LL + t # include typedef pthread_mutex_t Lock; typedef pthread_cond_t WaitCondition; -typedef pthread_t ThreadHandle; +typedef pthread_t NativeHandle; typedef void*(*start_fn)(void*); # define lock_init(x) pthread_mutex_init(&(x), NULL) @@ -90,7 +90,7 @@ inline uint64_t time_to_msec(const sys_time_t& t) { return t.time * 1000LL + t.m // but apart from this they have the same speed performance of SRW locks. typedef CRITICAL_SECTION Lock; typedef HANDLE WaitCondition; -typedef HANDLE ThreadHandle; +typedef HANDLE NativeHandle; # define lock_init(x) InitializeCriticalSection(&(x)) # define lock_grab(x) EnterCriticalSection(&(x)) diff --git a/src/thread.cpp b/src/thread.cpp index 031ee848..d67b9fcd 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -32,37 +32,24 @@ ThreadsManager Threads; // Global object namespace { extern "C" { // start_routine() is the C function which is called when a new thread - // is launched. It simply calls idle_loop() of the supplied thread. The first - // and last thread are special. First one is the main search thread while the - // last one mimics a timer, they run in main_loop() and timer_loop(). + // is launched. It is a wrapper to member function pointed by start_fn - long start_routine(Thread* th) { - - if (th->threadID == 0) - th->main_loop(); - - else if (th->threadID == MAX_THREADS) - th->timer_loop(); - - else - th->idle_loop(NULL); - - return 0; - } + long start_routine(Thread* th) { (th->*(th->start_fn))(); return 0; } } } -// Thread c'tor creates and launches the OS thread, that will go immediately to -// sleep. +// Thread c'tor starts a newly-created thread of execution that will call +// the idle loop function pointed by start_fn going immediately to sleep. -Thread::Thread(int id) { +Thread::Thread(Fn fn) { is_searching = do_exit = false; maxPly = splitPointsCnt = 0; curSplitPoint = NULL; - threadID = id; - do_sleep = (id != 0); // Avoid a race with start_thinking() + start_fn = fn; + threadID = Threads.size(); + do_sleep = (threadID != 0); // Avoid a race with start_thinking() lock_init(sleepLock); cond_init(sleepCond); @@ -72,7 +59,7 @@ Thread::Thread(int id) { if (!thread_create(handle, start_routine, this)) { - std::cerr << "Failed to create thread number " << id << std::endl; + std::cerr << "Failed to create thread number " << threadID << std::endl; ::exit(EXIT_FAILURE); } } @@ -221,8 +208,10 @@ void ThreadsManager::read_uci_options() { useSleepingThreads = Options["Use Sleeping Threads"]; int requested = Options["Threads"]; + assert(requested > 0); + while (size() < requested) - threads.push_back(new Thread(size())); + threads.push_back(new Thread(&Thread::idle_loop)); while (size() > requested) { @@ -264,8 +253,9 @@ void ThreadsManager::init() { cond_init(sleepCond); lock_init(splitLock); - timer = new Thread(MAX_THREADS); - read_uci_options(); // Creates at least the main thread + timer = new Thread(&Thread::timer_loop); + threads.push_back(new Thread(&Thread::main_loop)); + read_uci_options(); } diff --git a/src/thread.h b/src/thread.h index 6744ef31..4b712076 100644 --- a/src/thread.h +++ b/src/thread.h @@ -70,14 +70,17 @@ class Thread { Thread(const Thread&); // Only declared to disable the default ones Thread& operator=(const Thread&); // that are not suitable in this case. + typedef void (Thread::* Fn) (); + public: - Thread(int id); + Thread(Fn fn); ~Thread(); void wake_up(); bool cutoff_occurred() const; bool is_available_to(int master) const; void idle_loop(SplitPoint* sp_master); + void idle_loop() { idle_loop(NULL); } // Hack to allow storing in start_fn void main_loop(); void timer_loop(); void wait_for_stop_or_ponderhit(); @@ -89,7 +92,8 @@ public: int maxPly; Lock sleepLock; WaitCondition sleepCond; - ThreadHandle handle; + NativeHandle handle; + Fn start_fn; SplitPoint* volatile curSplitPoint; volatile int splitPointsCnt; volatile bool is_searching; -- 2.39.5