diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/engine.c | 144 | ||||
| -rw-r--r-- | src/ipc.h | 6 | ||||
| -rw-r--r-- | src/uci.c | 1 | ||||
| -rw-r--r-- | src/uci/response.c | 49 | ||||
| -rw-r--r-- | src/uci/state.h | 7 |
5 files changed, 172 insertions, 35 deletions
diff --git a/src/engine.c b/src/engine.c index 944c0f4..a063520 100644 --- a/src/engine.c +++ b/src/engine.c @@ -10,38 +10,138 @@ #include "uci.h" #include "ipc.h" +// TODO: implement break conditions from the go command +struct thread_args { + int id; + int stop; + position_t position; + struct engine_message *message; +}; +void *engine_thread(void *_args) { + struct thread_args *args = (struct thread_args*)_args; + + int k = 0; + while (k < 10) { + if (args->stop) continue; + struct engine_message *message = args->message; + + k++; + message->depth = 69; + message->multipv = args->id; + message->pv = comm_moves_init(); + add_comm_move(&message->pv, (struct uci_move) { 14, 24 }); + + if (k == 10) { + message->best_move = (struct uci_move) { 12, 24 }; + message->ponder = (struct uci_move) { 42, 54 }; + } + + message->next = malloc(sizeof(struct engine_message*)); + message->ready = 1; + args->message = message->next; + } +} + +struct threads { + pthread_t *threads; + struct thread_args* args; + engine_messages *engine_messages; + size_t count; + size_t capacity; + + position_t sharing_position; +}; + +void increase_threads(struct threads *threads, size_t change) { + if (threads->count + change > threads->capacity) { + threads->capacity = threads->count + change + 16; // TODO: maybe round it to the upper power of 2 + } + + threads->threads = threads->threads == NULL + ? malloc(sizeof(*threads->threads) * threads->capacity) + : realloc(threads->threads, sizeof(*threads->threads) * threads->capacity); + + threads->args = threads->args == NULL + ? malloc(sizeof(*threads->args) * threads->capacity) + : realloc(threads->args, sizeof(*threads->args) * threads->capacity); + + threads->engine_messages->data = threads->engine_messages->data == NULL + ? malloc(sizeof(*threads->engine_messages->data) * threads->capacity) + : realloc( + threads->engine_messages->data, + sizeof(*threads->engine_messages->data) * threads->capacity + ); + + for (int i = threads->count; i < threads->count + change; i++) { + threads->engine_messages->data[i] = malloc(sizeof(struct engine_message)); + threads->engine_messages->data[i]->ready = 0; + threads->args[i] = (struct thread_args) { + i, + 0, + threads->sharing_position, + threads->engine_messages->data[i], + }; + pthread_create( + threads->threads + i, + NULL, + &engine_thread, + (void*)(threads->args + i) + ); + } + threads->count += change; + threads->engine_messages->count = threads->count; +} + +void decrease_threads(struct threads *threads, size_t change) { + for (int i = 0; i < change; i++) { + free(threads->engine_messages->data[threads->count - i - 1]); + pthread_cancel(threads->threads[threads->count - i - 1]); + } + threads->count -= change; + threads->engine_messages->count = threads->count; +} + +void set_threads(struct threads *threads, size_t new_size) { + if (new_size > threads->count) { + increase_threads(threads, new_size - threads->count); + } else { + decrease_threads(threads, threads->count - new_size); + } +} + +// TODO: someday fix that some structs have typedef, some dont int main(int argc, char** argv) { comms *comms = malloc(sizeof(*comms)); comms->engine_messages = malloc(sizeof(*comms->engine_messages)); - - comms->engine_messages->data = malloc( - sizeof(*comms->engine_messages->data) * 1 // TODO: GET FROM UCI SETTINGS - ); - comms->engine_messages->count = 1; - comms->engine_messages->data[0] = malloc(sizeof( - *comms->engine_messages->data[0] - )); - comms->engine_messages->data[0]->ready = 0; - - printf("ENGINE: %p\nENGINE MESSAGE: %p\n", comms, comms->engine_messages); + comms->uci_state_initialized = 0; pthread_t uci_thread; pthread_create(&uci_thread, NULL, &uci, (void*)comms); - int k = 0; + + while (atomic_load(&comms->uci_state_initialized) == 0); + comms->state.quit = 0; + + struct threads engine_threads = {0}; + engine_threads.engine_messages = comms->engine_messages; + int initialized = 0; + while (1) { - if (k == 0) { - struct engine_message *message = comms->engine_messages->data[0]; - message->depth = 69; - message->pv = comm_moves_init(); - add_comm_move(&message->pv, (struct uci_move) { 14, 24 }); - message->next = malloc(sizeof(struct engine_message*)); - printf("\n%p\n", message->pv.moves); - - message->ready = 1; - k++; + if (atomic_load(&comms->state.quit)) break; + if (!atomic_load(&comms->state.go)) continue; + + if (initialized == 0) { + engine_threads.sharing_position = comms->state.position; + set_threads(&engine_threads, comms->state.threads); + initialized = 1; } } + set_threads(&engine_threads, 0); + free(engine_threads.threads); + free(engine_threads.args); + free(comms->engine_messages); + free(comms->engine_messages->data); + free(comms); return 0; } @@ -29,6 +29,9 @@ struct engine_message { int time; comm_moves pv; + struct uci_move best_move; + struct uci_move ponder; + struct engine_message *next; }; @@ -40,9 +43,8 @@ typedef struct { enum { MESSAGE_FILLED, MESSAGE_READ, MESSAGE_PROCESSED }; typedef struct { engine_messages *engine_messages; - uci_state state; - + int uci_state_initialized; int uci_message_ready; struct fen_load from_position; comm_moves moves; @@ -97,6 +97,7 @@ void *uci(void *_com) { "<empty>", &com->state.uci_setpositionvalue ); + atomic_store(&com->uci_state_initialized, 1); ucicmd cmd = ucicmd_init(); size_t n; diff --git a/src/uci/response.c b/src/uci/response.c index dbf4614..6208a54 100644 --- a/src/uci/response.c +++ b/src/uci/response.c @@ -154,10 +154,22 @@ void handle_idle( int k = 0; char* mode = ucicmd_get_arg(cmd, 0); if (strcmp(mode, "startpos") == 0) { - state->position = load_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); + struct fen_load fen = load_fen( + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + ); + if (fen.failed) { + printf("info invalid fen\n"); + return; + } + state->position = fen.position; } else if (strcmp(mode, "fen") == 0) { - state->position = load_fen(ucicmd_get_arg(cmd, k++)); + struct fen_load fen = load_fen(ucicmd_get_arg(cmd, k++)); + if (fen.failed) { + printf("info invalid fen\n"); + return; + } + state->position = fen.position; } else { assert(0); } if (cmd.args_count >= k) return; @@ -185,7 +197,6 @@ void handle_idle( (move[2] - 'a') * 8 + (move[3] - '1') }; } - state->go = 1; } else if (strcmp(cmd.root, "stop") == 0) { } else if (strcmp(cmd.root, "quit") == 0) { free(cmd.args); @@ -197,10 +208,11 @@ void handle_idle( free(setting.value.string->data); } - exit(0); + atomic_store(&state->quit, 1); } else if (strcmp(cmd.root, "isready") == 0) { current_state = STATE_SYNC; } else if (strcmp(cmd.root, "go") == 0) { + atomic_store(&state->go, 1); current_state = STATE_ACTIVE; } else { printf("info violation\n"); @@ -238,7 +250,6 @@ void handle_active( for (int i = 0; i < engine_messages->count; i++) { struct engine_message *old = engine_messages->data[i]; if (!old->ready) continue; - printf("INITIALIZED\n"); old->ready = 0; printf( @@ -265,10 +276,30 @@ void handle_active( ); } printf("\n"); - // // info depth 1 seldepth 1 multipv 1 score cp 18 nodes 20 nps 4000 hashfull 0 tbhits 0 time 5 pv e2e4 - // - // engine_messages->data[i] = old->next; - // free(old); + + if (old->best_move.from != 0 && old->best_move.to != 0) { + printf( + "bestmove %c%c%c%c", + (old->best_move.from / 8) + 'a', + (old->best_move.from % 8) + '1', + (old->best_move.to / 8) + 'a', + (old->best_move.to % 8) + '1' + ); + if (old->ponder.from != 0 && old->ponder.to != 0) { + printf( + " ponder %c%c%c%c", + (old->ponder.from / 8) + 'a', + (old->ponder.from % 8) + '1', + (old->ponder.to / 8) + 'a', + (old->ponder.to % 8) + '1' + ); + } + printf("\n"); + } + + engine_messages->data[i] = old->next; + free(old->pv.moves); + free(old); } // TODO: this section will call the engine to analysis if (cmd.empty) { diff --git a/src/uci/state.h b/src/uci/state.h index 9b09774..9c59a3a 100644 --- a/src/uci/state.h +++ b/src/uci/state.h @@ -1,6 +1,7 @@ #ifndef UCI_STATE_H #define UCI_STATE_H +#include <stdatomic.h> #include "../fen.h" typedef struct { @@ -80,8 +81,10 @@ typedef struct { char author[32]; bool debug; - int go; - struct fen_load position; + atomic_int go; + atomic_int quit; + + position_t position; struct uci_move *moves; int moves_count; |
