static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start, u8 end, phys_addr_t addr) { int result; struct device *dev = &info->bridge->dev; info->start_bus = start; info->end_bus = end; info->mcfg_added = false; /* return success if MMCFG is not in use */ if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg) return 0; if (!(pci_probe & PCI_PROBE_MMCONF)) return check_segment(seg, dev, "MMCONFIG is disabled,"); result = pci_mmconfig_insert(dev, seg, start, end, addr); if (result == 0) { /* enable MMCFG if it hasn't been enabled yet */ if (raw_pci_ext_ops == NULL) raw_pci_ext_ops = &pci_mmcfg; info->mcfg_added = true; } else if (result != -EEXIST) return check_segment(seg, dev, "fail to add MMCONFIG information,"); return 0; }
TEST test_create_allocate_get_release_free_and_destroy() { // Allocate segment list segment_list_t *segment_list = create_segment_list(".", "test_segment_list.str", SIZE, DELETE_IF_EXISTS); ASSERT(segment_list != NULL); // Make sure the list is empty ASSERT(segment_list->is_empty(segment_list)); // The start segment is always zero // TODO: Should be able to get the first free segment //uint32_t segment_number = segment_list->get_next_free_segment(segment_list); //ASSERT(segment_number > 0); uint32_t segment_number = 0; // Allocate the first segment // FREE -> WRITING ASSERT(segment_list->allocate_segment(segment_list, segment_number) >= 0); // Close the segment we just allocated // WRITING -> CLOSED ASSERT(segment_list->close_segment(segment_list, segment_number) >= 0); // Attempt to get the segment we just closed for writing. This should not work, but return with // an error so we could recover if we were just too slow. segment_t *segment = segment_list->get_segment_for_writing(segment_list, segment_number); ASSERT(segment == NULL); // Get the segment we just closed // CLOSED -> READING segment = segment_list->get_segment_for_reading(segment_list, segment_number); ASSERT_EQ(check_segment(segment, 1), 0); ASSERT(segment != NULL); // Try to free the segment we just got. This should fail // READING -> FREE ASSERT(segment_list->free_segments(segment_list, segment_number, true/*destroy_store*/) == segment_number); ASSERT_EQ(check_segment(segment, 1), 0); // Release the segment we just allocated ASSERT(segment_list->release_segment_for_reading(segment_list, segment_number) >= 0); // Try to free the segment we just released ASSERT(segment_list->free_segments(segment_list, segment_number, true/*destroy_store*/) == segment_number + 1); // Try to get the segment we just freed. This should fail. This can happen in normal operation // if a thread is just too slow, so these functions should return NULL so the slow thread can // recover, rather than throwing an exception. segment = segment_list->get_segment_for_writing(segment_list, segment_number); ASSERT(segment == NULL); segment = segment_list->get_segment_for_reading(segment_list, segment_number); ASSERT(segment == NULL); // Destroy segment list ASSERT_EQ(segment_list->destroy(segment_list), 0); PASS(); }
// ---------------------------------------------------------------------------------------------------------------- // Recursively parse mine structure, drawing segments. void draw_mine_sub(int segnum,int depth) { segment *mine_ptr; if (Been_visited[segnum]) return; // If segment already drawn, return. Been_visited[segnum] = 1; // Say that this segment has been drawn. mine_ptr = &Segments[segnum]; // If this segment is active, process it, else skip it. if (mine_ptr->segnum != -1) { int side; if (Search_mode) check_segment(mine_ptr); else add_edges(mine_ptr); //add this segments edges to list if (depth != 0) { for (side=0; side<MAX_SIDES_PER_SEGMENT; side++) { if (IS_CHILD(mine_ptr->children[side])) { if (mine_ptr->sides[side].wall_num != -1) draw_special_wall(mine_ptr, side); draw_mine_sub(mine_ptr->children[side],depth-1); } } } } }
/** * Writes a coap option from given string @p s to @p buf. @p s should * point to a (percent-encoded) path or query segment of a coap_uri_t * object. The created option will have type @c 0, and the length * parameter will be set according to the size of the decoded string. * On success, this function returns the option's size, or a value * less than zero on error. This function must be called from * coap_split_path_impl() only. * * @param s The string to decode. * @param length The size of the percent-encoded string @p s. * @param buf The buffer to store the new coap option. * @param buflen The maximum size of @p buf. * * @return The option's size, or @c -1 on error. * * @bug This function does not split segments that are bigger than 270 * bytes. */ static int make_decoded_option(const unsigned char *s, size_t length, unsigned char *buf, size_t buflen) { int res; size_t written; if (!buflen) { debug("make_decoded_option(): buflen is 0!\n"); return -1; } res = check_segment(s, length); if (res < 0) return -1; /* write option header using delta 0 and length res */ written = coap_opt_setheader(buf, buflen, 0, res); assert(written <= buflen); if (!written) /* encoding error */ return -1; buf += written; /* advance past option type/length */ buflen -= written; if (buflen < (size_t)res) { debug("buffer too small for option\n"); return -1; } decode_segment(s, length, buf); return written + res; }
bool sphere_and_point_collision(const Point &segment_start, const Point &segment_end, double sphere_radius, const Point &point) { check_segment( segment_start, segment_end ); return greater_or_equal( sphere_radius, distance_between_point_and_segment( point, segment_start, segment_end ) ); }
TEST test_create_allocate_get_release_and_destroy() { // Allocate segment list segment_list_t *segment_list = create_segment_list(".", "test_segment_list.str", SIZE, DELETE_IF_EXISTS); ASSERT(segment_list != NULL); // Make sure the list is empty ASSERT(segment_list->is_empty(segment_list)); // The start segment is always zero // TODO: Should be able to get the first free segment //uint32_t segment_number = segment_list->get_next_free_segment(segment_list); //ASSERT(segment_number > 0); uint32_t segment_number = 0; // Allocate the first segment ASSERT(segment_list->allocate_segment(segment_list, segment_number) >= 0); // Get the segment we just allocated segment_t *segment = segment_list->get_segment_for_writing(segment_list, segment_number); ASSERT(segment != NULL); ASSERT_EQ(check_segment(segment, 1), 0); // Release the segment we just allocated ASSERT(segment_list->release_segment_for_writing(segment_list, segment_number) >= 0); // Destroy segment list ASSERT_EQ(segment_list->destroy(segment_list), 0); PASS(); }
static inline analyse_result apply(Turn const& turn, Piece const& piece) { typedef typename Turn::robust_point_type point_type; analyse_result code = check_helper_segments(turn, piece); if (code != analyse_continue) { return code; } geometry::equal_to<point_type> comparator; if (piece.offsetted_count > 8) { // If the offset contains some points and is monotonic, we try // to avoid walking all points linearly. // We try it only once. if (piece.is_monotonic_increasing[0]) { code = check_monotonic(turn, piece, geometry::less<point_type, 0>()); if (code != analyse_continue) return code; } else if (piece.is_monotonic_increasing[1]) { code = check_monotonic(turn, piece, geometry::less<point_type, 1>()); if (code != analyse_continue) return code; } else if (piece.is_monotonic_decreasing[0]) { code = check_monotonic(turn, piece, geometry::greater<point_type, 0>()); if (code != analyse_continue) return code; } else if (piece.is_monotonic_decreasing[1]) { code = check_monotonic(turn, piece, geometry::greater<point_type, 1>()); if (code != analyse_continue) return code; } } // It is small or not monotonic, walk linearly through offset // TODO: this will be combined with winding strategy for (int i = 1; i < piece.offsetted_count; i++) { point_type const& previous = piece.robust_ring[i - 1]; point_type const& current = piece.robust_ring[i]; // The robust ring can contain duplicates // (on which any side or side-value would return 0) if (! comparator(previous, current)) { code = check_segment(previous, current, turn, false); if (code != analyse_continue) { return code; } } } return analyse_unknown; }
void wtseek (void) { char *name; int fd; s64 i; name = RndName(); fd = creat(name, 0666); for (i = 0; Segment[i].offset >= 0; i++) { if (Segment[i].sparse && !Local_option.test_sparse) continue; write_segment(fd, Segment[i]); } close(fd); fd = open(name, O_RDONLY, 0); for (i = 0; Segment[i].offset >= 0; i++) { if (Segment[i].sparse && !Local_option.test_sparse) continue; check_segment(fd, Segment[i]); } for (i = 0; Hole[i].offset >= 0; i++) { if (Hole[i].sparse && !Local_option.test_sparse) continue; check_hole(fd, Hole[i]); } close(fd); free(name); }
static inline analyse_result apply(Turn const& turn, Piece const& piece) { typedef typename Piece::section_type section_type; typedef typename Turn::robust_point_type point_type; typedef typename geometry::coordinate_type<point_type>::type coordinate_type; coordinate_type const point_y = geometry::get<1>(turn.robust_point); typedef strategy::within::winding<point_type> strategy_type; typename strategy_type::state_type state; strategy_type strategy; boost::ignore_unused(strategy); for (std::size_t s = 0; s < piece.sections.size(); s++) { section_type const& section = piece.sections[s]; // If point within vertical range of monotonic section: if (! section.duplicate && section.begin_index < section.end_index && point_y >= geometry::get<min_corner, 1>(section.bounding_box) - 1 && point_y <= geometry::get<max_corner, 1>(section.bounding_box) + 1) { for (int i = section.begin_index + 1; i <= section.end_index; i++) { point_type const& previous = piece.robust_ring[i - 1]; point_type const& current = piece.robust_ring[i]; analyse_result code = check_segment(previous, current, turn, false); if (code != analyse_continue) { return code; } // Get the state (to determine it is within), we don't have // to cover the on-segment case (covered above) strategy.apply(turn.robust_point, previous, current, state); } } } int const code = strategy.result(state); if (code == 1) { return analyse_within; } else if (code == -1) { return analyse_disjoint; } // Should normally not occur - on-segment is covered return analyse_unknown; }
double distance_between_point_and_segment(const Point &point, const Point &segment_start, const Point &segment_end) { check_segment( segment_start, segment_end ); Point nearest; double dst = distance_between_point_and_line( point, segment_start, segment_end - segment_start, nearest ); if( ! is_point_between( nearest, segment_start, segment_end ) ) { dst = std::min( distance( point, segment_start ), distance( point, segment_end ) ); } return dst; }
bool sphere_and_plane_collision(const Point &segment_start, const Point &segment_end, double sphere_radius, const Point &plane_point, const Vector &plane_normal, /*out*/ Point &collision_point) { check_segment( segment_start, segment_end ); check_nonzero_vector( plane_normal, InvalidNormalError() ); const Vector line_vector = segment_end - segment_start; const Vector shift = sign( line_vector*plane_normal )*sphere_radius*plane_normal; // shift trajectory up or down depending on whether collision is lower or upper Point point; const bool result = segment_and_plane_collision( segment_start + shift, segment_end + shift, plane_point, plane_normal, point ); if( result ) { collision_point = point; } return result; }
bool segment_and_plane_collision(const Point &segment_start, const Point &segment_end, const Point &plane_point, const Vector &plane_normal, /*out*/ Point &collision_point) { check_segment( segment_start, segment_end ); check_nonzero_vector( plane_normal, InvalidNormalError() ); Point point; bool result = line_and_plane_collision( segment_start, segment_end - segment_start, plane_point, plane_normal, point ); if( result ) { result = is_point_between( point, segment_start, segment_end ); if( result ) { collision_point = point; } } return result; }
static inline analyse_result check_monotonic(Turn const& turn, Piece const& piece, Compare const& compare) { typedef typename Piece::piece_robust_ring_type ring_type; typedef typename ring_type::const_iterator it_type; it_type end = piece.robust_ring.begin() + piece.offsetted_count; it_type it = std::lower_bound(piece.robust_ring.begin(), end, turn.robust_point, compare); if (it != end && it != piece.robust_ring.begin()) { // iterator points to point larger than point // w.r.t. specified direction, and prev points to a point smaller // We now know if it is inside/outside it_type prev = it - 1; return check_segment(*prev, *it, turn, true); } return analyse_continue; }
// ----------------------------------------------------------------------------- // Draw all segments, ignoring connectivity. // A segment is drawn if its segnum != -1. void draw_mine_all(segment *sp, int automap_flag) { int s; int i; // clear visited list for (i=0; i<=Highest_segment_index; i++) Been_visited[i] = 0; edge_list_size = min(Num_vertices*4,MAX_EDGES); //make maybe smaller than max // clear edge list for (i=0; i<edge_list_size; i++) { edge_list[i].type = ET_EMPTY; edge_list[i].face_count = 0; edge_list[i].backface_count = 0; } n_used = 0; for (s=0; s<=Highest_segment_index; s++) if (sp[s].segnum != -1) { for (i=0; i<MAX_SIDES_PER_SEGMENT; i++) if (sp[s].sides[i].wall_num != -1) draw_special_wall(&sp[s], i); if (Search_mode) check_segment(&sp[s]); else { add_edges(&sp[s]); draw_seg_objects(&sp[s]); } } draw_mine_edges(automap_flag); }
bool sphere_and_triangle_collision(const Point &segment_start, const Point &segment_end, double sphere_radius, const Triangle &triangle, /*out*/ Point &collision_point) { check_segment( segment_start, segment_end ); const Vector L_sphere = segment_end - segment_start; // 1) is it touching a plane of triangle? Point result_point; bool result = sphere_and_plane_collision( segment_start, segment_end, sphere_radius, triangle[0], triangle.normal(), result_point ); if( result ) { // 1.1) is touching point really inside triangle if( is_point_inside_triangle( result_point, triangle ) ) { collision_point = result_point; return true; } } // 2) if not, is it touching any side of triangle? bool any_result = false; // will be true, if there is a collision with at least one side Point best_result_point; // best point is the point, nearest to the start of sphere's way for( unsigned i = 0; i < 3; ++i ) { result = sphere_and_segment_collision( segment_start, segment_end, sphere_radius, triangle[i], triangle[ (i+1)%3 ], result_point ); if( result && _is_vector_outside( L_sphere, triangle, i ) ) { // if there is a collision, and sphere is moving inside, not outside if( !any_result || distance( best_result_point, segment_start ) > distance( result_point, segment_start ) ) { // if no best result, or if the best result is worst than current best_result_point = result_point; } any_result = true; } } if( any_result ) { collision_point = best_result_point; return true; } // 3) if not, is it touching any vertex of triangle? any_result = false; for( unsigned i = 0; i < 3; ++i ) { result = sphere_and_point_collision( segment_start, segment_end, sphere_radius, triangle[i] ); if( result && _is_vector_outside( L_sphere, triangle, i ) && _is_vector_outside( L_sphere, triangle, (i+2)%3 ) ) { if( !any_result || distance( best_result_point, segment_start ) > distance( triangle[i], segment_start ) ) { // if no best result, or if the best result is worst than current best_result_point = triangle[i]; } any_result = true; } } if( any_result ) { collision_point = best_result_point; return true; } return false; }
bool sphere_and_segment_collision(const Point &sphere_segment_start, const Point &sphere_segment_end, double sphere_radius, const Point &segment_start, const Point &segment_end, /*out*/ Point &collision_point) { check_segment( segment_start, segment_end ); check_segment( sphere_segment_start, sphere_segment_end ); const Vector L_sphere = (sphere_segment_end - sphere_segment_start).normalized(); const Vector L_segment = (segment_end - segment_start).normalized(); Point nearest_on_sphere_way, nearest_on_segment; nearest_points_on_lines( sphere_segment_start, L_sphere, segment_start, L_segment, nearest_on_sphere_way, nearest_on_segment); const double dist = distance( nearest_on_sphere_way, nearest_on_segment ); if( L_sphere.is_collinear_to( L_segment ) ) { // when the sphere is flying in parallel to the line, it's assumed to be no collision return false; } if( greater_or_equal( sphere_radius, dist ) ) { // if distance between lines is less than radius const double perpendicular_length = sqrt( sphere_radius*sphere_radius - dist*dist ); Point result = perpendicular_base( L_sphere, L_segment, nearest_on_segment, perpendicular_length ); // now check that this collision point is inside the segment if( !is_point_between( result, segment_start, segment_end ) ) { return false; } Vector normal; // normal, aimed from L_segment to L_sphere if( L_sphere.is_orthogonal_to(L_segment) ) { normal = - L_sphere.normalized(); } else { const Vector L_segment_other = (result - nearest_on_segment).normalized(); assert( L_segment_other == L_segment || L_segment_other == -L_segment ); // calculating normal, aimed from L_segment to L_sphere as double cross-product. L_segment_other is used instead of L_segment in order to avoid sign mess normal = cross_product( cross_product( L_sphere, L_segment_other ), L_segment_other ).normalized(); } assert( !normal.is_zero() ); Point sphere_center = result + perpendicular_length*normal + (nearest_on_sphere_way - nearest_on_segment); // sphere center is here at the moment of collision // now check that sphere center at the moment of collision is inside the segment if( !is_point_between( sphere_center, sphere_segment_start, sphere_segment_end ) ) { return false; } // all checks passed => there is a collision collision_point = result; return true; } else { // otherwise, sphere flies too far, no collision return false; } }