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 <map>
00009 #include <boost/filesystem/operations.hpp>
00010 #include <boost/static_assert.hpp>
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 bool osl::OslConfig::usi_mode = false,
00051 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 bool osl::OslConfig::search_exact_value_in_one_reply = false;
00058 bool osl::OslConfig::has_byoyomi = false;
00059 boost::mutex osl::OslConfig::lock_io;
00060
00061 namespace
00062 {
00063 size_t system_memory_use_limit()
00064 {
00065 #ifdef _WIN32
00066 MEMORYSTATUSEX statex;
00067 statex.dwLength = sizeof(statex);
00068 GlobalMemoryStatusEx(&statex);
00069 return statex.ullTotalPhys;
00070 #else
00071 size_t limit_by_rlimit = std::numeric_limits<size_t>::max();
00072 {
00073 rlimit rlp;
00074 if (getrlimit(RLIMIT_AS, &rlp) == 0
00075 && rlp.rlim_cur != std::numeric_limits<rlim_t>::max()) {
00076 limit_by_rlimit = rlp.rlim_cur;
00077 #ifdef __APPLE__
00078 limit_by_rlimit *= 1024;
00079 #endif
00080 std::cerr << "rlimit " << limit_by_rlimit << "\n";
00081 }
00082 }
00083 #ifdef __APPLE__
00084 {
00085 int mib[2];
00086 unsigned int usermem;
00087 size_t len=sizeof(usermem);
00088 mib[0] = CTL_HW;
00089 mib[1] = HW_USERMEM;
00090 if (sysctl(mib, 2, &usermem, &len, NULL, 0) == 0
00091 && len == sizeof(usermem)) {
00092 std::cerr << "usermem " << usermem << std::endl;
00093 return std::min((size_t)usermem, limit_by_rlimit);
00094 }
00095 }
00096 #endif
00097 {
00098 std::string name, unit;
00099 size_t value;
00100 std::ifstream is("/proc/meminfo");
00101 if (is >> name >> value >> unit
00102 && name == "MemTotal:" && unit == "kB")
00103 return std::min(value * 1024, limit_by_rlimit);
00104 }
00105 #if (defined __FreeBSD__)
00106 const long mem = sysconf(_SC_PHYS_PAGES);
00107 if (mem != -1)
00108 return std::min(mem * getpagesize(), limit_by_rlimit);
00109 #endif
00110 return std::min((rlim_t)limit_by_rlimit, std::numeric_limits<rlim_t>::max());
00111 #endif
00112 }
00113 }
00114
00115 size_t osl::OslConfig::memory_use_limit = system_memory_use_limit();
00116 const size_t osl::OslConfig::memory_use_limit_system_max =
00117 #ifdef _WIN32
00118 3000000000;
00119 #else
00120 std::numeric_limits<rlim_t>::max();
00121 #endif
00122 double osl::OslConfig::memory_use_percent = 100.0;
00123
00124 void osl::OslConfig::setNumCPUs(int ncpu)
00125 {
00126 if (ncpu > MaxThreads) {
00127 std::cerr << "ncpu " << ncpu << " > " << "MaxThreads " << MaxThreads << "\n";
00128 ncpu = MaxThreads;
00129 }
00130 num_cpu = ncpu;
00131 }
00132
00133 int osl::OslConfig::numCPUs()
00134 {
00135 return num_cpu;
00136 }
00137
00138 void osl::OslConfig::setVerbose(bool v)
00139 {
00140 is_verbose = v;
00141 }
00142
00143 bool osl::OslConfig::verbose()
00144 {
00145 return is_verbose;
00146 }
00147
00148 bool osl::OslConfig::usiMode()
00149 {
00150 return usi_mode;
00151 }
00152 void osl::OslConfig::setUsiMode(bool enable)
00153 {
00154 usi_mode = enable;
00155 }
00156 bool osl::OslConfig::usiModeInSilent()
00157 {
00158 return usi_mode_silent;
00159 }
00160 void osl::OslConfig::setUsiSilent(bool enable)
00161 {
00162 usi_mode_silent = enable;
00163 }
00164 bool osl::OslConfig::searchExactValueInOneReply()
00165 {
00166 return search_exact_value_in_one_reply;
00167 }
00168 void osl::OslConfig::setSearchExactValueInOneReply(bool enable)
00169 {
00170 search_exact_value_in_one_reply = enable;
00171 }
00172
00173 bool osl::OslConfig::hasByoyomi()
00174 {
00175 return has_byoyomi;
00176 }
00177
00178 void osl::OslConfig::setHasByoyomi(bool value)
00179 {
00180 has_byoyomi = value;
00181 }
00182
00183 void osl::OslConfig::showOslHome(const std::string& home)
00184 {
00185 std::cerr << "using " << home << " as OSL_HOME, word size "
00186 << OSL_WORDSIZE << std::endl;
00187 }
00188
00189 void osl::OslConfig::showOslHome()
00190 {
00191 showOslHome(home());
00192 }
00193
00194 bool osl::OslConfig::isGoodDir(const std::string& dir)
00195 {
00196 return boost::filesystem::exists(dir)
00197 && boost::filesystem::is_directory(dir);
00198 }
00199
00200 void osl::OslConfig::trySetDir(std::string& dir, const std::string& candidate)
00201 {
00202 if (isGoodDir(candidate))
00203 {
00204 dir = candidate;
00205 return;
00206 }
00207 if (verbose())
00208 std::cerr << "skipping " << candidate << std::endl;
00209 }
00210
00211 const std::string osl::OslConfig::makeHome()
00212 {
00213 std::string result;
00214 if (const char *env = getenv("GPSSHOGI_HOME"))
00215 trySetDir(result, env);
00216
00217 #if defined GPSSHOGI_HOME
00218 if (result.empty())
00219 trySetDir(result, GPSSHOGI_HOME);
00220 #endif
00221
00222 if (result.empty())
00223 if (const char *env = getenv("OSL_HOME"))
00224 trySetDir(result, env);
00225
00226 if (result.empty())
00227 result = OSL_HOME;
00228
00229 if (verbose())
00230 showOslHome(result);
00231 return result;
00232 }
00233
00234 const std::string& osl::OslConfig::home()
00235 {
00236 static const std::string home_directory = makeHome();
00237 return home_directory;
00238 }
00239
00240 const char * osl::OslConfig::home_c_str()
00241 {
00242 return home().c_str();
00243 }
00244
00245 const std::string osl::OslConfig::gpsusiConf()
00246 {
00247
00248
00249
00250 #ifdef OSL_PUBLIC_RELEASE
00251
00252 if (const char *env = getenv("HOME"))
00253 return std::string(env) + "/gpsusi.conf";
00254 if (const char *env = getenv("USERPROFILE"))
00255 return std::string(env) + "/gpsusi.conf";
00256 #endif
00257
00258 static const std::string home_directory = makeHome();
00259 return home_directory + "/gpsusi.conf";
00260 }
00261
00262 const std::string osl::OslConfig::makeTest()
00263 {
00264 std::string result;
00265 if (const char *env = getenv("OSL_TEST"))
00266 trySetDir(result, env);
00267
00268 if (result.empty())
00269 result = home() + "/data";
00270
00271 std::cerr << "using " << result << " as OSL_TEST" << std::endl;
00272 return result;
00273 }
00274
00275 const std::string osl::OslConfig::makeTestPublic()
00276 {
00277 std::string result;
00278 if (const char *env = getenv("OSL_TEST_PUBLIC"))
00279 trySetDir(result, env);
00280
00281 if (result.empty())
00282 result = home() + "/public-domain";
00283
00284 std::cerr << "using " << result << " as OSL_TEST_PUBLIC" << std::endl;
00285 return result;
00286 }
00287
00288 const std::string osl::OslConfig::testPrivate()
00289 {
00290 static const std::string test_directory = makeTest();
00291 return test_directory;
00292 }
00293
00294 const std::string osl::OslConfig::testPublic()
00295 {
00296 static const std::string test_directory = makeTestPublic();
00297 return test_directory;
00298 }
00299
00300 namespace
00301 {
00302 struct NameHolder : std::map<std::string,std::string>
00303 {
00304 std::string directory;
00305
00306 NameHolder(const std::string& d) : directory(d)
00307 {
00308 directory += "/";
00309 }
00310
00311 iterator add(const std::string& key, const std::string& value)
00312 {
00313 return insert(std::make_pair(key, value)).first;
00314 }
00315 iterator addRelative(const std::string& key, const std::string& filename)
00316 {
00317 std::string value = directory + filename;
00318 return add(key, value);
00319 }
00320 iterator addRelative(const std::string& filename)
00321 {
00322 return addRelative(filename, filename);
00323 }
00324 };
00325 }
00326
00327 const char * osl::OslConfig::testPrivateFile(const std::string& filename)
00328 {
00329 static NameHolder table(testPrivate());
00330 NameHolder::iterator p=table.find(filename);
00331 if (p == table.end()) {
00332 p = table.addRelative(filename);
00333 }
00334 return p->second.c_str();
00335 }
00336
00337 const char * osl::OslConfig::testPublicFile(const std::string& filename)
00338 {
00339 static NameHolder table(testPublic());
00340 NameHolder::iterator p=table.find(filename);
00341 if (p == table.end()) {
00342 p = table.addRelative(filename);
00343 }
00344 return p->second.c_str();
00345 }
00346
00347 const char * osl::OslConfig::testCsaFile(const std::string& filename)
00348 {
00349 static NameHolder table(testPublic()+"/floodgate2010");
00350 NameHolder::iterator p=table.find(filename);
00351 if (p == table.end()) {
00352 p = table.addRelative(filename);
00353 }
00354 return p->second.c_str();
00355 }
00356
00357 const char *osl::OslConfig::openingBook(const std::string& filename)
00358 {
00359 static NameHolder table(home()+"/data");
00360 NameHolder::iterator p=table.find(filename);
00361 if (p == table.end()) {
00362 if (! filename.empty() && filename[0] == '/') {
00363
00364 p = table.add(filename, filename);
00365 }
00366 else {
00367
00368 p = table.addRelative(filename,
00369 (filename == "" ? "joseki.dat" : filename));
00370 }
00371 }
00372 return p->second.c_str();
00373 }
00374
00375
00376 size_t osl::OslConfig::residentMemoryUse()
00377 {
00378 #if defined(_WIN32)
00379 static const DWORD process_id = GetCurrentProcessId();
00380 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
00381 FALSE, process_id);
00382 if (NULL == hProcess)
00383 {
00384 std::cerr << "Failed to get residentMemoryUse()\n";
00385 return 0;
00386 }
00387
00388 size_t working_set = 0;
00389 PROCESS_MEMORY_COUNTERS pmc;
00390 if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
00391 working_set = pmc.WorkingSetSize;
00392 }
00393 CloseHandle(hProcess);
00394 return working_set;
00395 #else
00396
00397
00398 std::ifstream is("/proc/self/statm");
00399 size_t total, resident;
00400 if (is >> total >> resident)
00401 return resident*getpagesize();
00402 #ifdef __APPLE__
00403 mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
00404 task_basic_info_64 ti;
00405 if (task_info(current_task(), TASK_BASIC_INFO_64, (task_info_t)&ti, &count)
00406 == KERN_SUCCESS)
00407 return ti.resident_size;
00408 #endif
00409 #ifdef __FreeBSD__
00410 static kvm_t *kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "osl kvm_open");
00411 int nproc;
00412 kinfo_proc *pp = kvm_getprocs(kd, KERN_PROC_PID, getpid(), &nproc);
00413 if (pp)
00414 return pp->ki_rssize * getpagesize();
00415 #endif
00416 #endif
00417 return 0;
00418 }
00419
00420 #ifndef DFPNSTATONE
00421 void osl::OslConfig::setUp()
00422 {
00423 eval::ml::OpenMidEndingEval::setUp();
00424 progress::ml::NewProgress::setUp();
00425 }
00426 #endif
00427
00428
00429
00430
00431
00432