예제 #1
0
파일: ds.c 프로젝트: navicella/streamit
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 {
예제 #2
0
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;
}