problem with buffering/bioskey under winboard

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

problem with buffering/bioskey under winboard

Postby Roman Hartmann » 03 Aug 2005, 17:48

Hi all,
today I added winboard support to my engine and while the part I thought would cause problems went smoothly I have again problems in an area I thought I have a working solution.

The problem is that winboard doesn?t show any analysis output when my engine is switched to analyze mode. It works under Arena but doesn?t work under winboard.
A buffering problem I concluded and made sure that there was no buffering anymore but now I got another problem. Winboard sends constantly a dot (?.\n?) to the engine and that stopps my search now immediately cause my bioskey() function relies on a buffer it reads with fgets(). Now the search stopps if only a keyboard hit is detected or if winboard sends the dot to the engine, of course.
Anyway, I?m wondering now if there is a clean solution to that problem as I would like to use the bioskey() function for both UCI and winboard as they are sharing the same search. The strange thing is that playing works well under winboard only when switching to analyze mode I have this problem.
Anyone has and idea/approach to solve that problem?

Thanks a lot for any suggestions.
Roman
User avatar
Roman Hartmann
 
Posts: 155
Joined: 11 Oct 2004, 14:21

Re: problem with buffering/bioskey under winboard

Postby Dann Corbit » 03 Aug 2005, 18:21

Don't feel insulted if I say something obvious, because I do not know what you are doing.

First, you must turn off all buffering by doing this on program startup:
Code: Select all
    setbuf(stdout, NULL);
    setbuf(stdin, NULL);


or this, if you are using C++:
Code: Select all
    cout.rdbuf()->pubsetbuf(NULL,0);
    cin.rdbuf()->pubsetbuf(NULL,0);


This is what Beowulf does:

Code: Select all
/* Bioskey checks for input waiting in stdin.
 * Credit here goes to Dr Oliver Brausch for the code from his
 * program Olithink.  Some rewriting has been done by CMF, but not much
 * as I have absolutely no idea whatsoever what this does.
 * I think the original code is from Crafty by Prof. Robert Hyatt. */

#ifndef _WIN32
/* Non-windows version */
int             Bioskey(void)
{
    fd_set          readfds;
    struct timeval  timeout;

    FD_ZERO(&readfds);
    FD_SET(fileno(stdin), &readfds);
    /* Set to timeout immediately */
    timeout.tv_sec = 0;
    timeout.tv_usec = 0;
    select(16, &readfds, 0, 0, &timeout);

    return (FD_ISSET(fileno(stdin), &readfds));
}

#else
/* Windows-version */
#include <windows.h>
#include <conio.h>
int             Bioskey(void)
{
    static int      init = 0,
                    pipe;
    static HANDLE   inh;
    DWORD           dw;
    /* If we're running under XBoard then we can't use _kbhit() as the input
     * commands are sent to us directly over the internal pipe */
    if (XBoard) {
#if defined(FILE_CNT)
        if (stdin->_cnt > 0)
            return stdin->_cnt;
#endif
        if (!init) {
            init = 1;
            inh = GetStdHandle(STD_INPUT_HANDLE);
            pipe = !GetConsoleMode(inh, &dw);
            if (!pipe) {
                SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
                FlushConsoleInputBuffer(inh);
            }
        }
        if (pipe) {
            if (!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL))
                return 1;
            return dw;
        } else {
            GetNumberOfConsoleInputEvents(inh, &dw);
            return dw <= 1 ? 0 : dw;
        }
    } else
        return _kbhit();
}
#endif
Dann Corbit
 

Re: problem with buffering/bioskey under winboard

Postby Roman Hartmann » 03 Aug 2005, 18:49

Hi Dann,
thanks for your answer. I'm already successfully doing what you proposed in the UCI part of my engine. The UCI stuff works flawless in all the GUI's I tested so far. That's why I thought I could do it the same way under xboard. But in the code you posted now I can see that there is a #ifdef statement regarding xboard, so I guess I can't just do it the same way in xboard then.

Anyway, the code snippets of the biosky() function you posted look quite a bit different than the bioskey function that I'm using (although I also looked at Olikthing, I guess). The main problem seems to be that I'm using fgets() in my bioskey() function (no buffering but trying to read from a buffer ...).

Thanks again.

Roman
User avatar
Roman Hartmann
 
Posts: 155
Joined: 11 Oct 2004, 14:21

Re: problem with buffering/bioskey under winboard

Postby Roman Hartmann » 04 Aug 2005, 08:42

In the meanwhile I fixed part of the problem. The problem wasn't the bioskey() function though but my check_input() function where I check if the search is aborted by the user or the time is running out. I was trying to read user input with fgets() into a buffer and then check this buffer for 'exit' or 'stop' (depending if I'm in xboard or UCI mode). Anyway, I couldn't bring fgets() to work in my check_input() function as it was always somehow garbled by the results of the bioskey() function. I replaced the fgets() part with something I found in Beowulf now.

Code: Select all
      do {
         bytes=read(fileno(stdin),input,255);
      } while (bytes<0);



And this works just fine. I still don't know why fgets() doesn't work in this particular context.

But I have under winboard still the same problem that the evals are not posted, neither in normal mode nor in analyze mode. The evals are written to the debug file though but they are not shown in the window. But I guess the problem could also be related to an option I'm sending or not responding to when the engine starts up (I wasn't too familiar with winboard 3 days ago so ...).

Someone with some more winboard knowledge than me might spot the problem immediately only by looking at the output, I guess. In case someone finds the time to have a look at it here is the link:
http://mypage.bluewin.ch/romanhartmann/roce0341.zip
(time management is currently only partially implemented in xboard-mode though)

Roman
User avatar
Roman Hartmann
 
Posts: 155
Joined: 11 Oct 2004, 14:21

Re: problem with buffering/bioskey under winboard

Postby diepeveen » 04 Aug 2005, 13:34

Roman Hartmann wrote:Hi all,
today I added winboard support to my engine and while the part I thought would cause problems went smoothly I have again problems in an area I thought I have a working solution.

The problem is that winboard doesn?t show any analysis output when my engine is switched to analyze mode. It works under Arena but doesn?t work under winboard.
A buffering problem I concluded and made sure that there was no buffering anymore but now I got another problem. Winboard sends constantly a dot (?.\n?) to the engine and that stopps my search now immediately cause my bioskey() function relies on a buffer it reads with fgets(). Now the search stopps if only a keyboard hit is detected or if winboard sends the dot to the engine, of course.
Anyway, I?m wondering now if there is a clean solution to that problem as I would like to use the bioskey() function for both UCI and winboard as they are sharing the same search. The strange thing is that playing works well under winboard only when switching to analyze mode I have this problem.
Anyone has and idea/approach to solve that problem?

Thanks a lot for any suggestions.
Roman


You can skip the Corbit suggestion and instead use a buffered approach for data that doesn't matter and after each printf of a line that does matter (such as mainline, bestmove) use

fflush(stdout);

that is the default way to do it in C
diepeveen
 
Posts: 116
Joined: 28 Jun 2005, 01:09
Location: Netherlands

Re: problem with buffering/bioskey under winboard

Postby Sven Schüle » 04 Aug 2005, 14:10

diepeveen wrote:You can skip the Corbit suggestion and instead use a buffered approach for data that doesn't matter and after each printf of a line that does matter (such as mainline, bestmove) use

fflush(stdout);

that is the default way to do it in C

Hi Vincent,

you are addressing the output direction only, but Dann mainly has addressed the input side in his posting.

Moreover I think that it's really better not to write these many "fflush(stdout);" lines into the code but instead use unbuffered I/O for the output side, too, as Dann and others have suggested. I write "these many" because AFAIK there are more than a few cases where the engine must send its output immediately (i.e. unbuffered). Configuring this at one central place is less error prone than adding an fflush() at several distinct places.

I think it does no harm to use unbuffered I/O for output, too, unless an engine produces many lines of output per second during search so that I/O would slow down the search.

Sven
User avatar
Sven Schüle
 
Posts: 240
Joined: 26 Sep 2004, 20:19
Location: Berlin, Germany

Re: problem with buffering/bioskey under winboard

Postby diepeveen » 04 Aug 2005, 14:19

Sven Sch?le wrote:
diepeveen wrote:You can skip the Corbit suggestion and instead use a buffered approach for data that doesn't matter and after each printf of a line that does matter (such as mainline, bestmove) use

fflush(stdout);

that is the default way to do it in C

Hi Vincent,

you are addressing the output direction only, but Dann mainly has addressed the input side in his posting.

Moreover I think that it's really better not to write these many "fflush(stdout);" lines into the code but instead use unbuffered I/O for the output side, too, as Dann and others have suggested. I write "these many" because AFAIK there are more than a few cases where the engine must send its output immediately (i.e. unbuffered). Configuring this at one central place is less error prone than adding an fflush() at several distinct places.

I think it does no harm to use unbuffered I/O for output, too, unless an engine produces many lines of output per second during search so that I/O would slow down the search.

Sven


Sven, the output is the only problem. Not buffering the rest is a bad idea.
It hurts performance severely for Diep when not buffering the entire i/o.

Vincent
diepeveen
 
Posts: 116
Joined: 28 Jun 2005, 01:09
Location: Netherlands

Output buffering

Postby Sven Schüle » 04 Aug 2005, 15:06

Vincent,

I thought that engines usually output a few lines per iteration. Obviously Diep does more than that, otherwise you wouldn't have such a problem. Can you explain where these problems come from?

Sven
User avatar
Sven Schüle
 
Posts: 240
Joined: 26 Sep 2004, 20:19
Location: Berlin, Germany

Input buffering

Postby Sven Schüle » 04 Aug 2005, 15:15

diepeveen wrote:Sven, the output is the only problem. Not buffering the rest is a bad idea.
It hurts performance severely for Diep when not buffering the entire i/o.

Regarding input: how does this work for you with buffered input?
Sven
User avatar
Sven Schüle
 
Posts: 240
Joined: 26 Sep 2004, 20:19
Location: Berlin, Germany

Re: Input buffering

Postby diepeveen » 04 Aug 2005, 15:42

Sven Sch?le wrote:
diepeveen wrote:Sven, the output is the only problem. Not buffering the rest is a bad idea.
It hurts performance severely for Diep when not buffering the entire i/o.

Regarding input: how does this work for you with buffered input?
Sven


The winboard problem is not a buffering problem with input,
but an output problem of the engine.

fflush fixes it in the best way.

If you turn off buffering then that hurts simply.

Every 0.0x% system time i can win, i WILL win whenever possible in an easy way.

Not messing with buffering is 1 such way to avoid that problem.

Diep ships loads of information to and from the Diep3d GUI of course.
diepeveen
 
Posts: 116
Joined: 28 Jun 2005, 01:09
Location: Netherlands


Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 7 guests