I have tried mutex before with great difficulty. There also seems to be some kind of problem chasing nStdHandle when using I/O inside threads. Only the root core needs to monitor the flags so there is no need for a separate Input() thread. I/O can be done in subroutines. I suppose one could combine the time and pipe calls by using a single variable to save a little time monitoring the flag:stegemma wrote:I've separated the engine thread against the interface thread and the input thread, so the interface thread handles protocol commands (reading from input thread with a mutex) and time and the engine itself only have to search for the best move. This way, I need only one boolean flag for the search engine, that say "hey, stop you!". All the input/output stuff are handled by the interface thread, that eventually just stop the engine, for commands that require an immediate answer (or abort and so on). I use Mutex to protect any structure shared between threads, even to get the PV from the engine (only the best move, for now).D Sceviour wrote:[...]the polling thread continuously monitors only two functions: Timer() and PeekNamedPipe(). Then it sets an abort_search flag for time out, or an internal pipe_request flag for the pipe. The only overhead on the engine search is to monitor two internal boolean variables: abort_search and pipe_request.[...]
For debugging purpose, I use a FIFO stack protected by a mutex where the engine puts its strings (but even the interface and all other objects of the program use it). Using mutex seems to me to be the more flexible way to communicates between threads and you "only" have to take care of dead-locks.
This way, the search engine doesn't know anything about the protocol used, it only starts/stops thinking, eventually sets some options through its functions/parameters. You can change protocol with no changes in the search engine... or don0't use a protocol at all, for stand-alone software.
abort_search = STOP_NOW
abort_search = PIPE_REQUEST
All the I/O, mutex and debug problems can be cleaned up by looping the polling thread on something like this:
Code: Select all
Do
; Wait() or Sleep() thing
time_used = timer - start
If (time_used > time_limit) and (analyze_mode=0) then
abort_search = 1
end if
if xboard and (pipe_request=0) then
dw=0
PeekNamedPipe(nStdHandle, 0, 0, 0, @dw, 0)
if dw then pipe_request=1
end if
Loop until terminate