summaryrefslogtreecommitdiff
path: root/src/engine/threads.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/threads.c')
-rw-r--r--src/engine/threads.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/engine/threads.c b/src/engine/threads.c
index c0d1da7..fe38013 100644
--- a/src/engine/threads.c
+++ b/src/engine/threads.c
@@ -109,11 +109,17 @@ void __threads_args_init(
args->go_args = handler->go_args;
args->message = handler->engine_messages->data[i];
args->ttable = &handler->ttable;
+ args->split_points = handler->split_point_pool;
+ args->sp_pool_capacity = handler->capacity;
+ args->workers_stop = handler->running_count > 1
+ ? &handler->args[1].child_thread_args.stop
+ : NULL;
+ args->workers_count = handler->running_count - 1;
}
-split_point_t *split_point_alloc(struct threads *handler) {
- for (size_t i = 0; i < handler->capacity; i++) {
- split_point_t *sp = (split_point_t*)handler->split_point_pool + i;
+split_point_t *__pool_alloc(split_point_t *pool, size_t capacity) {
+ for (size_t i = 0; i < capacity; i++) {
+ split_point_t *sp = pool + i;
int expected = SPLITPOINT_STATE_FREE;
if (!atomic_compare_exchange_weak(&sp->state, &expected, SPLITPOINT_STATE_ACTIVE)) continue;
@@ -124,11 +130,18 @@ split_point_t *split_point_alloc(struct threads *handler) {
// workers counts only registered helpers; the creator registers itself
atomic_store(&sp->workers, 0);
sp->best_move = (move_t) { 0 };
+ // recycled block: release the previous occupant's move list
+ moves_deinit(sp->moves);
+ sp->moves = moves_empty();
return sp;
}
return NULL;
}
+split_point_t *split_point_alloc(struct threads *handler) {
+ return __pool_alloc(handler->split_point_pool, handler->capacity);
+}
+
void split_point_free(struct threads *handler, split_point_t *split_point) {
// Unsplit (§2.7): drop the block back into the pool
atomic_store(&split_point->state, SPLITPOINT_STATE_FREE);
@@ -141,6 +154,8 @@ void split_point_publish(split_point_t *split_point) {
// Select (§2.5): lock-free claim of the next move via the shared counter
bool split_point_claim_move(split_point_t *split_point, move_t *move) {
+ // a block that was already Unsplitten must not be claimed from anymore
+ if (atomic_load(&split_point->state) != SPLITPOINT_STATE_ACTIVE) return false;
int idx = atomic_fetch_add(&split_point->next_move_idx, 1);
if (idx >= (int)split_point->moves.length) return false;
*move = split_point->moves.moves[idx];