]> git.sesse.net Git - stockfish/blobdiff - src/misc.cpp
Use a timer to avoid polling
[stockfish] / src / misc.cpp
index f168782518c8f48d387f8bb33687f06ef75de7b0..5e851f12f6ded08dfdebb1c967e12bd822b30367 100644 (file)
@@ -29,6 +29,7 @@
 #else
 
 #define _CRT_SECURE_NO_DEPRECATE
+#define NOMINMAX // disable macros min() and max()
 #include <windows.h>
 #include <sys/timeb.h>
 
@@ -43,6 +44,7 @@
 #include <iomanip>
 #include <iostream>
 #include <sstream>
+#include <algorithm>
 
 #include "bitcount.h"
 #include "misc.h"
@@ -54,7 +56,7 @@ using namespace std;
 /// current date (in the format YYMMDD) is used as a version number.
 
 static const string AppName = "Stockfish";
-static const string EngineVersion = "2.1";
+static const string EngineVersion = "";
 static const string AppTag  = "";
 
 
@@ -103,14 +105,14 @@ static uint64_t dbg_mean_cnt1;
 void dbg_print_hit_rate() {
 
   if (dbg_hit_cnt0)
-      cout << "Total " << dbg_hit_cnt0 << " Hit " << dbg_hit_cnt1
+      cerr << "Total " << dbg_hit_cnt0 << " Hit " << dbg_hit_cnt1
            << " hit rate (%) " << 100 * dbg_hit_cnt1 / dbg_hit_cnt0 << endl;
 }
 
 void dbg_print_mean() {
 
   if (dbg_mean_cnt0)
-      cout << "Total " << dbg_mean_cnt0 << " Mean "
+      cerr << "Total " << dbg_mean_cnt0 << " Mean "
            << (float)dbg_mean_cnt1 / dbg_mean_cnt0 << endl;
 }
 
@@ -155,16 +157,16 @@ int cpu_count() {
 #if defined(_MSC_VER)
   SYSTEM_INFO s;
   GetSystemInfo(&s);
-  return Min(s.dwNumberOfProcessors, MAX_THREADS);
+  return std::min(int(s.dwNumberOfProcessors), MAX_THREADS);
 #else
 
 #  if defined(_SC_NPROCESSORS_ONLN)
-  return Min(sysconf(_SC_NPROCESSORS_ONLN), MAX_THREADS);
+  return std::min((int)sysconf(_SC_NPROCESSORS_ONLN), MAX_THREADS);
 #  elif defined(__hpux)
   struct pst_dynamic psd;
   if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) == -1)
       return 1;
-  return Min(psd.psd_proc_cnt, MAX_THREADS);
+  return std::min((int)psd.psd_proc_cnt, MAX_THREADS);
 #  else
   return 1;
 #  endif
@@ -173,74 +175,34 @@ int cpu_count() {
 }
 
 
-/// Check for console input. Original code from Beowulf, Olithink and Greko
+/// timed_wait() waits for msec milliseconds. It is mainly an helper to wrap
+/// conversion from milliseconds to struct timespec, as used by pthreads.
 
-#ifndef _WIN32
-
-int input_available() {
-
-  fd_set readfds;
-  struct timeval  timeout;
-
-  FD_ZERO(&readfds);
-  FD_SET(fileno(stdin), &readfds);
-  timeout.tv_sec = 0; // Set to timeout immediately
-  timeout.tv_usec = 0;
-  select(16, &readfds, 0, 0, &timeout);
+#if defined(_MSC_VER)
 
-  return (FD_ISSET(fileno(stdin), &readfds));
+void timed_wait(WaitCondition* sleepCond, Lock* sleepLock, int msec) {
+  cond_timedwait(sleepCond, sleepLock, msec);
 }
 
 #else
 
-int input_available() {
-
-  static HANDLE inh = NULL;
-  static bool usePipe = false;
-  INPUT_RECORD rec[256];
-  DWORD nchars, recCnt;
-
-  if (!inh)
-  {
-      inh = GetStdHandle(STD_INPUT_HANDLE);
-      if (GetConsoleMode(inh, &nchars))
-      {
-          SetConsoleMode(inh, nchars & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
-          FlushConsoleInputBuffer(inh);
-      } else
-          usePipe = true;
-  }
-
-  // When using Standard C input functions, also check if there
-  // is anything in the buffer. After a call to such functions,
-  // the input waiting in the pipe will be copied to the buffer,
-  // and the call to PeekNamedPipe can indicate no input available.
-  // Setting stdin to unbuffered was not enough. [from Greko]
-  if (stdin->_cnt > 0)
-      return 1;
+void timed_wait(WaitCondition* sleepCond, Lock* sleepLock, int msec) {
 
-  // When running under a GUI the input commands are sent to us
-  // directly over the internal pipe. If PeekNamedPipe() returns 0
-  // then something went wrong. Probably the parent program exited.
-  // Returning 1 will make the next call to the input function
-  // return EOF, where this should be catched then.
-  if (usePipe)
-      return PeekNamedPipe(inh, NULL, 0, NULL, &nchars, NULL) ? nchars : 1;
+  struct timeval t;
+  struct timespec abstime;
 
-  // Count the number of unread input records, including keyboard,
-  // mouse, and window-resizing input records.
-  GetNumberOfConsoleInputEvents(inh, &nchars);
+  gettimeofday(&t, NULL);
 
-  // Read data from console without removing it from the buffer
-  if (nchars <= 0 || !PeekConsoleInput(inh, rec, Min(nchars, 256), &recCnt))
-      return 0;
+  abstime.tv_sec = t.tv_sec + (msec / 1000);
+  abstime.tv_nsec = (t.tv_usec + (msec % 1000) * 1000) * 1000;
 
-  // Search for at least one keyboard event
-  for (DWORD i = 0; i < recCnt; i++)
-      if (rec[i].EventType == KEY_EVENT)
-          return 1;
+  if (abstime.tv_nsec > 1000000000LL)
+  {
+      abstime.tv_sec += 1;
+      abstime.tv_nsec -= 1000000000LL;
+  }
 
-  return 0;
+  cond_timedwait(sleepCond, sleepLock, &abstime);
 }
 
 #endif