X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsyzygy%2Ftbprobe.cpp;h=84346c278194501550c820412e3650317d2a35fe;hp=03cffca17bc4756839443559ea4247bb13c05d6d;hb=7196f4c2370d0c7acd8ec3ed8de7ecb7f0682123;hpb=8c0a2733924f59316003c576ee2064ded490678b diff --git a/src/syzygy/tbprobe.cpp b/src/syzygy/tbprobe.cpp index 03cffca1..84346c27 100644 --- a/src/syzygy/tbprobe.cpp +++ b/src/syzygy/tbprobe.cpp @@ -1,7 +1,7 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 Copyright (c) 2013 Ronald de Man - Copyright (C) 2016-2018 Marco Costalba, Lucas Braesch + Copyright (C) 2016-2019 Marco Costalba, Lucas Braesch Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,12 +27,12 @@ #include #include #include +#include #include "../bitboard.h" #include "../movegen.h" #include "../position.h" #include "../search.h" -#include "../thread_win32.h" #include "../types.h" #include "../uci.h" @@ -45,7 +45,9 @@ #include #else #define WIN32_LEAN_AND_MEAN -#define NOMINMAX +#ifndef NOMINMAX +# define NOMINMAX // Disable macros min() and max() +#endif #include #endif @@ -214,39 +216,57 @@ public: return *baseAddress = nullptr, nullptr; fstat(fd, &statbuf); + + if (statbuf.st_size % 64 != 16) + { + std::cerr << "Corrupt tablebase file " << fname << std::endl; + exit(EXIT_FAILURE); + } + *mapping = statbuf.st_size; *baseAddress = mmap(nullptr, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); madvise(*baseAddress, statbuf.st_size, MADV_RANDOM); ::close(fd); - if (*baseAddress == MAP_FAILED) { + if (*baseAddress == MAP_FAILED) + { std::cerr << "Could not mmap() " << fname << std::endl; - exit(1); + exit(EXIT_FAILURE); } #else + // Note FILE_FLAG_RANDOM_ACCESS is only a hint to Windows and as such may get ignored. HANDLE fd = CreateFile(fname.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr); if (fd == INVALID_HANDLE_VALUE) return *baseAddress = nullptr, nullptr; DWORD size_high; DWORD size_low = GetFileSize(fd, &size_high); + + if (size_low % 64 != 16) + { + std::cerr << "Corrupt tablebase file " << fname << std::endl; + exit(EXIT_FAILURE); + } + HANDLE mmap = CreateFileMapping(fd, nullptr, PAGE_READONLY, size_high, size_low, nullptr); CloseHandle(fd); - if (!mmap) { + if (!mmap) + { std::cerr << "CreateFileMapping() failed" << std::endl; - exit(1); + exit(EXIT_FAILURE); } *mapping = (uint64_t)mmap; *baseAddress = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0); - if (!*baseAddress) { + if (!*baseAddress) + { std::cerr << "MapViewOfFile() failed, name = " << fname << ", error = " << GetLastError() << std::endl; - exit(1); + exit(EXIT_FAILURE); } #endif uint8_t* data = (uint8_t*)*baseAddress; @@ -254,7 +274,8 @@ public: constexpr uint8_t Magics[][4] = { { 0xD7, 0x66, 0x0C, 0xA5 }, { 0x71, 0xE8, 0x23, 0x5D } }; - if (memcmp(data, Magics[type == WDL], 4)) { + if (memcmp(data, Magics[type == WDL], 4)) + { std::cerr << "Corrupted table in file " << fname << std::endl; unmap(*baseAddress, *mapping); return *baseAddress = nullptr, nullptr; @@ -348,7 +369,7 @@ TBTable::TBTable(const std::string& code) : TBTable() { hasPawns = pos.pieces(PAWN); hasUniquePieces = false; - for (Color c = WHITE; c <= BLACK; ++c) + for (Color c : { WHITE, BLACK }) for (PieceType pt = PAWN; pt < KING; ++pt) if (popcount(pos.pieces(c, pt)) == 1) hasUniquePieces = true; @@ -415,7 +436,7 @@ class TBTables { } } std::cerr << "TB hash table size too low!" << std::endl; - exit(1); + exit(EXIT_FAILURE); } public: @@ -685,9 +706,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu std::swap(squares[0], *std::max_element(squares, squares + leadPawnsCnt, pawns_comp)); - tbFile = file_of(squares[0]); - if (tbFile > FILE_D) - tbFile = file_of(squares[0] ^ 7); // Horizontal flip: SQ_H1 -> SQ_A1 + tbFile = map_to_queenside(file_of(squares[0])); } // DTZ tables are one-sided, i.e. they store positions only for white to @@ -1041,8 +1060,8 @@ void set(T& e, uint8_t* data) { enum { Split = 1, HasPawns = 2 }; - assert(e.hasPawns == !!(*data & HasPawns)); - assert((e.key != e.key2) == !!(*data & Split)); + assert(e.hasPawns == bool(*data & HasPawns)); + assert((e.key != e.key2) == bool(*data & Split)); data++; // First byte stores flags @@ -1105,14 +1124,14 @@ void set(T& e, uint8_t* data) { template void* mapped(TBTable& e, const Position& pos) { - static Mutex mutex; + static std::mutex mutex; - // Use 'aquire' to avoid a thread reads 'ready' == true while another is - // still working, this could happen due to compiler reordering. + // Use 'acquire' to avoid a thread reading 'ready' == true while + // another is still working. (compiler reordering may cause this). if (e.ready.load(std::memory_order_acquire)) - return e.baseAddress; // Could be nullptr if file does not exsist + return e.baseAddress; // Could be nullptr if file does not exist - std::unique_lock lk(mutex); + std::unique_lock lk(mutex); if (e.ready.load(std::memory_order_relaxed)) // Recheck under lock return e.baseAddress; @@ -1277,7 +1296,7 @@ void Tablebases::init(const std::string& paths) { continue; // First on diagonal, second above else if (!off_A1H8(s1) && !off_A1H8(s2)) - bothOnDiagonal.push_back(std::make_pair(idx, s2)); + bothOnDiagonal.emplace_back(idx, s2); else MapKK[idx][s2] = code++;