along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef THREAD_WIN32_H_INCLUDED
-#define THREAD_WIN32_H_INCLUDED
+#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
#include <condition_variable>
#include <mutex>
+#include <thread>
#if defined(_WIN32) && !defined(_MSC_VER)
#endif
-#endif // #ifndef THREAD_WIN32_H_INCLUDED
+/// 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 <pthread.h>
+
+static const size_t TH_STACK_SIZE = 2 * 1024 * 1024;
+
+template <class T, class P = std::pair<T*, void(T::*)()>>
+void* start_routine(void* ptr)
+{
+ P* p = reinterpret_cast<P*>(ptr);
+ (p->first->*(p->second))(); // Call member function pointer
+ delete p;
+ return NULL;
+}
+
+class NativeThread {
+
+ pthread_t thread;
+
+public:
+ template<class T, class P = std::pair<T*, void(T::*)()>>
+ 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<T>, 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