diff options
Diffstat (limited to 'src/engine/threads.c')
| -rw-r--r-- | src/engine/threads.c | 21 |
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]; |
