Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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();
}
Ejemplo n.º 3
0
// ----------------------------------------------------------------------------------------------------------------
// 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;
}
Ejemplo n.º 5
0
    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 ) );
    }
Ejemplo n.º 6
0
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();
}
Ejemplo n.º 7
0
    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;
    }
Ejemplo n.º 8
0
Archivo: rw.c Proyecto: taysom/tau
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);
}
Ejemplo n.º 9
0
    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;
    }
Ejemplo n.º 10
0
    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;
    }
Ejemplo n.º 11
0
    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;
    }
Ejemplo n.º 12
0
    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;
    }
Ejemplo n.º 13
0
    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;
    }
Ejemplo n.º 14
0
// -----------------------------------------------------------------------------
//	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);

}
Ejemplo n.º 15
0
    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;
    }
Ejemplo n.º 16
0
    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;
        }
    }