static void calc_filter_buffering(FILTER *f) { uint32_t input_iters = 0; uint32_t output_iters = 0; for (uint32_t i = 0; i < f->desc.num_inputs; i++) { CHANNEL *c = f->inputs[i]; c->input.spu_buf_size = c->input.peek_extra_bytes + ((((c->buf.head + c->input.peek_extra_bytes) | c->input.pop_bytes) & QWORD_MASK) == 0 ? CHECK : QWORD_MASK + QWORD_MASK); } for (uint32_t i = 0; i < f->desc.num_outputs; i++) { CHANNEL *c = f->outputs[i]; c->output.spu_buf_size = (((c->buf.tail | c->output.push_bytes) & QWORD_MASK) == 0 ? 0 : QWORD_MASK); } if (!f->exclusive) { input_iters = calc_max_iters(f, TRUE, FALSE, 32768); if (input_iters < DS_MIN_GROUP_ITERS) { f->exclusive = TRUE; } } if (!f->exclusive) { output_iters = calc_max_iters(f, FALSE, TRUE, 32768); if (output_iters < DS_MIN_GROUP_ITERS) { f->exclusive = TRUE; } } if (!f->exclusive) { f->group_iters = min_uint32(input_iters, output_iters); } else { f->group_iters = calc_max_iters(f, TRUE, TRUE, 32768 * 3); check(f->group_iters != 0); } calc_input_buffering(f, f->group_iters, TRUE); calc_output_buffering(f, f->group_iters, TRUE); f->loop_iters = max_uint32(f->group_iters / DS_MIN_GROUP_ITERS, 1); #if PRINT_BUFFERING printf("Filter %2d [%-20.20s]: %-1.1s g: %5d l: %5d b: %5d\n", f - filters, f->name, (f->exclusive ? "e" : ""), f->group_iters, f->loop_iters, f->output_buffered_iters); if (f->desc.num_inputs != 0) { printf(" I:"); for (uint32_t i = 0; i < f->desc.num_inputs; i++) { uint32_t buf_size = f->inputs[i]->input.spu_buf_size; if (buf_size >= 1024) { printf(" %2dk", buf_size >> 10); } else {
int freecell_solver_user_resume_solution( void * user_instance ) { int init_num_times; int run_for_first_iteration = 1; int ret; fcs_user_t * user; user = (fcs_user_t*)user_instance; ret = FCS_STATE_IS_NOT_SOLVEABLE; /* * I expect user->current_instance_idx to be initialized at some value. * */ for( ; run_for_first_iteration || ((user->current_instance_idx < user->num_instances) && (ret == FCS_STATE_IS_NOT_SOLVEABLE)) ; recycle_instance(user, user->current_instance_idx), user->current_instance_idx++ ) { run_for_first_iteration = 0; user->instance = user->instances_list[user->current_instance_idx].instance; if (user->instances_list[user->current_instance_idx].ret == FCS_STATE_NOT_BEGAN_YET) { int status; #if (!(defined(HARD_CODED_NUM_FREECELLS) && defined(HARD_CODED_NUM_STACKS) && defined(HARD_CODED_NUM_DECKS))) fc_solve_instance_t * instance = user->instance; #endif status = fc_solve_initial_user_state_to_c( user->state_string_copy, &(user->state.s), &(user->state.info), INSTANCE_FREECELLS_NUM, INSTANCE_STACKS_NUM, INSTANCE_DECKS_NUM #ifdef FCS_WITH_TALONS ,user->instance->talon_type #endif #ifdef INDIRECT_STACK_STATES ,user->indirect_stacks_buffer #endif ); if (status != FCS_USER_STATE_TO_C__SUCCESS) { user->ret = FCS_STATE_INVALID_STATE; user->state_validity_ret = FCS_STATE_VALIDITY__PREMATURE_END_OF_INPUT; return user->ret; } user->state_validity_ret = fc_solve_check_state_validity( &(user->state.info), INSTANCE_FREECELLS_NUM, INSTANCE_STACKS_NUM, INSTANCE_DECKS_NUM, #ifdef FCS_WITH_TALONS FCS_TALON_NONE, #endif &(user->state_validity_card)); if (user->state_validity_ret != FCS_STATE_VALIDITY__OK) { user->ret = FCS_STATE_INVALID_STATE; return user->ret; } /* running_state is a normalized state. So I'm duplicating * state to it before state is canonized * */ fcs_duplicate_state( &(user->running_state.s), &(user->running_state.info), &(user->state.s), &(user->state.info) ); fc_solve_canonize_state( &user->state.info, INSTANCE_FREECELLS_NUM, INSTANCE_STACKS_NUM ); fc_solve_init_instance(user->instance); #define global_limit() \ (user->instance->num_times + user->current_iterations_limit - user->iterations_board_started_at) #define local_limit() \ (user->instances_list[user->current_instance_idx].limit) #define min(a,b) (((a)<(b))?(a):(b)) #define calc_max_iters() \ { \ if (user->instances_list[user->current_instance_idx].limit < 0) \ {\ if (user->current_iterations_limit < 0)\ {\ user->instance->max_num_times = -1;\ }\ else\ {\ user->instance->max_num_times = global_limit();\ }\ }\ else\ {\ if (user->current_iterations_limit < 0)\ {\ user->instance->max_num_times = local_limit();\ }\ else\ {\ int a, b;\ \ a = global_limit();\ b = local_limit();\ \ user->instance->max_num_times = min(a,b);\ }\ }\ } calc_max_iters(); user->init_num_times = init_num_times = user->instance->num_times; ret = user->ret = user->instances_list[user->current_instance_idx].ret = fc_solve_solve_instance(user->instance, &user->state.info); } else { calc_max_iters(); user->init_num_times = init_num_times = user->instance->num_times; ret = user->ret = user->instances_list[user->current_instance_idx].ret = fc_solve_resume_instance(user->instance); } user->iterations_board_started_at += user->instance->num_times - init_num_times; user->init_num_times = user->instance->num_times; if (user->ret == FCS_STATE_WAS_SOLVED) { #if (!(defined(HARD_CODED_NUM_FREECELLS) && defined(HARD_CODED_NUM_STACKS) && defined(HARD_CODED_NUM_DECKS))) fc_solve_instance_t * instance = user->instance; #endif fc_solve_move_stack_normalize( user->instance->solution_moves, &(user->state.info), INSTANCE_FREECELLS_NUM, INSTANCE_STACKS_NUM, INSTANCE_DECKS_NUM ); break; } else if (user->ret == FCS_STATE_SUSPEND_PROCESS) { /* * First - check if we exceeded our limit. If so - we must terminate * and return now. * */ if ((user->current_iterations_limit >= 0) && (user->iterations_board_started_at >= user->current_iterations_limit)) { break; } /* * Determine if we exceeded the instance-specific quota and if * so, designate it as unsolvable. * */ if ((local_limit() >= 0) && (user->instance->num_times >= local_limit()) ) { ret = FCS_STATE_IS_NOT_SOLVEABLE; } } } return ret; }