]> git.sesse.net Git - stockfish/blobdiff - src/thread.cpp
Remove Thread::WORKISWAITING
[stockfish] / src / thread.cpp
index a8e26b9f85c43a69a3f0260db1313285ca3ccee2..f620c71c69d2640de29e098ba904f68ddcadd023 100644 (file)
@@ -27,23 +27,23 @@ ThreadsManager Threads; // Global object definition
 namespace { extern "C" {
 
  // start_routine() is the C function which is called when a new thread
- // is launched. It simply calls idle_loop() with the supplied threadID.
+ // is launched. It simply calls idle_loop() of the supplied thread.
  // There are two versions of this function; one for POSIX threads and
  // one for Windows threads.
 
 #if defined(_MSC_VER)
 
-  DWORD WINAPI start_routine(LPVOID threadID) {
+  DWORD WINAPI start_routine(LPVOID thread) {
 
-    Threads[*(int*)threadID].idle_loop(NULL);
+    ((Thread*)thread)->idle_loop(NULL);
     return 0;
   }
 
 #else
 
-  void* start_routine(void* threadID) {
+  void* start_routine(void* thread) {
 
-    Threads[*(int*)threadID].idle_loop(NULL);
+    ((Thread*)thread)->idle_loop(NULL);
     return NULL;
   }
 
@@ -63,9 +63,8 @@ void Thread::wake_up() {
 }
 
 
-// cutoff_occurred() checks whether a beta cutoff has occurred in
-// the thread's currently active split point, or in some ancestor of
-// the current split point.
+// cutoff_occurred() checks whether a beta cutoff has occurred in the current
+// active split point, or in some ancestor of the split point.
 
 bool Thread::cutoff_occurred() const {
 
@@ -126,7 +125,20 @@ void ThreadsManager::set_size(int cnt) {
   activeThreads = cnt;
 
   for (int i = 0; i < MAX_THREADS; i++)
-      threads[i].do_sleep = !(i < activeThreads);
+      if (i < activeThreads)
+      {
+          // Dynamically allocate pawn and material hash tables according to the
+          // number of active threads. This avoids preallocating memory for all
+          // possible threads if only few are used as, for instance, on mobile
+          // devices where memory is scarce and allocating for MAX_THREADS could
+          // even result in a crash.
+          threads[i].pawnTable.init();
+          threads[i].materialTable.init();
+
+          threads[i].do_sleep = false;
+      }
+      else
+          threads[i].do_sleep = true;
 }
 
 
@@ -135,14 +147,6 @@ void ThreadsManager::set_size(int cnt) {
 
 void ThreadsManager::init() {
 
-  // Threads will go to sleep as soon as created, only main thread is kept alive
-  set_size(1);
-  threads[0].state = Thread::SEARCHING;
-  threads[0].threadID = 0;
-
-  // Allocate pawn and material hash tables for main thread
-  init_hash_tables();
-
   // Initialize threads lock, used when allocating slaves during splitting
   lock_init(&threadsLock);
 
@@ -156,22 +160,28 @@ void ThreadsManager::init() {
           lock_init(&(threads[i].splitPoints[j].lock));
   }
 
-  // Create and startup all the threads but the main that is already running
+  // Initialize main thread's associated data
+  threads[0].state = Thread::SEARCHING;
+  threads[0].threadID = 0;
+  set_size(1); // This makes all the threads but the main to go to sleep
+
+  // Create and launch all the threads but the main that is already running,
+  // threads will go immediately to sleep.
   for (int i = 1; i < MAX_THREADS; i++)
   {
       threads[i].state = Thread::AVAILABLE;
       threads[i].threadID = i;
 
 #if defined(_MSC_VER)
-      threads[i].handle = CreateThread(NULL, 0, start_routine, (LPVOID)&threads[i].threadID, 0, NULL);
+      threads[i].handle = CreateThread(NULL, 0, start_routine, (LPVOID)&threads[i], 0, NULL);
       bool ok = (threads[i].handle != NULL);
 #else
-      bool ok = (pthread_create(&threads[i].handle, NULL, start_routine, (void*)&threads[i].threadID) == 0);
+      bool ok = (pthread_create(&threads[i].handle, NULL, start_routine, (void*)&threads[i]) == 0);
 #endif
 
       if (!ok)
       {
-          std::cout << "Failed to create thread number " << i << std::endl;
+          std::cerr << "Failed to create thread number " << i << std::endl;
           ::exit(EXIT_FAILURE);
       }
   }
@@ -195,7 +205,6 @@ void ThreadsManager::exit() {
           CloseHandle(threads[i].handle);
 #else
           pthread_join(threads[i].handle, NULL);
-          pthread_detach(threads[i].handle);
 #endif
       }
 
@@ -211,22 +220,6 @@ void ThreadsManager::exit() {
 }
 
 
-// init_hash_tables() dynamically allocates pawn and material hash tables
-// according to the number of active threads. This avoids preallocating
-// memory for all possible threads if only few are used as, for instance,
-// on mobile devices where memory is scarce and allocating for MAX_THREADS
-// threads could even result in a crash.
-
-void ThreadsManager::init_hash_tables() {
-
-  for (int i = 0; i < activeThreads; i++)
-  {
-      threads[i].pawnTable.init();
-      threads[i].materialTable.init();
-  }
-}
-
-
 // available_slave_exists() tries to find an idle thread which is available as
 // a slave for the thread with threadID "master".
 
@@ -310,7 +303,7 @@ Value ThreadsManager::split(Position& pos, SearchStack* ss, Value alpha, Value b
           threads[i].splitPoint = sp;
 
           // This makes the slave to exit from idle_loop()
-          threads[i].state = Thread::WORKISWAITING;
+          threads[i].state = Thread::SEARCHING;
 
           if (useSleepingThreads)
               threads[i].wake_up();
@@ -324,7 +317,6 @@ Value ThreadsManager::split(Position& pos, SearchStack* ss, Value alpha, Value b
 
   masterThread.splitPoint = sp;
   masterThread.activeSplitPoints++;
-  masterThread.state = Thread::WORKISWAITING;
 
   // Everything is set up. The master thread enters the idle loop, from
   // which it will instantly launch a search, because its state is