#include #include #include #include #include "bitboard.h" #include "engine/moves.h" #include "fen.h" #include "fcntl.h" #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->uci_state_initialized = 0; pthread_t uci_thread; pthread_create(&uci_thread, NULL, &uci, (void*)comms); 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 (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; } #include "engine/moves.c"