#include #include #include #include #include #include #include "ipc/state.h" #include "ipc/threads.h" #include "ipc/uci.h" #include "engine/ttable.h" #include "engine/magic.h" void *uci_thread_func(void* data) { ipc_state_t *state = (ipc_state_t*)data; return uci(state); } int main(int argc, char** argv) { magic_init(); zobrist_init(); ipc_state_t ipc_state; ipc_state_init(&ipc_state); pthread_t uci_thread; pthread_create(&uci_thread, NULL, uci_thread_func, (void*)&ipc_state); struct threads engine_threads = {0}; threads_init(&engine_threads, ipc_state.uci_state.threads); threads_link(&engine_threads, &ipc_state); // initialise the transposition table from the UCI "Hash" option (in MiB). // pick the smallest power of two (>= 2^4) that fills at least that much memory. size_t hash_mb = (size_t)ipc_state.uci_state.hash; u64 buckets = (hash_mb * 1024 * 1024) / sizeof(tbucket_t); int hash_log2 = 4; while ((1ULL << (hash_log2 + 1)) <= buckets && hash_log2 < 30) hash_log2++; ttable_init(&engine_threads.ttable, hash_log2); engine_messages_init(&ipc_state.engine_messages); goto skip_refresh; waiting_for_go: engine_messages_refresh(&ipc_state.engine_messages); skip_refresh: bool is_stop, quit; while ( !ipc_state_is_event(&ipc_state, EVENT_ENGINE_GO) && !(quit = ipc_state_is_event(&ipc_state, EVENT_QUIT)) ); if (quit) goto quit; engine_threads.running_count = ipc_state.uci_state.threads; ipc_state.engine_messages.count = ipc_state.uci_state.threads; threads_reserve(&engine_threads, engine_threads.running_count); threads_go(&engine_threads); ipc_state_set_event(&ipc_state, EVENT_UCI_RUNNING); while (1) { while ( !ipc_state_is_event(&ipc_state, EVENT_ENGINE_RUNNING) && !(quit = ipc_state_is_event(&ipc_state, EVENT_QUIT)) && !(is_stop = ipc_state_is_event(&ipc_state, EVENT_ENGINE_STOP)) ); if (quit) { break; } if (is_stop) { // cooperative stop: signal all threads, wait for them to finish threads_stop_all(&engine_threads); threads_join(&engine_threads); threads_cleanup(&engine_threads); ipc_state_set_event(&ipc_state, EVENT_UCI_RUNNING); goto waiting_for_go; } threads_go_loop(&engine_threads); ipc_state_set_event(&ipc_state, EVENT_UCI_RUNNING); } quit: // cooperative stop for engine threads, then hard-cancel the UCI thread // (which blocks on stdin and cannot exit cooperatively). if (engine_threads.running_count > 0) { threads_stop_all(&engine_threads); threads_join(&engine_threads); } ipc_state_deinit(&ipc_state); pthread_cancel(uci_thread); threads_deinit(&engine_threads); return 0; } #include "fen.c" #include "bitboard.c" #include "random.c"