X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fthread_win32_osx.h;fp=src%2Fthread_win32_osx.h;h=8890054020459b0d57ca445ed4a17b9ab6c4c66d;hp=0000000000000000000000000000000000000000;hb=bad18bccb60c874410edd3f61624696d3abc3cbc;hpb=b8efa0daac897e1b8f3efb9ca09ec4151492f1e0 diff --git a/src/thread_win32_osx.h b/src/thread_win32_osx.h new file mode 100644 index 00000000..88900540 --- /dev/null +++ b/src/thread_win32_osx.h @@ -0,0 +1,112 @@ +/* + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad + Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad + + Stockfish is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Stockfish is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef THREAD_WIN32_OSX_H_INCLUDED +#define THREAD_WIN32_OSX_H_INCLUDED + +/// STL thread library used by mingw and gcc when cross compiling for Windows +/// relies on libwinpthread. Currently libwinpthread implements mutexes directly +/// on top of Windows semaphores. Semaphores, being kernel objects, require kernel +/// mode transition in order to lock or unlock, which is very slow compared to +/// interlocked operations (about 30% slower on bench test). To work around this +/// issue, we define our wrappers to the low level Win32 calls. We use critical +/// sections to support Windows XP and older versions. Unfortunately, cond_wait() +/// is racy between unlock() and WaitForSingleObject() but they have the same +/// speed performance as the SRW locks. + +#include +#include +#include + +#if defined(_WIN32) && !defined(_MSC_VER) + +#ifndef NOMINMAX +# define NOMINMAX // Disable macros min() and max() +#endif + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#undef NOMINMAX + +/// Mutex and ConditionVariable struct are wrappers of the low level locking +/// machinery and are modeled after the corresponding C++11 classes. + +struct Mutex { + Mutex() { InitializeCriticalSection(&cs); } + ~Mutex() { DeleteCriticalSection(&cs); } + void lock() { EnterCriticalSection(&cs); } + void unlock() { LeaveCriticalSection(&cs); } + +private: + CRITICAL_SECTION cs; +}; + +typedef std::condition_variable_any ConditionVariable; + +#else // Default case: use STL classes + +typedef std::mutex Mutex; +typedef std::condition_variable ConditionVariable; + +#endif + +/// On OSX threads other than the main thread are created with a reduced stack +/// size of 512KB by default, this is dangerously low for deep searches, so +/// adjust it to TH_STACK_SIZE. The implementation calls pthread_create() with +/// proper stack size parameter. + +#if defined(__APPLE__) + +#include + +static const size_t TH_STACK_SIZE = 2 * 1024 * 1024; + +template > +void* start_routine(void* ptr) +{ + P* p = reinterpret_cast(ptr); + (p->first->*(p->second))(); // Call member function pointer + delete p; + return NULL; +} + +class NativeThread { + + pthread_t thread; + +public: + template> + explicit NativeThread(void(T::*fun)(), T* obj) { + pthread_attr_t attr_storage, *attr = &attr_storage; + pthread_attr_init(attr); + pthread_attr_setstacksize(attr, TH_STACK_SIZE); + pthread_create(&thread, attr, start_routine, new P(obj, fun)); + } + void join() { pthread_join(thread, NULL); } +}; + +#else // Default case: use STL classes + +typedef std::thread NativeThread; + +#endif + +#endif // #ifndef THREAD_WIN32_OSX_H_INCLUDED