And directly pass RootMoves instead of SearchMoves
to main thread. A class declaration is better suited
in a header and slims a bit the fatty search.cpp
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We just need to verify if a legal move is among the
SearchMoves, so we don't need a vector for this.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
New gcc 4.7 complains about casting a volatile pointer
to void* so assign the variables directly.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It could lead to terrible mistakes otherwise, as
it happened during a game on playchess when on
this position (after white's f4):
2q4r/4b1k1/p3rpp1/3np2p/PpNpNP1P/1P1P2PQ/2P1R3/4R1K1 b - - 0 1
SF moves immediately e5xf4 instead of the correct f5.
In general during engine matches it is impossible the
opponent leaves a piece hanging or anyhow starts a
clear losing sequence. So avoid to fall in subtle traps.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It should help to avoid recalculating check squares
of sliding attackers for queen when already done for
bishops and rooks. Of course this helps when there are
bishop, rook and queen on the board !
Fixed also a subtle bug (use of same variable b in while
condition and in condition body) introduced recently by
revision d655147e8c that triggers
in case we have at least 2 non-pawn discovered check pieces.
This is very rare that's why didn't show in the node count
verification where we actually have a case of 2 dc pieces
in position 14, but one is a pawn.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
During generation of non-captures checks (in qsearch)
we don't consider castling moves that give check,
this patch includes also this rare case. Verified with
perft that all the non-capture checks are now generated.
There should be a very little slowdown due to the extra
work, but actually I failed to measure it. I don't expect
any ELO improvment, there is even no functional change on
the standard depth 12 search, it is just to have a correct
move generator.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The full movegen patch series shows a speed up of almost
6% (!) on perft, and code is much more readable too.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
MV_CHECK is an alias of the more appropiate named
MV_NON_CAPTURE_CHECK so use only the latter.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
And make CRITICAL_SECTION locks the only option for Windows.
This guarantees backward compatibility with all the Windows
versions (even XP and older) and an hassle free experience
when compiling for Windows. Tests performed by Ingo and
reported on talkchess confirm there is no speed penalty
against the most modern SRW locks:
http://www.talkchess.com/forum/viewtopic.php?t=41835&start=20
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
On that platform non-bracketed casting are not supported.
Reported by Richard Lloyd.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Further increase safety against time losses. After this
change (tested on LittleBlitzer and cutechess) I had no
more time losses at 2" and 1"+0.02 TC both on Windows
and Linux on more than 10000 games.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
We try hard not to lose on time even under extreme
time pressure. We achieve this through 3 different but
coordinated steps:
1) Increase max frequency of timer events
2) Quickly return after a stop signal
3) Take in account timer resolution
With these SF played under LittleBlitzer at 1"+0.02 and 3"+0
without losing on time even one game.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Before creating main thread we set its do_sleep flag to true,
then thread is created and it will go to sleep in main_loop()
after resetting do_sleep.
But if after the setting of do_sleep and before its resetting
the UI thread calls start_thinking() it will not wait on:
if (!asyncMode)
while (!main.do_sleep)
cond_wait(&sleepCond, &main.sleepLock);
as it should but will immediately return before the main thread has
started the search. This very rare race show itself during bench,
when the first position is erroneusly skipped so that bench node count
results of 5309038 instead of the correct 5457475.
The patch is somewhat tricky, but is simple and it works!
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Locals left and right shadow two same named
variables in the std::ifstream base class.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It seems it yields to missing wake-up events with the
result of SF loosing on time as reported by many people.
So revert the patch and use a more robust approach: assume
there can be spurious wake ups events and make the code to
work also in those cases.
While debugging I found that WaitForSingleObject() had wrong
parameter 0 instead of INFINITE yielding to a crash while
exiting under Windows, strangely unnoticed til now.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The aim is to have shorter names without losing
readibility but, if possible, increasing it.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Retire open(), close() and name() from public visibility
and greately simplify the code. It is amazing how much
can be squeezed out of an already mature code !
No functional change
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
In Windows when OLD_LOCKS is defined we use SetEvent() to mimic
the semantic of the POSIX pthread_cond_signal().
Unfortunatly there is not a direct mapping because with SetEvent()
the state of an event object remains signaled until it is set
explicitly to the nonsignaled state or until a single waiting thread
has been released. Instead in case of pthread_cond_signal(), if there
are no waiting threads it has no effect. What we may want is something
like PulseEvent() instead of SetEvent(). Unfortunatly it is documented
by Mcrosoft as 'unreliable' due to spurious wakes up that could
filter out the signal resetting. So we opt to reset manually any
pending signaled state before to go to sleep.
This fixes the strange misbehaves during 'stockfish bench'
when using OLD_LOCKS under Windows.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Now that HasPopCnt is a compile time constant we can
centralize and unify the BitCountType selection.
Also rename count_1s() in the more standard popcount()
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
It was meant to build a single binary optimized
for any kind of CPU: with and without hardware POPCNT.
This is a nice idea but in practice was never used, or
people builds binary with popcnt enabled or not, mainly
according to their type of CPU. And it was also never
used in the official Jim's builds where, in case, would
be easier for a number of reasons, do build two different
versions: with and without SEE42 support.
So retire this feature and simplify the code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This leads to a further and unexpected simplification
of this already very size optimized code.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Currently after a 'quit' command UI thread raises stop
signal, exits from uci_loop() and calls Threads.exit()
while the search threads are still active.
In Threads.exit() main thread is asked to terminate, but
if it is parked in idle_loop() it will exit and free its
resources (in particular the shared Movepicker object) while
sibling slaves are still active and this leads to a crash.
The fix is to let the UI thread always wait for main thread
to finish the search before to return from uci_loop().
Found by Valgrind when running with 8 threads.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Greatly improves the usage. User defined conversions
are a novelity for SF, another amazing C++ facility
at work !
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
The condition for a mate score was wrong:
abs(v) < VALUE_MATE - PLY_MAX * ONE_PLY
instead of
abs(v) < VALUE_MATE_IN_PLY_MAX
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
During the search we score a mate as "plies to mate
from the root" to compare in an homogeneous way the
values returned by different sub-trees. However we
store in TT a mate score as "plies to mate from the
current position" the let the TT value remain valid
across the game.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>