ref: edfb1269aba6f7602aab6e6a25945064a5c97e0f
parent: 2777bd283d4e238761e594fcd038e20f5b9a1d7b
author: zamfofex <zamfofex@twdb.moe>
date: Wed Nov 27 12:36:47 EST 2024
add support for 'stop'
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
!/.build.yml
!/moonfish.vcxproj
!/moonfish.h
+!/threads.h
!/chess.c
!/search.c
!/main.c
--- a/main.c
+++ b/main.c
@@ -8,8 +8,18 @@
#include <strings.h>
#include "moonfish.h"
+#include "threads.h"
-static void moonfish_go(struct moonfish_node *node, int thread_count)
+struct moonfish_info {+ struct moonfish_node *node;
+ int thread_count;
+ _Atomic unsigned char searching;
+#ifndef moonfish_no_threads
+ thrd_t thread;
+#endif
+};
+
+static moonfish_result_t moonfish_go(void *data)
{static struct moonfish_result result;
static struct moonfish_options options;
@@ -18,12 +28,15 @@
long int our_time, their_time, *xtime, time;
char *arg, *end;
char name[6];
+ struct moonfish_info *info;
+ info = data;
+
our_time = -1;
their_time = -1;
time = -1;
- moonfish_root(node, &chess);
+ moonfish_root(info->node, &chess);
for (;;) {@@ -78,12 +91,16 @@
options.max_time = time;
options.our_time = our_time;
- options.thread_count = thread_count;
- moonfish_best_move(node, &result, &options);
+ options.thread_count = info->thread_count;
+ moonfish_best_move(info->node, &result, &options);
moonfish_to_uci(&chess, &result.move, name);
+ info->searching = 2;
printf("info depth 1 score cp %d nodes %ld multipv 1 pv %s\n", result.score, result.node_count, name); printf("bestmove %s\n", name);+ fflush(stdout);
+
+ return moonfish_value;
}
static void moonfish_position(struct moonfish_node *node)
@@ -193,10 +210,9 @@
int main(int argc, char **argv)
{static char line[2048];
- int thread_count;
char *arg;
- struct moonfish_node *node;
+ struct moonfish_info info;
if (argc > 1) {fprintf(stderr, "usage: %s (no arguments)\n", argv[0]);
@@ -203,8 +219,9 @@
return 1;
}
- node = moonfish_new();
- thread_count = 1;
+ info.node = moonfish_new();
+ info.thread_count = 1;
+ info.searching = 0;
for (;;) {@@ -220,7 +237,27 @@
if (arg == NULL) continue;
if (!strcmp(arg, "go")) {- moonfish_go(node, thread_count);
+#ifdef moonfish_no_threads
+ moonfish_go(&info);
+#else
+ if (info.searching == 2) {+ if (thrd_join(info.thread, NULL) != thrd_success) {+ fprintf(stderr, "could not join thread\n");
+ exit(1);
+ }
+ }
+ else {+ if (info.searching) {+ fprintf(stderr, "cannot start search while searching\n");
+ exit(1);
+ }
+ }
+ info.searching = 1;
+ if (thrd_create(&info.thread, &moonfish_go, &info) != thrd_success) {+ fprintf(stderr, "could not create thread\n");
+ exit(1);
+ }
+#endif
continue;
}
@@ -227,7 +264,11 @@
if (!strcmp(arg, "quit")) break;
if (!strcmp(arg, "position")) {- moonfish_position(node);
+ if (info.searching == 1) {+ fprintf(stderr, "cannot set position while searching\n");
+ exit(1);
+ }
+ moonfish_position(info.node);
continue;
}
@@ -247,10 +288,27 @@
}
#ifndef moonfish_no_threads
+
if (!strcmp(arg, "setoption")) {- moonfish_setoption(&thread_count);
+ moonfish_setoption(&info.thread_count);
+ if (info.searching == 1) {+ printf("info string warning: option will only take effect next search request\n");+ }
continue;
}
+
+ if (!strcmp(arg, "stop")) {+ if (info.searching) {+ moonfish_stop(info.node);
+ if (thrd_join(info.thread, NULL) != thrd_success) {+ fprintf(stderr, "could not join thread\n");
+ exit(1);
+ }
+ info.searching = 0;
+ }
+ continue;
+ }
+
#endif
if (!strcmp(arg, "debug") || !strcmp(arg, "ucinewgame") || !strcmp(arg, "stop")) continue;
@@ -258,6 +316,16 @@
fprintf(stderr, "warning: unknown command '%s'\n", arg);
}
- moonfish_finish(node);
+#ifndef moonfish_no_threads
+ if (info.searching) {+ moonfish_stop(info.node);
+ if (thrd_join(info.thread, NULL) != thrd_success) {+ fprintf(stderr, "could not join thread\n");
+ exit(1);
+ }
+ }
+#endif
+
+ moonfish_finish(info.node);
return 0;
}
--- a/makefile
+++ b/makefile
@@ -12,7 +12,7 @@
all: moonfish lichess analyse chat
-moonfish: moonfish.h chess.c search.c main.c
+moonfish: moonfish.h threads.h chess.c search.c main.c
$(cc) $(filter %.c,$^) -o $@ -lm -pthread -latomic
%: moonfish.h tools/tools.h tools/utils.c chess.c tools/%.c
--- a/moonfish.h
+++ b/moonfish.h
@@ -202,4 +202,7 @@
/* frees the given state (so that it is no longer usable) */
void moonfish_finish(struct moonfish_node *node);
+/* requests to stop searching the given state (from a different thread) */
+void moonfish_stop(struct moonfish_node *node);
+
#endif
--- a/moonfish.vcxproj
+++ b/moonfish.vcxproj
@@ -20,6 +20,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="moonfish.h" />
+ <ClInclude Include="threads.h" />
<ClCompile Include="chess.c" />
<ClCompile Include="search.c" />
<ClCompile Include="main.c" />
--- a/scripts/compare.sh
+++ b/scripts/compare.sh
@@ -58,7 +58,7 @@
"$cli" \
-engine {name=,cmd=./}moonfish-"$rev1$dirty" \ -engine {name=,cmd=./}moonfish-"$rev2" \- -each $protocol tc=inf/10+0.1 \
+ -each $protocol tc=inf/10+0.1 option.Threads=1 \
-openings $format file=openings.fen order=random \
-games 2 -rounds 1024 \
-sprt elo0=0 elo1=12 alpha=0.05 beta=0.05 \
--- a/scripts/minify.sh
+++ b/scripts/minify.sh
@@ -11,7 +11,7 @@
(sleep 3;rm $t)&exec $t'
# for each C source file
-cat moonfish.h chess.c search.c mini.c |
+cat moonfish.h threads.h chess.c search.c mini.c |
# remove the '#' from system '#include'
sed -E 's/^#(include <)/\1/g' |
--- a/search.c
+++ b/search.c
@@ -13,42 +13,8 @@
#include <time.h>
#endif
-#ifdef moonfish_no_threads
-
-#define moonfish_result_t int
-#define moonfish_value 0
-#define _Atomic
-
-#else
-
-#include <stdatomic.h>
-
-#ifndef moonfish_pthreads
-
-#include <threads.h>
-#define moonfish_result_t int
-#define moonfish_value 0
-
-#else
-
-#include <pthread.h>
-#define thrd_t pthread_t
-#define thrd_create(thread, fn, arg) pthread_create(thread, NULL, fn, arg)
-#define thrd_join pthread_join
-#define moonfish_result_t void *
-#define moonfish_value NULL
-#define thrd_success 0
-
-#endif
-
-#endif
-
-#ifdef moonfish_mini
-#undef atomic_compare_exchange_strong
-#undef atomic_fetch_add
-#endif
-
#include "moonfish.h"
+#include "threads.h"
#ifdef _WIN32
@@ -323,6 +289,7 @@
moonfish_search(data->node, 0x100);
while (moonfish_clock() - data->time0 < data->time) {+ if (data->node->ignored) break;
count = data->node->count;
for (i = 0 ; i < data->node->count ; i++) {if (data->node->children[i].ignored) count--;
@@ -350,6 +317,7 @@
if (options->our_time >= 0 && time > options->our_time / 16) time = options->our_time / 16;
time -= time / 32 + 125;
+ node->ignored = 0;
data.node = node;
data.time = time;
data.time0 = moonfish_clock();
@@ -450,3 +418,12 @@
moonfish_discard(node);
free(node);
}
+
+#ifndef moonfish_mini
+
+void moonfish_stop(struct moonfish_node *node)
+{+ node->ignored = 1;
+}
+
+#endif
--- /dev/null
+++ b/threads.h
@@ -1,0 +1,42 @@
+/* moonfish is licensed under the AGPL (v3 or later) */
+/* copyright 2024 zamfofex */
+
+#ifndef MOONFISH_THREADS
+#define MOONFISH_THREADS
+
+#ifdef moonfish_no_threads
+
+#define moonfish_result_t int
+#define moonfish_value 0
+#define _Atomic
+
+#else
+
+#include <stdatomic.h>
+
+#ifndef moonfish_pthreads
+
+#include <threads.h>
+#define moonfish_result_t int
+#define moonfish_value 0
+
+#else
+
+#include <pthread.h>
+#define thrd_t pthread_t
+#define thrd_create(thread, fn, arg) pthread_create(thread, NULL, fn, arg)
+#define thrd_join pthread_join
+#define moonfish_result_t void *
+#define moonfish_value NULL
+#define thrd_success 0
+
+#endif
+
+#endif
+
+#ifdef moonfish_mini
+#undef atomic_compare_exchange_strong
+#undef atomic_fetch_add
+#endif
+
+#endif
--
⑨