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 const std::string osl::OslConfig::makeTest()
00264 {
00265 std::string result;
00266 if (const char *env = getenv("OSL_TEST"))
00267 trySetDir(result, env);
00268
00269 if (result.empty())
00270 result = home() + "/data";
00271
00272 std::cerr << "using " << result << " as OSL_TEST" << std::endl;
00273 return result;
00274 }
00275
00276 const std::string osl::OslConfig::makeTestPublic()
00277 {
00278 std::string result;
00279 if (const char *env = getenv("OSL_TEST_PUBLIC"))
00280 trySetDir(result, env);
00281
00282 if (result.empty())
00283 result = home() + "/public-domain";
00284
00285 std::cerr << "using " << result << " as OSL_TEST_PUBLIC" << std::endl;
00286 return result;
00287 }
00288
00289 const std::string osl::OslConfig::testPrivate()
00290 {
00291 static const std::string test_directory = makeTest();
00292 return test_directory;
00293 }
00294
00295 const std::string osl::OslConfig::testPublic()
00296 {
00297 static const std::string test_directory = makeTestPublic();
00298 return test_directory;
00299 }
00300
00301 namespace
00302 {
00303 struct NameHolder : std::map<std::string,std::string>
00304 {
00305 std::string directory;
00306
00307 NameHolder(const std::string& d) : directory(d)
00308 {
00309 directory += "/";
00310 }
00311
00312 iterator add(const std::string& key, const std::string& value)
00313 {
00314 return insert(std::make_pair(key, value)).first;
00315 }
00316 iterator addRelative(const std::string& key, const std::string& filename)
00317 {
00318 std::string value = directory + filename;
00319 return add(key, value);
00320 }
00321 iterator addRelative(const std::string& filename)
00322 {
00323 return addRelative(filename, filename);
00324 }
00325 };
00326 }
00327
00328 const char * osl::OslConfig::testPrivateFile(const std::string& filename)
00329 {
00330 static NameHolder table(testPrivate());
00331 NameHolder::iterator p=table.find(filename);
00332 if (p == table.end()) {
00333 p = table.addRelative(filename);
00334 }
00335 return p->second.c_str();
00336 }
00337
00338 const char * osl::OslConfig::testPublicFile(const std::string& filename)
00339 {
00340 static NameHolder table(testPublic());
00341 NameHolder::iterator p=table.find(filename);
00342 if (p == table.end()) {
00343 p = table.addRelative(filename);
00344 }
00345 return p->second.c_str();
00346 }
00347
00348 const char * osl::OslConfig::testCsaFile(const std::string& filename)
00349 {
00350 static NameHolder table(testPublic()+"/floodgate2010");
00351 NameHolder::iterator p=table.find(filename);
00352 if (p == table.end()) {
00353 p = table.addRelative(filename);
00354 }
00355 return p->second.c_str();
00356 }
00357
00358 const char *osl::OslConfig::openingBook(const std::string& filename)
00359 {
00360 static NameHolder table(home()+"/data");
00361 NameHolder::iterator p=table.find(filename);
00362 if (p == table.end()) {
00363 if (! filename.empty() && filename[0] == '/') {
00364
00365 p = table.add(filename, filename);
00366 }
00367 else {
00368
00369 p = table.addRelative(filename,
00370 (filename == "" ? "joseki.dat" : filename));
00371 }
00372 }
00373 return p->second.c_str();
00374 }
00375
00376
00377 size_t osl::OslConfig::residentMemoryUse()
00378 {
00379 #if defined(_WIN32)
00380 static const DWORD process_id = GetCurrentProcessId();
00381 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
00382 FALSE, process_id);
00383 if (NULL == hProcess)
00384 {
00385 std::cerr << "Failed to get residentMemoryUse()\n";
00386 return 0;
00387 }
00388
00389 size_t working_set = 0;
00390 PROCESS_MEMORY_COUNTERS pmc;
00391 if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
00392 working_set = pmc.WorkingSetSize;
00393 }
00394 CloseHandle(hProcess);
00395 return working_set;
00396 #else
00397
00398
00399 std::ifstream is("/proc/self/statm");
00400 size_t total, resident;
00401 if (is >> total >> resident)
00402 return resident*getpagesize();
00403 #ifdef __APPLE__
00404 mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
00405 task_basic_info_64 ti;
00406 if (task_info(current_task(), TASK_BASIC_INFO_64, (task_info_t)&ti, &count)
00407 == KERN_SUCCESS)
00408 return ti.resident_size;
00409 #endif
00410 #ifdef __FreeBSD__
00411 static kvm_t *kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "osl kvm_open");
00412 int nproc;
00413 kinfo_proc *pp = kvm_getprocs(kd, KERN_PROC_PID, getpid(), &nproc);
00414 if (pp)
00415 return pp->ki_rssize * getpagesize();
00416 #endif
00417 #endif
00418 return 0;
00419 }
00420
00421 #ifndef DFPNSTATONE
00422 void osl::OslConfig::setUp()
00423 {
00424 eval::ml::OpenMidEndingEval::setUp();
00425 progress::ml::NewProgress::setUp();
00426 }
00427 #endif
00428
00429 bool osl::OslConfig::healthCheck()
00430 {
00431 bool old_verbose = verbose();
00432 setVerbose(true);
00433 std::cerr << "health check\n";
00434 showOslHome(home());
00435 #ifndef DFPNSTATONE
00436 {
00437 std::string filename = eval::ml::OpenMidEndingEval::defaultFilename();
00438 std::cerr << "loading " << filename << ' ';
00439 bool success = eval::ml::OpenMidEndingEval::setUp(filename.c_str());
00440 std::cerr << (success ? "success" : "failed\a") << "\n";
00441 if (! success) {
00442 std::cerr << "exists? " << boost::filesystem::exists(filename.c_str()) << "\n";
00443 std::cerr << "regular? " << boost::filesystem::is_regular_file(filename.c_str()) << "\n";
00444 return false;
00445 }
00446 }
00447 {
00448 std::string filename = progress::ml::NewProgress::defaultFilename();
00449 std::cerr << "loading " << filename << ' ';
00450 bool success = progress::ml::NewProgress::setUp(filename.c_str());
00451 std::cerr << (success ? "success" : "failed\a") << "\n";
00452 if (! success) {
00453 std::cerr << "exists? " << boost::filesystem::exists(filename.c_str()) << "\n";
00454 std::cerr << "regular? " << boost::filesystem::is_regular_file(filename.c_str()) << "\n";
00455 return false;
00456 }
00457 }
00458 #endif
00459 setVerbose(old_verbose);
00460 return true;
00461 }
00462
00463 int osl::OslConfig::dfpnMaxDepth()
00464 {
00465 return dfpn_max_depth;
00466 }
00467 void osl::OslConfig::setDfpnMaxDepth(int new_depth)
00468 {
00469 dfpn_max_depth = new_depth;
00470 }
00471
00472
00473
00474
00475
00476