#include #include #include #include #include "fcntl.h" #include "bitboard.h" #include "moves.h" #include "fen.h" #include "uci.h" #include "ipc.h" struct thread_args { int id; int stop; position_t position; struct go_args *go_args; struct engine_message *message; }; void *engine_thread(void *_args) { printf("NIGGGGA\n"); struct thread_args *args = (struct thread_args*)_args; args->stop = 0; int depth = 0; while (true) { struct engine_message *message = args->message; message->depth = depth++; message->multipv = args->id; message->pv = comm_moves_init(); // pseudo engine work for (volatile int k = 0; k < 1000000000; k++) {} add_comm_move(&message->pv, (struct uci_move) { 14, 24 }); if (args->stop || !should_continue(message, args->go_args)) { message->best_move = (struct uci_move) { 12, 24 }; message->ponder = (struct uci_move) { 42, 54 }; message->next = NULL; message->ready = 1; break; } message->next = malloc(sizeof(struct engine_message*)); message->next->ready = 0; message->ready = 1; args->message = message->next; } args->stop = 2; } struct threads { pthread_t *threads; struct thread_args* args; struct go_args *go_args; engine_messages *engine_messages; size_t count; size_t capacity; position_t sharing_position; }; void increase_threads(struct threads *threads, size_t change) { int old_capacity = threads->capacity; if (threads->count + change > threads->capacity) { threads->capacity = threads->count + change + 16; } threads->threads = threads->threads == NULL ? malloc(sizeof(pthread_t) * threads->capacity) : realloc(threads->threads, sizeof(pthread_t) * threads->capacity); threads->args = threads->args == NULL ? malloc(sizeof(struct thread_args) * threads->capacity) : realloc(threads->args, sizeof(struct thread_args) * threads->capacity); threads->engine_messages->data = threads->engine_messages->data == NULL ? malloc(sizeof(struct engine_message*) * threads->capacity) : realloc( threads->engine_messages->data, sizeof(struct engine_message*) * 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->go_args, 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++) { struct engine_message *item = threads->engine_messages->data[i]; threads->engine_messages->data[i] = NULL; free(item); 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); } } void send_stop_signal(struct threads *threads) { for (int i = 0; i < threads->count; i++) { if (threads->args[i].stop) continue; threads->args[i].stop = 1; } } bool all_stopped(struct threads *threads) { if (threads->count == 0) return false; for (int i = 0; i < threads->count; i++) { if (threads->args[i].stop == 2) continue; return false; } return true; } // 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 = NULL; 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; while (1) { if (atomic_load(&comms->state.quit)) break; if (atomic_load(&comms->state.cleanup)) { set_threads(&engine_threads, 0); for (int i = 0; i < engine_threads.count; i++) { engine_threads.args[i].stop = -1; } } if (atomic_load(&comms->state.go)) { printf("going\n"); engine_threads.sharing_position = comms->state.position; engine_threads.go_args = (struct go_args*)comms->state.go_args; set_threads(&engine_threads, comms->state.threads); atomic_store(&comms->state.go, 0); atomic_store(&comms->state.go_ready_receive, 1); } if (atomic_load(&comms->state.stop)) { printf("stopping\n"); send_stop_signal(&engine_threads); if (!all_stopped(&engine_threads)) continue; set_threads(&engine_threads, 0); for (int i = 0; i < engine_threads.count; i++) { engine_threads.args[i].stop = -1; } atomic_store(&comms->state.stop, 0); } } pthread_cancel(uci_thread); set_threads(&engine_threads, 0); free(engine_threads.threads); free(engine_threads.args); for (int i = 0; i < engine_threads.count; i++) { free(engine_threads.engine_messages->data[i]); } free(comms->engine_messages->data); free(comms->engine_messages); free(comms); return 0; } #include "engine/moves.c"