Пример #1
0
Файл: vm.c Проект: AndrewD/prex
static int
do_allocate(vm_map_t map, void **addr, size_t size, int anywhere)
{
	struct region *reg;
	char *start, *end, *phys;

	if (size == 0)
		return EINVAL;

	/*
	 * Allocate region
	 */
	if (anywhere) {
		size = (size_t)PAGE_ALIGN(size);
		if ((reg = region_alloc(&map->head, size)) == NULL)
			return ENOMEM;
	} else {
		start = (char *)PAGE_TRUNC(*addr);
		end = (char *)PAGE_ALIGN(start + size);
		size = (size_t)(end - start);

		reg = region_find(&map->head, start, size);
		if (reg == NULL || !(reg->flags & REG_FREE))
			return EINVAL;

		reg = region_split(&map->head, reg, start, size);
		if (reg == NULL)
			return ENOMEM;
	}
	reg->flags = REG_READ | REG_WRITE;

	/*
	 * Allocate physical pages, and map them into virtual address
	 */
	if ((phys = page_alloc(size)) == 0)
		goto err1;

	if (mmu_map(map->pgd, phys, reg->addr, size, PG_WRITE))
		goto err2;

	reg->phys = phys;

	/* Zero fill */
	memset(phys_to_virt(phys), 0, reg->size);
	*addr = reg->addr;
	return 0;

 err2:
	page_free(phys, size);
 err1:
	region_free(&map->head, reg);
	return ENOMEM;
}
Пример #2
0
void zw::geoData::subdivide( geo_ptr &data, cell_size_t &extant )
{
	auto created = extant;
	
	// Store Links To Future-Nodes
	std::vector<deferral> deferred;
	
	for ( cell_size_t parent = 0; parent < extant; ++parent )
	{
		for ( int spoke = 0; spoke < 6; ++spoke )
		{
			auto child = data[parent].link[spoke];
			
			if ( child >= extant )
				continue; // we already split this pair
				
			// Create new node at the modpoint of pair
			
			for ( int s = 0; s < 6; ++s )
				data[created].link[s] = nolink - 1;
				
			data[created].v = ( data[parent].v + data[child].v ) / 2;
			data[created].v.normalize();
			
			data[created].region = ( created < REGION_LIMIT ) ? created : region_split(
			                           data[parent].region, data[child].region );
			region_score[data[created].region] += 1;
			
			//
			// Here's how the linking works. In the original hexagon, there is
			// a "center" which is the parent node. This center has 6 spokes
			// leading to the vertices of the hexagon. We are creating a new
			// point between the parent and one of the spokes -- the child. The
			// created node needs to be linked to both the parent and child. In
			// the original hexagon, we also need to know the child's sibling
			// nodes on either side from the parent - counter-clockwise and
			// clockwise.
			//
			// During this iteration, the links between these two nodes and both
			// the parent and child should be subdivided just like this spoke,
			// creating four new nodes. Our newly created node needs to link to
			// all four of these. Some of them are likely to have already been
			// created previously in the subdivision process and we can link
			// straight to them. Others will not have been created yet and we'll
			// need to set up deferred links which will be created when the
			// nodes are.
			//
			// link[0] = parent
			// link[1] = new node between parent and counter-clockwise sibling
			// link[2] = new node between counter-clockwise sibling and child
			// link[3] = child
			// link[4] = new node between clockwise sibling and child
			// link[5] = new node between parent and clockwise sibling
			//
			
			// Link To Parent
			
			data[created].link[0] = parent;
			data[parent].link[spoke] = created;
			
			// Link To Counter-Clockwise Siblings
			
			auto neighbor = data[parent].prevNeighbor( spoke );
			
			if ( neighbor >= extant )
			{
				data[created].link[1] = neighbor;
				
				if ( data[neighbor].link[0] == parent )
					neighbor = data[neighbor].link[3];
				else
					neighbor = data[neighbor].link[0];
			}
			else
				deferred.push_back( deferral( parent, neighbor, 1, created ) );
				
			for ( int s = 0; s < 6; ++s )
			{
				if ( data[neighbor].link[s] == child )
				{
					deferred.push_back( deferral( child, neighbor, 2, created ) );
					break;
				}
				else if ( ( data[data[neighbor].link[s]].link[0] == child
				            && data[data[neighbor].link[s]].link[3] == neighbor )
				          || ( data[data[neighbor].link[s]].link[0] == neighbor
				               && data[data[neighbor].link[s]].link[3] == child ) )
				{
					data[created].link[2] = data[neighbor].link[s];
					break;
				}
			}
			
			// Link To Child
			
			data[created].link[3] = child;
			
			for ( int s = 0; s < 6; ++s )
			{
				if ( data[child].link[s] == parent )
				{
					data[child].link[s] = created;
					break;
				}
			}
			
			// Link To Clockwise Siblings
			
			neighbor = data[parent].nextNeighbor( spoke );
			
			if ( neighbor >= extant )
			{
				data[created].link[5] = neighbor;
				
				if ( data[neighbor].link[0] == parent )
					neighbor = data[neighbor].link[3];
				else
					neighbor = data[neighbor].link[0];
			}
			else
				deferred.push_back( deferral( parent, neighbor, 5, created ) );
				
			for ( int s = 0; s < 6; ++s )
			{
				if ( data[neighbor].link[s] == child )
				{
					deferred.push_back( deferral( child, neighbor, 4, created ) );
					break;
				}
				else if ( ( data[data[neighbor].link[s]].link[0] == child
				            && data[data[neighbor].link[s]].link[3] == neighbor )
				          || ( data[data[neighbor].link[s]].link[0] == neighbor
				               && data[data[neighbor].link[s]].link[3] == child ) )
				{
					data[created].link[4] = data[neighbor].link[s];
					break;
				}
			}
			
			// We have finished creating this node.
			
			++created;
		}
	}
	
	for ( auto const &d : deferred )
	{
		for ( int s = 0; s < 6; ++s )
		{
			auto other = data[d.a].link[s];
			
			if ( ( data[other].link[0] == d.a && data[other].link[3] == d.b )
			        || ( data[other].link[3] == d.a && data[other].link[0] == d.b ) )
			{
				data[d.t].link[d.s] = other;
				break;
			}
			
			assert( s != 5 ); // we should never get here
		}
	}
	
	// We're Done
	extant = created;
}