/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
- Copyright (C) 2004-2020 The Stockfish developers (see AUTHORS file)
+ Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <sys/mman.h>
#endif
-#if defined(__APPLE__) || defined(__ANDROID__) || defined(__OpenBSD__) || (defined(__GLIBCXX__) && !defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) && !defined(_WIN32))
+#if defined(__APPLE__) || defined(__ANDROID__) || defined(__OpenBSD__) || (defined(__GLIBCXX__) && !defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) && !defined(_WIN32)) || defined(__e2k__)
#define POSIXALIGNEDALLOC
#include <stdlib.h>
#endif
using namespace std;
+namespace Stockfish {
+
namespace {
/// Version number. If Version is left empty, then compile date in the format
static Logger l;
- if (!fname.empty() && !l.file.is_open())
+ if (l.file.is_open())
+ {
+ cout.rdbuf(l.out.buf);
+ cin.rdbuf(l.in.buf);
+ l.file.close();
+ }
+
+ if (!fname.empty())
{
l.file.open(fname, ifstream::out);
cin.rdbuf(&l.in);
cout.rdbuf(&l.out);
}
- else if (fname.empty() && l.file.is_open())
- {
- cout.rdbuf(l.out.buf);
- cin.rdbuf(l.in.buf);
- l.file.close();
- }
}
};
/// the program was compiled) or "Stockfish <Version>", depending on whether
/// Version is empty.
-const string engine_info(bool to_uci) {
+string engine_info(bool to_uci) {
const string months("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec");
string month, day, year;
/// compiler_info() returns a string trying to describe the compiler we use
-const std::string compiler_info() {
+std::string compiler_info() {
#define stringify2(x) #x
#define stringify(x) stringify2(x)
compiler += "(version ";
compiler += stringify(_MSC_FULL_VER) "." stringify(_MSC_BUILD);
compiler += ")";
+ #elif defined(__e2k__) && defined(__LCC__)
+ #define dot_ver2(n) \
+ compiler += (char)'.'; \
+ compiler += (char)('0' + (n) / 10); \
+ compiler += (char)('0' + (n) % 10);
+
+ compiler += "MCST LCC ";
+ compiler += "(version ";
+ compiler += std::to_string(__LCC__ / 100);
+ dot_ver2(__LCC__ % 100)
+ dot_ver2(__LCC_MINOR__)
+ compiler += ")";
#elif __GNUC__
compiler += "g++ (GNUC) ";
compiler += make_version_string(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
#endif
}
-/// aligned_ttmem_alloc() will return suitably aligned memory, if possible using large pages.
-/// The returned pointer is the aligned one, while the mem argument is the one that needs
-/// to be passed to free. With c++17 some of this functionality could be simplified.
-
-#if defined(__linux__) && !defined(__ANDROID__)
-
-void* aligned_ttmem_alloc(size_t allocSize, void*& mem) {
+/// aligned_large_pages_alloc() will return suitably aligned memory, if possible using large pages.
- constexpr size_t alignment = 2 * 1024 * 1024; // assumed 2MB page sizes
- size_t size = ((allocSize + alignment - 1) / alignment) * alignment; // multiple of alignment
- if (posix_memalign(&mem, alignment, size))
- mem = nullptr;
-#if defined(MADV_HUGEPAGE)
- madvise(mem, allocSize, MADV_HUGEPAGE);
-#endif
- return mem;
-}
+#if defined(_WIN32)
-#elif defined(_WIN64)
+static void* aligned_large_pages_alloc_windows(size_t allocSize) {
-static void* aligned_ttmem_alloc_large_pages(size_t allocSize) {
+ #if !defined(_WIN64)
+ (void)allocSize; // suppress unused-parameter compiler warning
+ return nullptr;
+ #else
HANDLE hProcessToken { };
LUID luid { };
CloseHandle(hProcessToken);
return mem;
-}
-void* aligned_ttmem_alloc(size_t allocSize, void*& mem) {
+ #endif
+}
- static bool firstCall = true;
+void* aligned_large_pages_alloc(size_t allocSize) {
// Try to allocate large pages
- mem = aligned_ttmem_alloc_large_pages(allocSize);
-
- // Suppress info strings on the first call. The first call occurs before 'uci'
- // is received and in that case this output confuses some GUIs.
- if (!firstCall)
- {
- if (mem)
- sync_cout << "info string Hash table allocation: Windows large pages used." << sync_endl;
- else
- sync_cout << "info string Hash table allocation: Windows large pages not used." << sync_endl;
- }
- firstCall = false;
+ void* mem = aligned_large_pages_alloc_windows(allocSize);
// Fall back to regular, page aligned, allocation if necessary
if (!mem)
#else
-void* aligned_ttmem_alloc(size_t allocSize, void*& mem) {
+void* aligned_large_pages_alloc(size_t allocSize) {
+
+#if defined(__linux__)
+ constexpr size_t alignment = 2 * 1024 * 1024; // assumed 2MB page size
+#else
+ constexpr size_t alignment = 4096; // assumed small page size
+#endif
- constexpr size_t alignment = 64; // assumed cache line size
- size_t size = allocSize + alignment - 1; // allocate some extra space
- mem = malloc(size);
- void* ret = reinterpret_cast<void*>((uintptr_t(mem) + alignment - 1) & ~uintptr_t(alignment - 1));
- return ret;
+ // round up to multiples of alignment
+ size_t size = ((allocSize + alignment - 1) / alignment) * alignment;
+ void *mem = std_aligned_alloc(alignment, size);
+#if defined(MADV_HUGEPAGE)
+ madvise(mem, size, MADV_HUGEPAGE);
+#endif
+ return mem;
}
#endif
-/// aligned_ttmem_free() will free the previously allocated ttmem
+/// aligned_large_pages_free() will free the previously allocated ttmem
-#if defined(_WIN64)
+#if defined(_WIN32)
-void aligned_ttmem_free(void* mem) {
+void aligned_large_pages_free(void* mem) {
if (mem && !VirtualFree(mem, 0, MEM_RELEASE))
{
DWORD err = GetLastError();
- std::cerr << "Failed to free transposition table. Error code: 0x" <<
- std::hex << err << std::dec << std::endl;
+ std::cerr << "Failed to free large page memory. Error code: 0x"
+ << std::hex << err
+ << std::dec << std::endl;
exit(EXIT_FAILURE);
}
}
#else
-void aligned_ttmem_free(void *mem) {
- free(mem);
+void aligned_large_pages_free(void *mem) {
+ std_aligned_free(mem);
}
#endif
string argv0; // path+name of the executable binary, as given by argv[0]
string binaryDirectory; // path of the executable directory
string workingDirectory; // path of the working directory
-string pathSeparator; // Separator for our current OS
void init(int argc, char* argv[]) {
(void)argc;
- string separator;
+ string pathSeparator;
// extract the path+name of the executable binary
argv0 = argv[0];
} // namespace CommandLine
+
+} // namespace Stockfish