vm: break: allow brk() on any region
use the user-supplied point to lookup which region to perform brk() on, and if it's a reasonable one, do it, no matter what vm's notion of the heap region is.
This commit is contained in:
parent
1c7885f932
commit
660e15b2d1
3 changed files with 43 additions and 14 deletions
|
@ -167,19 +167,11 @@ int real_brk(vmp, v)
|
|||
struct vmproc *vmp;
|
||||
vir_bytes v;
|
||||
{
|
||||
vir_bytes new_sp;
|
||||
vir_clicks new_clicks;
|
||||
int r;
|
||||
if(!(vmp->vm_flags & VMF_HASPT))
|
||||
return OK;
|
||||
|
||||
if(map_region_extend_upto_v(vmp, v) == OK)
|
||||
return OK;
|
||||
|
||||
new_clicks = (vir_clicks) (CLICK_CEIL(v) >> CLICK_SHIFT);
|
||||
if (new_clicks < vmp->vm_arch.vm_seg[D].mem_vir) {
|
||||
printf("VM: real_brk failed because new_clicks too high: %d\n",
|
||||
new_clicks);
|
||||
return(ENOMEM);
|
||||
}
|
||||
new_clicks -= vmp->vm_arch.vm_seg[D].mem_vir;
|
||||
if ((r=get_stack_ptr(vmp->vm_endpoint, &new_sp)) != OK)
|
||||
panic("couldn't get stack pointer: %d", r);
|
||||
r = adjust(vmp, new_clicks, new_sp);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -144,6 +144,7 @@ struct vir_region * map_page_region(struct vmproc *vmp, vir_bytes min,
|
|||
struct vir_region * map_proc_kernel(struct vmproc *dst);
|
||||
int map_region_extend(struct vmproc *vmp, struct vir_region *vr,
|
||||
vir_bytes delta);
|
||||
int map_region_extend_upto_v(struct vmproc *vmp, vir_bytes vir);
|
||||
int map_region_shrink(struct vir_region *vr, vir_bytes delta);
|
||||
int map_unmap_region(struct vmproc *vmp, struct vir_region *vr,
|
||||
vir_bytes len);
|
||||
|
|
|
@ -1665,6 +1665,42 @@ struct vir_region *map_proc_kernel(struct vmproc *vmp)
|
|||
return vr; /* Return pointer not useful, just non-NULL. */
|
||||
}
|
||||
|
||||
int map_region_extend_upto_v(struct vmproc *vmp, vir_bytes v)
|
||||
{
|
||||
vir_bytes offset, o, end;
|
||||
struct vir_region *vr, *nextvr;
|
||||
|
||||
offset = arch_vir2map(vmp, v);
|
||||
|
||||
if((o=(offset % VM_PAGE_SIZE))) {
|
||||
offset+= VM_PAGE_SIZE - o;
|
||||
}
|
||||
|
||||
if(!(vr = region_search(&vmp->vm_regions_avl, offset, AVL_LESS_EQUAL))) {
|
||||
printf("VM: nothing to extend\n");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if(!(vr->flags & VR_ANON)) {
|
||||
printf("VM: memory range to extend not anonymous\n");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
assert(vr->vaddr <= offset);
|
||||
if((nextvr = getnextvr(vr))) {
|
||||
assert(offset < nextvr->vaddr);
|
||||
}
|
||||
|
||||
end = vr->vaddr + vr->length;
|
||||
|
||||
if(offset < end)
|
||||
return map_region_shrink(vr, end - offset);
|
||||
|
||||
return map_region_extend(vmp, vr, offset - end);
|
||||
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/*========================================================================*
|
||||
* map_region_extend *
|
||||
*========================================================================*/
|
||||
|
|
Loading…
Reference in a new issue