From: H.G. Muller Date: Thu, 14 Oct 2010 19:58:39 +0000 (+0200) Subject: Port UCI2WB to Linux X-Git-Tag: v2.0~55 X-Git-Url: http://winboard.nl/cgi-bin?p=uci2wb.git;a=commitdiff_plain;h=a694d39c28c9b357b7187872d2ef5ae2b35a21e8 Port UCI2WB to Linux If WIN32 is not defined, POSIX calls are used to create the engine thread, pipes and engine process, and an own implemntation of GetTickCount() is suppled. --- diff --git a/UCI2WB.c b/UCI2WB.c index c6eb949..6b454de 100644 --- a/UCI2WB.c +++ b/UCI2WB.c @@ -3,9 +3,22 @@ #define VERSION "1.5" #include -#include -#include +#include +#ifdef WIN32 +# include +# include + HANDLE process; + DWORD thread_id; +#else +# include +# include +# define NO_ERROR 0 +# include + int GetTickCount() // with thanks to Tord + { struct timeval t; gettimeofday(&t, NULL); return t.tv_sec*1000 + t.tv_usec/1000; } +#endif #include +#include #ifdef _MSC_VER #define SLEEP() Sleep(1) @@ -22,13 +35,11 @@ #define ANALYZE 3 char move[2000][10], checkOptions[8192], iniPos[256], hashOpt[20], pause, pondering, ponder, post, hasHash, c, sc='c', *suffix; -int mps, tc, inc, stime, depth, myTime, hisTime, stm, computer = NONE, memory, oldMem=0, cores, moveNr, lastDepth, lastScore, startTime; +int mps, tc, inc, sTime, depth, myTime, hisTime, stm, computer = NONE, memory, oldMem=0, cores, moveNr, lastDepth, lastScore, startTime; int statDepth, statScore, statNodes, statTime, currNr, size; char currMove[20]; // for analyze mode FILE *toE, *fromE; -HANDLE process; int pid; -DWORD thread_id; void StartSearch(char *ponder) @@ -36,7 +47,7 @@ StartSearch(char *ponder) int nr = moveNr + (ponder[0] != 0); // we ponder for one move ahead! fprintf(toE, "\ngo btime %d wtime %d", stm == BLACK ^ sc=='s' ? myTime : hisTime, stm == WHITE ^ sc=='s' ? myTime : hisTime); printf( "\n# go btime %d wtime %d", stm == BLACK ^ sc=='s' ? myTime : hisTime, stm == WHITE ^ sc=='s' ? myTime : hisTime); - if(stime > 0) fprintf(toE, " movetime %d", stime),printf(" movetime %d", stime); else + if(sTime > 0) fprintf(toE, " movetime %d", sTime),printf(" movetime %d", sTime); else if(mps) fprintf(toE, " movestogo %d", mps*(nr/(2*mps)+1)-nr/2),printf(" movestogo %d", mps*(nr/(2*mps)+1)-nr/2); if(inc && !suffix) fprintf(toE, " winc %d binc %d", inc, inc),printf(" winc %d binc %d", inc, inc); if(depth > 0) fprintf(toE, " depth %d", depth),printf(" depth %d", depth); @@ -76,7 +87,7 @@ char *Convert(char *pv) return buf; } -void +void * Engine2GUI() { char line[1024], command[256]; @@ -98,7 +109,7 @@ printf("# engine said: %s", line); strstr(line+9, "0000")) { printf("%s\n", lastScore < -99999 ? "resign" : "1/2-1/2 {stalemate}"); computer = NONE; } sscanf(line, "bestmove %s", move[moveNr++]); myTime -= (GetTickCount() - startTime)*1.02 + inc; // update own clock, so we can give correct wtime, btime with ponder - if(mps && ((moveNr+1)/2) % mps == 0) myTime += tc; if(stime) myTime = stime; // new session or move starts + if(mps && ((moveNr+1)/2) % mps == 0) myTime += tc; if(sTime) myTime = sTime; // new session or move starts // first start a new ponder search, if pondering is on and we have a move to ponder on if(p = strstr(line+9, "ponder")) { if(computer != NONE && ponder) { @@ -207,7 +218,7 @@ printf("# start search\n"); nomove: fflush(toE); fflush(stdout); i = 0; while((x = getchar()) != EOF && (line[i] = x) != '\n') i++; - line[++i] = 0; if(x == EOF) { printf("# EOF\n"); exit(-1); } + line[++i] = 0; if(x == EOF) { printf("# EOF\n"); exit(-1); } sscanf(line, "%s", command); while(pause) SLEEP(); // wait for readyok if(!strcmp(command, "new")) { @@ -251,7 +262,7 @@ printf("# start search\n"); int sec = 0; sscanf(line, "level %d %d:%d %d", &mps, &tc, &sec, &inc) == 4 || sscanf(line, "level %d %d %d", &mps, &tc, &inc); - tc = (60*tc + sec)*1000; inc *= 1000; stime = 0; + tc = (60*tc + sec)*1000; inc *= 1000; sTime = 0; } else if(!strcmp(command, "option")) { char name[80], *p; @@ -300,14 +311,15 @@ printf("# start search\n"); else if(!strcmp(command, "memory")) sscanf(line, "memory %d", &memory); else if(!strcmp(command, "cores")) sscanf(line, "cores %d", &cores); else if(!strcmp(command, "sd")) sscanf(line, "sd %d", &depth); - else if(!strcmp(command, "st")) sscanf(line, "st %d", &stime), stime *= 1000, inc = 0; + else if(!strcmp(command, "st")) sscanf(line, "st %d", &sTime), sTime *= 1000, inc = 0; else if(!strcmp(command, "quit")) fprintf(toE, "quit\n"), fflush(toE), exit(0); } } int StartEngine(char *cmdLine, char *dir) -{ +{ +#ifdef WIN32 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr; SECURITY_ATTRIBUTES saAttr; @@ -367,7 +379,31 @@ StartEngine(char *cmdLine, char *dir) pid = piProcInfo.dwProcessId; fromE = (FILE*) _fdopen( _open_osfhandle((long)hChildStdoutRd, _O_TEXT|_O_RDONLY), "r"); toE = (FILE*) _fdopen( _open_osfhandle((long)hChildStdinWr, _O_WRONLY), "w"); - +#else + char *argv[10], *p, buf[200]; + int i, toEngine[2], fromEngine[2]; + + if (dir && dir[0] && chdir(dir)) { perror(dir); exit(1); } + pipe(toEngine); pipe(fromEngine); // create two pipes + + if ((pid = fork()) == 0) { // Child + dup2(toEngine[0], 0); close(toEngine[0]); close(toEngine[1]); // stdin from toE pipe + dup2(fromEngine[1], 1); close(fromEngine[0]); close(fromEngine[1]); // stdout into fromE pipe + dup2(1, fileno(stderr)); // stderr into frome pipe + + strcpy(buf, cmdLine); p = buf; + for (i=0;;) { argv[i++] = p; p = strchr(p, ' '); if (p == NULL) break; *p++ = 0; } + argv[i] = NULL; + execvp(argv[0], argv); // startup engine + + perror(argv[0]); exit(1); // could not start engine; quit. + } + signal(SIGPIPE, SIG_IGN); + close(toEngine[0]); close(fromEngine[1]); // close engine ends of pipes in adapter + + fromE = (FILE*) fdopen(fromEngine[0], "r"); // make into high-level I/O + toE = (FILE*) fdopen(toEngine[1], "w"); +#endif return NO_ERROR; } @@ -377,15 +413,19 @@ main(int argc, char **argv) if(argc == 2 && !strcmp(argv[1], "-v")) { printf("UCI2WB " VERSION " by H.G.Muller\n"); exit(0); } if(argc > 1 && argv[1][0] == '-') { sc = argv[1][1]; argc--; argv++; } - if(argc < 2) { printf("usage is: U%cI2WB [-s] []", sc-32); exit(-1); } + if(argc < 2) { printf("usage is: U%cI2WB [-s] []\n", sc-32); exit(-1); } if(argc > 2) dir = argv[2]; if(argc > 3) suffix = argv[3]; // spawn engine proc - if((errno = StartEngine(argv[1], dir)) != NO_ERROR) { perror(argv[1]), exit(-1); } + if(StartEngine(argv[1], dir) != NO_ERROR) { perror(argv[1]), exit(-1); } // create separate thread to handle engine->GUI traffic - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Engine2GUI, (LPVOID) NULL, 0, &thread_id); +#ifdef WIN32 + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Engine2GUI, (LPVOID) NULL, 0, &thread_id); +#else + { pthread_t t; signal(SIGINT, SIG_IGN); pthread_create(&t, NULL, Engine2GUI, NULL); } +#endif // handle GUI->engine traffic in original thread GUI2Engine();