/* Allocate a series branch * @param length maximum number of half-moves of slice (+ slack) * @param min_length minimum number of half-moves of slice (+ slack) * @return index of entry slice into allocated series branch */ slice_index alloc_series_branch(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",length); TraceFunctionParam("%u",min_length); TraceFunctionParamListEnd(); { slice_index const adapter = alloc_help_adapter_slice(length,min_length); slice_index const ready = alloc_branch(STReadyForHelpMove, length,min_length); slice_index const testpre = alloc_pipe(STTestingPrerequisites); slice_index const generating = alloc_pipe(STGeneratingMoves); slice_index const done_generating = alloc_pipe(STDoneGeneratingMoves); slice_index const done_removing_illegal = alloc_pipe(STDoneRemovingIllegalMoves); slice_index const done_removing_futile = alloc_pipe(STDoneRemovingFutileMoves); slice_index const done_priorising = alloc_pipe(STDonePriorisingMoves); slice_index const move = alloc_pipe(STMove); slice_index const played1 = alloc_help_move_played_slice(); slice_index const not_end_goal1 = alloc_pipe(STNotEndOfBranchGoal); slice_index const played2 = alloc_help_move_played_slice(); slice_index const not_end_goal2 = alloc_pipe(STNotEndOfBranchGoal); slice_index const deadend = alloc_pipe(STDeadEnd); result = adapter; pipe_link(adapter,ready); pipe_link(ready,testpre); pipe_link(testpre,generating); pipe_link(generating,done_generating); pipe_link(done_generating,done_removing_illegal); pipe_link(done_removing_illegal,done_removing_futile); pipe_link(done_removing_futile,done_priorising); pipe_link(done_priorising,move); pipe_link(move,played1); pipe_link(played1,not_end_goal1); pipe_link(not_end_goal1,played2); pipe_link(played2,not_end_goal2); pipe_link(not_end_goal2,adapter); if (length%2==0) /* branch ends after the pseudo move */ pipe_append(not_end_goal2,deadend); else /* branch ends after the real move */ pipe_append(not_end_goal1,deadend); } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static inline int get_block(struct inode * inode, sector_t block, struct buffer_head *bh, int create) { int err = -EIO; int offsets[DEPTH]; Indirect chain[DEPTH]; Indirect *partial; int left; int depth = block_to_path(inode, block, offsets); if (depth == 0) goto out; reread: partial = get_branch(inode, depth, offsets, chain, &err); if (!partial) { got_it: map_bh(bh, inode->i_sb, block_to_cpu(chain[depth-1].key)); partial = chain+depth-1; goto cleanup; } if (!create || err == -EIO) { cleanup: while (partial > chain) { brelse(partial->bh); partial--; } out: return err; } if (err == -EAGAIN) goto changed; left = (chain + depth) - partial; err = alloc_branch(inode, left, offsets+(partial-chain), partial); if (err) goto cleanup; if (splice_branch(inode, chain, partial, left) < 0) goto changed; set_buffer_new(bh); goto got_it; changed: while (partial > chain) { brelse(partial->bh); partial--; } goto reread; }
/* Allocate a STStopOnShortSolutionsFilter slice. * @param length full length * @param length minimum length * @return allocated slice */ slice_index alloc_stoponshortsolutions_filter(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); result = alloc_branch(STStopOnShortSolutionsFilter,length,min_length); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Allocate a STDegenerateTree slice * @return allocated slice */ static slice_index alloc_degenerate_tree_guard_slice(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",length); TraceFunctionParam("%u",min_length); TraceFunctionParamListEnd(); result = alloc_branch(STDegenerateTree,length,min_length); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Allocate a STFindByIncreasingLength slice. * @param length maximum number of half-moves of slice (+ slack) * @param min_length minimum number of half-moves of slice (+ slack) * @return index of allocated slice */ slice_index alloc_find_by_increasing_length_slice(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",length); TraceFunctionParam("%u",min_length); TraceFunctionParamListEnd(); result = alloc_branch(STFindByIncreasingLength,length,min_length); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Allocate a STDefenseAdapter slice. * @param length maximum number of half-moves of slice (+ slack) * @param min_length minimum number of half-moves of slice (+ slack) * @return index of allocated slice */ slice_index alloc_defense_adapter_slice(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",length); TraceFunctionParam("%u",min_length); TraceFunctionParamListEnd(); result = alloc_branch(STDefenseAdapter,length,min_length); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
static inline int get_block(struct inode * inode, sector_t block, struct buffer_head *bh, int create) { int err = -EIO; int offsets[DEPTH]; Indirect chain[DEPTH]; Indirect *partial; int left; int depth = block_to_path(inode, block, offsets); if (depth == 0) goto out; reread: partial = get_branch(inode, depth, offsets, chain, &err); /* Simplest case - block found, no allocation needed */ if (!partial) { got_it: map_bh(bh, inode->i_sb, block_to_cpu(chain[depth-1].key)); /* Clean up and exit */ partial = chain+depth-1; /* the whole chain */ goto cleanup; } /* Next simple case - plain lookup or failed read of indirect block */ if (!create || err == -EIO) { cleanup: while (partial > chain) { brelse(partial->bh); partial--; } out: return err; } /* * Indirect block might be removed by truncate while we were * reading it. Handling of that case (forget what we've got and * reread) is taken out of the main path. */ if (err == -EAGAIN) goto changed; left = (chain + depth) - partial; err = alloc_branch(inode, left, offsets+(partial-chain), partial); if (err) goto cleanup; if (splice_branch(inode, chain, partial, left) < 0) goto changed; set_buffer_new(bh); goto got_it; changed: while (partial > chain) { brelse(partial->bh); partial--; } goto reread; }
/* Allocate a help branch. * @param length maximum number of half-moves of slice (+ slack) * @param min_length minimum number of half-moves of slice (+ slack) * @param proxy_to_next identifies slice leading towards goal * @return index of entry slice into allocated series branch */ slice_index alloc_help_branch(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",length); TraceFunctionParam("%u",min_length); TraceFunctionParamListEnd(); { slice_index const adapter = alloc_help_adapter_slice(length,min_length); slice_index const ready1 = alloc_branch(STReadyForHelpMove, length,min_length); slice_index const testpre1 = alloc_pipe(STTestingPrerequisites); slice_index const generating1 = alloc_pipe(STGeneratingMoves); slice_index const done_generating1 = alloc_pipe(STDoneGeneratingMoves); slice_index const done_removing_illegal1 = alloc_pipe(STDoneRemovingIllegalMoves); slice_index const done_removing_futile1 = alloc_pipe(STDoneRemovingFutileMoves); slice_index const done_priorising1 = alloc_pipe(STDonePriorisingMoves); slice_index const move1 = alloc_pipe(STMove); slice_index const played1 = alloc_help_move_played_slice(); slice_index const not_end_goal1 = alloc_pipe(STNotEndOfBranchGoal); slice_index const ready2 = alloc_branch(STReadyForHelpMove, length-1,min_length-1); slice_index const testpre2 = alloc_pipe(STTestingPrerequisites); slice_index const generating2 = alloc_pipe(STGeneratingMoves); slice_index const done_generating2 = alloc_pipe(STDoneGeneratingMoves); slice_index const done_removing_illegal2 = alloc_pipe(STDoneRemovingIllegalMoves); slice_index const done_removing_futile2 = alloc_pipe(STDoneRemovingFutileMoves); slice_index const done_priorising2 = alloc_pipe(STDonePriorisingMoves); slice_index const move2 = alloc_pipe(STMove); slice_index const played2 = alloc_help_move_played_slice(); slice_index const not_end_goal2 = alloc_pipe(STNotEndOfBranchGoal); slice_index const deadend = alloc_pipe(STDeadEnd); pipe_link(adapter,ready1); pipe_link(ready1,testpre1); pipe_link(testpre1,generating1); pipe_link(generating1,done_generating1); pipe_link(done_generating1,done_removing_illegal1); pipe_link(done_removing_illegal1,done_removing_futile1); pipe_link(done_removing_futile1,done_priorising1); pipe_link(done_priorising1,move1); pipe_link(move1,played1); pipe_link(played1,not_end_goal1); pipe_link(not_end_goal1,ready2); pipe_link(ready2,testpre2); pipe_link(testpre2,generating2); pipe_link(generating2,done_generating2); pipe_link(done_generating2,done_removing_illegal2); pipe_link(done_removing_illegal2,done_removing_futile2); pipe_link(done_removing_futile2,done_priorising2); pipe_link(done_priorising2,move2); pipe_link(move2,played2); pipe_link(played2,not_end_goal2); pipe_link(not_end_goal2,adapter); if (length%2==0) help_branch_insert_slices(adapter,&deadend,1); else help_branch_insert_slices(move1,&deadend,1); result = adapter; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Allocate a branch that represents battle play * @param length maximum number of half-moves of slice (+ slack) * @param min_length minimum number of half-moves of slice (+ slack) * @return index of entry slice to allocated branch */ slice_index alloc_battle_branch(stip_length_type length, stip_length_type min_length) { slice_index result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",length); TraceFunctionParam("%u",min_length); TraceFunctionParamListEnd(); { slice_index const adapter = alloc_attack_adapter_slice(length,min_length); slice_index const aready = alloc_branch(STReadyForAttack,length,min_length); slice_index const atestpre = alloc_pipe(STTestingPrerequisites); slice_index const adeadend = alloc_pipe(STDeadEnd); slice_index const agenerating = alloc_pipe(STGeneratingMoves); slice_index const done_agenerating = alloc_pipe(STDoneGeneratingMoves); slice_index const done_aremoving_illegal = alloc_pipe(STDoneRemovingIllegalMoves); slice_index const done_aremoving_futile = alloc_pipe(STDoneRemovingFutileMoves); slice_index const done_apriorising = alloc_pipe(STDonePriorisingMoves); slice_index const attack = alloc_pipe(STMove); slice_index const aplayed = alloc_attack_played_slice(); slice_index const anotgoal = alloc_pipe(STNotEndOfBranchGoal); slice_index const anotend = alloc_pipe(STNotEndOfBranch); slice_index const dready = alloc_branch(STReadyForDefense, length-1,min_length-1); slice_index const dtestpre = alloc_pipe(STTestingPrerequisites); slice_index const ddeadend = alloc_pipe(STDeadEnd); slice_index const dgenerating = alloc_pipe(STGeneratingMoves); slice_index const done_dgenerating = alloc_pipe(STDoneGeneratingMoves); slice_index const done_dremoving_illegal = alloc_pipe(STDoneRemovingIllegalMoves); slice_index const done_dremoving_futile = alloc_pipe(STDoneRemovingFutileMoves); slice_index const done_dpriorising = alloc_pipe(STDonePriorisingMoves); slice_index const defense = alloc_pipe(STMove); slice_index const dplayed = alloc_defense_played_slice(); slice_index const dnotgoal = alloc_pipe(STNotEndOfBranchGoal); slice_index const dnotend = alloc_pipe(STNotEndOfBranch); pipe_link(adapter,aready); pipe_link(aready,atestpre); pipe_link(atestpre,adeadend); pipe_link(adeadend,agenerating); pipe_link(agenerating,done_agenerating); pipe_link(done_agenerating,done_aremoving_illegal); pipe_link(done_aremoving_illegal,done_aremoving_futile); pipe_link(done_aremoving_futile,done_apriorising); pipe_link(done_apriorising,attack); pipe_link(attack,aplayed); pipe_link(aplayed,anotgoal); pipe_link(anotgoal,anotend); pipe_link(anotend,dready); pipe_link(dready,dtestpre); pipe_link(dtestpre,ddeadend); pipe_link(ddeadend,dgenerating); pipe_link(dgenerating,done_dgenerating); pipe_link(done_dgenerating,done_dremoving_illegal); pipe_link(done_dremoving_illegal,done_dremoving_futile); pipe_link(done_dremoving_futile,done_dpriorising); pipe_link(done_dpriorising,defense); pipe_link(defense,dplayed); pipe_link(dplayed,dnotgoal); pipe_link(dnotgoal,dnotend); pipe_link(dnotend,adapter); result = adapter; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }