#ifndef ENGINE_THREADS_H #define ENGINE_THREADS_H #include #include #include "bitboard.h" #include "engine/ttable.h" #include "ipc/engine_message.h" #include "ipc/go_args.h" enum { SPLITPOINT_STATE_FREE, SPLITPOINT_STATE_ACTIVE }; enum { NODE_PV, NODE_CUT, NODE_ALL }; // §2.1 thrashing guard: refuse HELP when nodes_searched < THRESHOLD at a // split point. Prevents the end-of-iteration "N idle procs split 1 proc". enum { SPLITPOINT_THRASH_THRESHOLD = 256 }; typedef struct split_point { atomic_int state; atomic_int next_move_idx; atomic_int alpha, beta; atomic_int best_score; atomic_int workers; atomic_int nodes_searched; // §2.1 thrashing guard: refuse HELP when < threshold move_t best_move; struct split_point *parent; int ply; int depth; // remaining search depth at this node int node_type; int confidence; position_t position_snapshot; moves_t moves; } split_point_t; struct child_thread_args { // signal sent by threads manager atomic_int stop; // signal sent by thread atomic_int finished; int id; go_args_t *go_args; position_t *position; ttable_t *ttable; split_point_t *split_points; // shared DTS pool (§2.4) size_t sp_pool_capacity; engine_message_handler_t *message; }; struct root_thread_args { // signal sent by threads manager atomic_int stop; // signal sent by thread atomic_int finished; int id; position_t *position; go_args_t *go_args; engine_message_handler_t *message; ttable_t *ttable; split_point_t *split_points; // shared DTS pool (§2.4) size_t sp_pool_capacity; // the root stops its workers when the search completes. struct threads *handler; int workers_count; }; typedef union thread_args { struct child_thread_args child_thread_args; struct root_thread_args root_thread_args; } thread_args_t; struct threads { pthread_t *threads; thread_args_t *args; size_t count; size_t capacity; int running_count; engine_messages_t *engine_messages; go_args_t *go_args; position_t *position; ttable_t ttable; void* split_point_pool; }; #ifdef ENGINE_THREADS_INTERNAL void __threads_args_init( thread_args_t* args, struct threads *handler, int i ); // DTS primitives (§2.3–2.8): split point pool + lock-free move claiming split_point_t *split_point_alloc(struct threads *handler); split_point_t *__pool_alloc(split_point_t *pool, size_t capacity); void split_point_free(struct threads *handler, split_point_t *split_point); void split_point_publish(split_point_t *split_point); bool split_point_claim_move(split_point_t *split_point, move_t *move); bool split_point_merge(split_point_t *split_point); void split_point_share(split_point_t *split_point, i32 score, move_t move); // §2.1 thrashing guard: true if this split point has been searched enough // to be worth publishing for HELP. bool split_point_worth_sharing(split_point_t *split_point); // HELP (§2.3): scan the pool for a published split point with work left split_point_t *threads_find_work(struct threads *handler); split_point_t *__pool_find_work(split_point_t *pool, size_t capacity); #endif void threads_init(struct threads *handler, size_t capacity); void threads_deinit(struct threads *handler); void threads_reserve(struct threads *handler, size_t capacity); void threads_go(struct threads *handler); bool threads_go_loop(struct threads *handler); bool threads_all_done(struct threads *handler); void threads_stop_all(struct threads *handler); void threads_join(struct threads *handler); void threads_cleanup(struct threads *handler); void *child_thread(void *args); void *root_thread(void *args); #endif // ENGINE_THREADS_H