예제 #1
0
int valloc_alloc_at(spdid_t spdid, spdid_t dest, void *addr, unsigned long npages)
{
	int ret = -1, i = 0;
	struct spd_vas_tracker *trac;
	struct spd_vas_occupied *occ;
	unsigned long off, ext_size;

	LOCK();
	trac = cos_vect_lookup(&spd_vect, dest);
	if (!trac) {
		if (__valloc_init(dest) ||
		    !(trac = cos_vect_lookup(&spd_vect, dest))) goto done;
	}

	if (unlikely(npages > MAP_MAX * sizeof(u32_t))) {
		printc("valloc: cannot alloc more than %u bytes in one time!\n", 32 * WORDS_PER_PAGE * PAGE_SIZE);
		goto done;
	}

	while (trac->extents[i].map) {
		if (addr < trac->extents[i].start || addr > trac->extents[i].end) {
			if (++i == MAX_SPD_VAS_LOCATIONS) goto done;
			continue;
		}
		/* the address is in the range of an existing extent */
		occ = trac->extents[i].map;
		off = ((char*)addr - (char*)trac->extents[i].start) / PAGE_SIZE;
		assert(off + npages < MAP_MAX * sizeof(u32_t));
		ret = bitmap_extent_set_at(&occ->pgd_occupied[0], off, npages, MAP_MAX);
		goto done;
	}

	ext_size = round_up_to_pgd_page(npages * PAGE_SIZE);
	trac->extents[i].map = alloc_page();
	occ = trac->extents[i].map;
	assert(occ);
	if (vas_mgr_take(spdid, dest, (vaddr_t)addr, ext_size) == 0) goto free;
	trac->extents[i].start = addr;
	trac->extents[i].end = (void *)((uintptr_t)addr + ext_size);
	bitmap_set_contig(&occ->pgd_occupied[0], 0, ext_size / PAGE_SIZE, 1);
	bitmap_set_contig(&occ->pgd_occupied[0], 0, npages, 0);
	ret = 0;
done:
	UNLOCK();
	return ret;
free:
	free_page(trac->extents[i].map);
	goto done;
}
예제 #2
0
int valloc_free(spdid_t spdid, spdid_t dest, void *addr, unsigned long npages)
{
	int ret = -1;
	struct spd_vas_tracker *trac;
	struct spd_vas_occupied *occ;
	unsigned long off;

	LOCK();
	trac = cos_vect_lookup(&spd_vect, dest);
	if (!trac) goto done;

	int i = 0;
	/* locate the address to be freed in which range (extents) */
	while (addr < trac->extents[i].start || addr > trac->extents[i].end) {
		if (++i == MAX_SPD_VAS_LOCATIONS) goto done;
	}
	occ = trac->extents[i].map;
	assert(occ);
	off = ((char *)addr - (char *)trac->extents[i].start) / PAGE_SIZE;
	assert(off + npages < MAP_MAX * sizeof(u32_t));
	bitmap_set_contig(&occ->pgd_occupied[0], off, npages, 1);
	ret = 0;
done:	
	UNLOCK();
	return ret;
}
예제 #3
0
void *valloc_alloc(spdid_t spdid, spdid_t dest, unsigned long npages)
{
	void *ret = NULL;
	struct spd_vas_tracker *trac;
	struct spd_vas_occupied *occ;
	unsigned long ext_size;
	long off, i = 0;

	LOCK();

	trac = cos_vect_lookup(&spd_vect, dest);
	if (!trac) {
		if (__valloc_init(dest) ||
		    !(trac = cos_vect_lookup(&spd_vect, dest))) goto done;
	}

	if (unlikely(npages > MAP_MAX * sizeof(u32_t))) {
		printc("valloc: cannot alloc more than %u bytes in one time!\n", 32 * WORDS_PER_PAGE * PAGE_SIZE);
		goto done;
	}

	while (trac->extents[i].map) {
		occ = trac->extents[i].map;
		off = bitmap_extent_find_set(&occ->pgd_occupied[0], 0, npages, MAP_MAX);
		if (off < 0) {
			if (++i == MAX_SPD_VAS_LOCATIONS) goto done;
			continue;
		}
		ret = (void *)((char *)trac->extents[i].start + off * PAGE_SIZE);
		goto done;
	}

	ext_size = round_up_to_pgd_page(npages * PAGE_SIZE);
	trac->extents[i].map = alloc_page();
	occ = trac->extents[i].map;
	assert(occ);
	trac->extents[i].start = (void*)vas_mgr_expand(spdid, dest, ext_size);
	trac->extents[i].end = (void *)(trac->extents[i].start + ext_size);
	bitmap_set_contig(&occ->pgd_occupied[0], 0, ext_size / PAGE_SIZE, 1);
	bitmap_set_contig(&occ->pgd_occupied[0], 0, npages, 0);
	ret = trac->extents[i].start;
done:
	UNLOCK();
	return ret;
}
예제 #4
0
static int __valloc_init(spdid_t spdid)
{
	int ret = -1;
	struct spd_vas_tracker *trac;
	struct spd_vas_occupied *occ;
	unsigned long page_off;
	void *hp;

	if (cos_vect_lookup(&spd_vect, spdid)) goto success;
	trac = malloc(sizeof(struct spd_vas_tracker));
	if (!trac) goto done;

	occ = alloc_page();
	if (!occ) goto err_free1;
	
	hp = cinfo_get_heap_pointer(cos_spd_id(), spdid);
	if (!hp) goto err_free2;

        trac->spdid            = spdid;
        trac->map              = occ;
        trac->extents[0].start = (void*)round_to_pgd_page(hp);
        trac->extents[0].end   = (void*)round_up_to_pgd_page(hp);
        trac->extents[0].map   = occ;
        page_off = ((unsigned long)hp - (unsigned long)round_to_pgd_page(hp))/PAGE_SIZE;
        bitmap_set_contig(&occ->pgd_occupied[0], page_off, (PGD_SIZE/PAGE_SIZE)-page_off, 1);
        bitmap_set_contig(&occ->pgd_occupied[0], 0, page_off, 0);

	cos_vect_add_id(&spd_vect, trac, spdid);
	assert(cos_vect_lookup(&spd_vect, spdid));
success:
	ret = 0;
done:
	return ret;
err_free2:
	free_page(occ);
err_free1:
	free(trac);
	goto done;
}
예제 #5
0
파일: valloc.c 프로젝트: wittrock/Composite
static int __valloc_init(spdid_t spdid)
{
	int ret = -1;
	struct spd_vas_tracker *trac;
	struct spd_vas_occupied *occ;
	struct cos_component_information *ci;
	unsigned long page_off;
	void *hp;

	if (cos_vect_lookup(&spd_vect, spdid)) goto success;
	trac = malloc(sizeof(struct spd_vas_tracker));
	if (!trac) goto done;

	occ = alloc_page();
	if (!occ) goto err_free1;
	
	ci = cos_get_vas_page();
	if (cinfo_map(cos_spd_id(), (vaddr_t)ci, spdid)) goto err_free2;
	hp = (void*)ci->cos_heap_ptr;
	//	printc("valloc init heap_ptr: %x\n", (unsigned int) hp);

	trac->spdid            = spdid;
	trac->ci               = ci;
	trac->map              = occ;
	trac->extents[0].start = (void*)round_to_pgd_page(hp);
	trac->extents[0].end   = (void*)round_up_to_pgd_page(hp);
	page_off = ((unsigned long)hp - (unsigned long)round_to_pgd_page(hp))/PAGE_SIZE;
	bitmap_set_contig(&occ->pgd_occupied[0], page_off, (PGD_SIZE/PAGE_SIZE)-page_off, 1);

	cos_vect_add_id(&spd_vect, trac, spdid);
	assert(cos_vect_lookup(&spd_vect, spdid));
success:
	//	printc("valloc init success\n");
	ret = 0;
done:
	return ret;
err_free2:
	cos_release_vas_page(ci);
	free_page(occ);
err_free1:
	free(trac);
	goto done;
}
예제 #6
0
int valloc_free(spdid_t spdid, spdid_t dest, void *addr, unsigned long npages)
{
	int ret = -1;
	struct spd_vas_tracker *trac;
	struct spd_vas_occupied *occ;
	unsigned long off;

	LOCK();
	trac = cos_vect_lookup(&spd_vect, dest);
	if (!trac) goto done;
	occ = trac->map;
	assert(occ);
	off = ((char *)addr - (char *)trac->extents[0].start)/PAGE_SIZE;
	assert(off+npages < MAP_MAX*sizeof(u32_t));
	bitmap_set_contig(&occ->pgd_occupied[0], off, npages, 1);
	ret = 0;
done:	
	UNLOCK();
	return ret;
}