Go to the documentation of this file.00001
00002
00003 #include "osl/oslConfig.h"
00004 #include "osl/config.h"
00005 #include "osl/misc/ncores.h"
00006 #include "osl/eval/ml/openMidEndingEval.h"
00007 #include "osl/progress/ml/newProgress.h"
00008 #include <boost/filesystem/operations.hpp>
00009 #include <boost/static_assert.hpp>
00010 #include <map>
00011 #include <limits>
00012 #include <iostream>
00013 #include <fstream>
00014 #include <cstdlib>
00015 #ifndef _MSC_VER
00016 # include <unistd.h>
00017 #endif
00018 #ifdef _WIN32
00019 # include <windows.h>
00020 # include <psapi.h>
00021 #else
00022 #include <sys/resource.h>
00023 #ifdef __FreeBSD__
00024 # include <kvm.h>
00025 # include <sys/param.h>
00026 # include <sys/sysctl.h>
00027 # include <sys/user.h>
00028 # include <paths.h>
00029 # include <fcntl.h>
00030 #endif
00031 #ifdef __APPLE__
00032 # include <sys/types.h>
00033 # include <sys/sysctl.h>
00034 # include <mach/task.h>
00035 # include <mach/mach_init.h>
00036 #endif
00037 #endif
00038
00039 const int osl::OslConfig::MaxThreads;
00040 unsigned int osl::OslConfig::eval_random = 0;
00041
00042 bool osl::OslConfig::is_verbose = false;
00043 #ifndef OSL_NCPUS
00044 const int osl::OslConfig::default_ncpus = osl::misc::ncores();
00045 #else
00046 BOOST_STATIC_ASSERT(OSL_NCPUS <= osl::OslConfig::MaxThreads);
00047 const int osl::OslConfig::default_ncpus = OSL_NCPUS;
00048 #endif
00049 int osl::OslConfig::num_cpu = default_ncpus;
00050 volatile osl::OslConfig::UsiMode osl::OslConfig::usi_mode = osl::OslConfig::NoUSI;
00051 volatile bool osl::OslConfig::usi_mode_silent = false,
00052 osl::OslConfig::force_root_window = false;
00053 int osl::OslConfig::usi_output_pawn_value = 100;
00054 volatile int osl::OslConfig::root_window_alpha = 0;
00055 volatile int osl::OslConfig::root_window_beta = 0;
00056 volatile int osl::OslConfig::in_unit_test = 0;
00057 int osl::OslConfig::dfpn_max_depth = 256;
00058 bool osl::OslConfig::search_exact_value_in_one_reply = false;
00059 bool osl::OslConfig::has_byoyomi = false;
00060 boost::mutex osl::OslConfig::lock_io;
00061
00062 namespace
00063 {
00064 size_t system_memory_use_limit()
00065 {
00066 #ifdef _WIN32
00067 MEMORYSTATUSEX statex;
00068 statex.dwLength = sizeof(statex);
00069 GlobalMemoryStatusEx(&statex);
00070 return statex.ullTotalPhys;
00071 #else
00072 size_t limit_by_rlimit = std::numeric_limits<size_t>::max();
00073 {
00074 rlimit rlp;
00075 if (getrlimit(RLIMIT_AS, &rlp) == 0
00076 && rlp.rlim_cur != std::numeric_limits<rlim_t>::max()) {
00077 limit_by_rlimit = rlp.rlim_cur;
00078 #ifdef __APPLE__
00079 limit_by_rlimit *= 1024;
00080 #endif
00081 std::cerr << "rlimit " << limit_by_rlimit << "\n";
00082 }
00083 }
00084 #ifdef __APPLE__
00085 {
00086 int mib[2];
00087 unsigned int usermem;
00088 size_t len=sizeof(usermem);
00089 mib[0] = CTL_HW;
00090 mib[1] = HW_USERMEM;
00091 if (sysctl(mib, 2, &usermem, &len, NULL, 0) == 0
00092 && len == sizeof(usermem)) {
00093 std::cerr << "usermem " << usermem << std::endl;
00094 return std::min((size_t)usermem, limit_by_rlimit);
00095 }
00096 }
00097 #endif
00098 {
00099 std::string name, unit;
00100 size_t value;
00101 std::ifstream is("/proc/meminfo");
00102 if (is >> name >> value >> unit
00103 && name == "MemTotal:" && unit == "kB")
00104 return std::min(value * 1024, limit_by_rlimit);
00105 }
00106 #if (defined __FreeBSD__)
00107 const long mem = sysconf(_SC_PHYS_PAGES);
00108 if (mem != -1)
00109 return std::min(mem * getpagesize(), limit_by_rlimit);
00110 #endif
00111 return std::min((rlim_t)limit_by_rlimit, std::numeric_limits<rlim_t>::max());
00112 #endif
00113 }
00114 }
00115
00116 size_t osl::OslConfig::memory_use_limit = system_memory_use_limit();
00117 const size_t osl::OslConfig::memory_use_limit_system_max =
00118 #ifdef _WIN32
00119 3000000000;
00120 #else
00121 std::numeric_limits<rlim_t>::max();
00122 #endif
00123 double osl::OslConfig::memory_use_percent = 100.0;
00124
00125 void osl::OslConfig::setNumCPUs(int ncpu)
00126 {
00127 if (ncpu > MaxThreads) {
00128 std::cerr << "ncpu " << ncpu << " > " << "MaxThreads " << MaxThreads << "\n";
00129 ncpu = MaxThreads;
00130 }
00131 num_cpu = ncpu;
00132 }
00133
00134 int osl::OslConfig::numCPUs()
00135 {
00136 return num_cpu;
00137 }
00138
00139 void osl::OslConfig::setVerbose(bool v)
00140 {
00141 is_verbose = v;
00142 }
00143
00144 bool osl::OslConfig::verbose()
00145 {
00146 return is_verbose;
00147 }
00148
00149 osl::OslConfig::UsiMode osl::OslConfig::usiMode()
00150 {
00151 return usi_mode;
00152 }
00153 void osl::OslConfig::setUsiMode(UsiMode enable)
00154 {
00155 usi_mode = enable;
00156 }
00157 bool osl::OslConfig::usiModeInSilent()
00158 {
00159 return usi_mode_silent;
00160 }
00161 void osl::OslConfig::setUsiSilent(bool enable)
00162 {
00163 usi_mode_silent = enable;
00164 }
00165 bool osl::OslConfig::searchExactValueInOneReply()
00166 {
00167 return search_exact_value_in_one_reply;
00168 }
00169 void osl::OslConfig::setSearchExactValueInOneReply(bool enable)
00170 {
00171 search_exact_value_in_one_reply = enable;
00172 }
00173
00174 bool osl::OslConfig::hasByoyomi()
00175 {
00176 return has_byoyomi;
00177 }
00178
00179 void osl::OslConfig::setHasByoyomi(bool value)
00180 {
00181 has_byoyomi = value;
00182 }
00183
00184 void osl::OslConfig::showOslHome(const std::string& home)
00185 {
00186 std::cerr << "using " << home << " as OSL_HOME, word size "
00187 << OSL_WORDSIZE << std::endl;
00188 }
00189
00190 void osl::OslConfig::showOslHome()
00191 {
00192 showOslHome(home());
00193 }
00194
00195 bool osl::OslConfig::isGoodDir(const std::string& dir)
00196 {
00197 return boost::filesystem::exists(dir)
00198 && boost::filesystem::is_directory(dir);
00199 }
00200
00201 void osl::OslConfig::trySetDir(std::string& dir, const std::string& candidate)
00202 {
00203 if (isGoodDir(candidate))
00204 {
00205 dir = candidate;
00206 return;
00207 }
00208 if (verbose())
00209 std::cerr << "skipping " << candidate << std::endl;
00210 }
00211
00212 const std::string osl::OslConfig::makeHome()
00213 {
00214 std::string result;
00215 if (const char *env = getenv("GPSSHOGI_HOME"))
00216 trySetDir(result, env);
00217
00218 #if defined GPSSHOGI_HOME
00219 if (result.empty())
00220 trySetDir(result, GPSSHOGI_HOME);
00221 #endif
00222
00223 if (result.empty())
00224 if (const char *env = getenv("OSL_HOME"))
00225 trySetDir(result, env);
00226
00227 if (result.empty())
00228 result = OSL_HOME;
00229
00230 if (verbose())
00231 showOslHome(result);
00232 return result;
00233 }
00234
00235 const std::string& osl::OslConfig::home()
00236 {
00237 static const std::string home_directory = makeHome();
00238 return home_directory;
00239 }
00240
00241 const char * osl::OslConfig::home_c_str()
00242 {
00243 return home().c_str();
00244 }
00245
00246 const std::string osl::OslConfig::gpsusiConf()
00247 {
00248
00249
00250
00251 #ifdef OSL_PUBLIC_RELEASE
00252
00253 if (const char *env = getenv("HOME"))
00254 return std::string(env) + "/gpsusi.conf";
00255 if (const char *env = getenv("USERPROFILE"))
00256 return std::string(env) + "/gpsusi.conf";
00257 #endif
00258
00259 static const std::string home_directory = makeHome();
00260 return home_directory + "/gpsusi.conf";
00261 }
00262
00263 int osl::OslConfig::resignThreshold()
00264 {
00265 static const int value = getenv("OSL_RESIGN_VALUE")
00266 ? atoi(getenv("OSL_RESIGN_VALUE")) : 0;
00267 return (value > 0) ? value : 10000;
00268 }
00269
00270 const std::string osl::OslConfig::makeTest()
00271 {
00272 std::string result;
00273 if (const char *env = getenv("OSL_TEST"))
00274 trySetDir(result, env);
00275
00276 if (result.empty())
00277 result = home() + "/data";
00278
00279 std::cerr << "using " << result << " as OSL_TEST" << std::endl;
00280 return result;
00281 }
00282
00283 const std::string osl::OslConfig::makeTestPublic()
00284 {
00285 std::string result;
00286 if (const char *env = getenv("OSL_TEST_PUBLIC"))
00287 trySetDir(result, env);
00288
00289 if (result.empty())
00290 result = home() + "/public-domain";
00291
00292 std::cerr << "using " << result << " as OSL_TEST_PUBLIC" << std::endl;
00293 return result;
00294 }
00295
00296 const std::string osl::OslConfig::testPrivate()
00297 {
00298 static const std::string test_directory = makeTest();
00299 return test_directory;
00300 }
00301
00302 const std::string osl::OslConfig::testPublic()
00303 {
00304 static const std::string test_directory = makeTestPublic();
00305 return test_directory;
00306 }
00307
00308 namespace
00309 {
00310 struct NameHolder : std::map<std::string,std::string>
00311 {
00312 std::string directory;
00313
00314 NameHolder(const std::string& d) : directory(d)
00315 {
00316 directory += "/";
00317 }
00318
00319 iterator add(const std::string& key, const std::string& value)
00320 {
00321 return insert(std::make_pair(key, value)).first;
00322 }
00323 iterator addRelative(const std::string& key, const std::string& filename)
00324 {
00325 std::string value = directory + filename;
00326 return add(key, value);
00327 }
00328 iterator addRelative(const std::string& filename)
00329 {
00330 return addRelative(filename, filename);
00331 }
00332 };
00333 }
00334
00335 const char * osl::OslConfig::testPrivateFile(const std::string& filename)
00336 {
00337 static NameHolder table(testPrivate());
00338 NameHolder::iterator p=table.find(filename);
00339 if (p == table.end()) {
00340 p = table.addRelative(filename);
00341 }
00342 return p->second.c_str();
00343 }
00344
00345 const char * osl::OslConfig::testPublicFile(const std::string& filename)
00346 {
00347 static NameHolder table(testPublic());
00348 NameHolder::iterator p=table.find(filename);
00349 if (p == table.end()) {
00350 p = table.addRelative(filename);
00351 }
00352 return p->second.c_str();
00353 }
00354
00355 const char * osl::OslConfig::testCsaFile(const std::string& filename)
00356 {
00357 static NameHolder table(testPublic()+"/floodgate2010");
00358 NameHolder::iterator p=table.find(filename);
00359 if (p == table.end()) {
00360 p = table.addRelative(filename);
00361 }
00362 return p->second.c_str();
00363 }
00364
00365 const char *osl::OslConfig::openingBook(const std::string& filename)
00366 {
00367 static NameHolder table(home()+"/data");
00368 NameHolder::iterator p=table.find(filename);
00369 if (p == table.end()) {
00370 if (! filename.empty() && filename[0] == '/') {
00371
00372 p = table.add(filename, filename);
00373 }
00374 else {
00375
00376 p = table.addRelative(filename,
00377 (filename == "" ? "joseki.dat" : filename));
00378 }
00379 }
00380 return p->second.c_str();
00381 }
00382
00383
00384 size_t osl::OslConfig::residentMemoryUse()
00385 {
00386 #if defined(_WIN32)
00387 static const DWORD process_id = GetCurrentProcessId();
00388 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
00389 FALSE, process_id);
00390 if (NULL == hProcess)
00391 {
00392 std::cerr << "Failed to get residentMemoryUse()\n";
00393 return 0;
00394 }
00395
00396 size_t working_set = 0;
00397 PROCESS_MEMORY_COUNTERS pmc;
00398 if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
00399 working_set = pmc.WorkingSetSize;
00400 }
00401 CloseHandle(hProcess);
00402 return working_set;
00403 #else
00404
00405
00406 std::ifstream is("/proc/self/statm");
00407 size_t total, resident;
00408 if (is >> total >> resident)
00409 return resident*getpagesize();
00410 #ifdef __APPLE__
00411 mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
00412 task_basic_info_64 ti;
00413 if (task_info(current_task(), TASK_BASIC_INFO_64, (task_info_t)&ti, &count)
00414 == KERN_SUCCESS)
00415 return ti.resident_size;
00416 #endif
00417 #ifdef __FreeBSD__
00418 static kvm_t *kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "osl kvm_open");
00419 int nproc;
00420 kinfo_proc *pp = kvm_getprocs(kd, KERN_PROC_PID, getpid(), &nproc);
00421 if (pp)
00422 return pp->ki_rssize * getpagesize();
00423 #endif
00424 #endif
00425 return 0;
00426 }
00427
00428 #ifndef DFPNSTATONE
00429 void osl::OslConfig::setUp()
00430 {
00431 eval::ml::OpenMidEndingEval::setUp();
00432 progress::ml::NewProgress::setUp();
00433 }
00434 #endif
00435
00436 bool osl::OslConfig::healthCheck()
00437 {
00438 bool old_verbose = verbose();
00439 setVerbose(true);
00440 std::cerr << "health check\n";
00441 showOslHome(home());
00442 #ifndef DFPNSTATONE
00443 {
00444 std::string filename = eval::ml::OpenMidEndingEval::defaultFilename();
00445 std::cerr << "loading " << filename << ' ';
00446 bool success = eval::ml::OpenMidEndingEval::setUp(filename.c_str());
00447 std::cerr << (success ? "success" : "failed\a") << "\n";
00448 if (! success) {
00449 std::cerr << "exists? " << boost::filesystem::exists(filename.c_str()) << "\n";
00450 std::cerr << "regular? " << boost::filesystem::is_regular_file(filename.c_str()) << "\n";
00451 return false;
00452 }
00453 }
00454 {
00455 std::string filename = progress::ml::NewProgress::defaultFilename();
00456 std::cerr << "loading " << filename << ' ';
00457 bool success = progress::ml::NewProgress::setUp(filename.c_str());
00458 std::cerr << (success ? "success" : "failed\a") << "\n";
00459 if (! success) {
00460 std::cerr << "exists? " << boost::filesystem::exists(filename.c_str()) << "\n";
00461 std::cerr << "regular? " << boost::filesystem::is_regular_file(filename.c_str()) << "\n";
00462 return false;
00463 }
00464 }
00465 #endif
00466 setVerbose(old_verbose);
00467 return true;
00468 }
00469
00470 int osl::OslConfig::dfpnMaxDepth()
00471 {
00472 return dfpn_max_depth;
00473 }
00474 void osl::OslConfig::setDfpnMaxDepth(int new_depth)
00475 {
00476 dfpn_max_depth = new_depth;
00477 }
00478
00479
00480
00481
00482
00483