From 5ab7dba3fad68fdedb3aa513e86ca9fa35de7c8b Mon Sep 17 00:00:00 2001 From: Avi Kivity <avi.kivity@gmail.com> Date: Wed, 9 Jan 2013 13:37:47 +0200 Subject: [PATCH] mmu: add reserve() Reserves a vma range for later use. Can be useful to implement mmap() hints with a two-step algorithm - reserve a range, then overwrite it with the real mmap. --- mmu.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++-- mmu.hh | 1 + 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/mmu.cc b/mmu.cc index 34ae0abc0..f9fee0587 100644 --- a/mmu.cc +++ b/mmu.cc @@ -21,13 +21,25 @@ namespace mmu { } }; - boost::intrusive::set<vma, + typedef boost::intrusive::set<vma, bi::compare<vma_compare>, bi::member_hook<vma, bi::set_member_hook<>, &vma::_vma_list_hook>, bi::optimize_size<true> - > vma_list; + > vma_list_base; + + struct vma_list_type : vma_list_base { + vma_list_type() { + // insert markers for the edges of allocatable area + // simplifies searches + insert(*new vma(0, 0)); + uintptr_t e = 0x800000000000; + insert(*new vma(e, e)); + } + }; + + vma_list_type vma_list; typedef uint64_t pt_element; const unsigned nlevels = 4; @@ -111,6 +123,37 @@ namespace mmu { } } + uintptr_t find_hole(uintptr_t start, uintptr_t size) + { + // FIXME: use lower_bound or something + auto p = vma_list.begin(); + auto n = std::next(p); + while (n != vma_list.end()) { + if (start >= p->end() && start + size <= n->start()) { + return start; + } + if (p->end() >= start && n->start() - p->end() >= size) { + return p->end(); + } + p = n; + ++n; + } + abort(); + } + + vma* reserve(void* hint, size_t size) + { + // look for a hole around 'hint' + auto start = reinterpret_cast<uintptr_t>(hint); + if (!start) { + start = 0x200000000000ul; + } + start = find_hole(start, size); + auto v = new vma(start, start + size); + vma_list.insert(*v); + return v; + } + vma* map_anon_dontzero(uintptr_t start, uintptr_t end, unsigned perm) { vma* ret = new vma(start, end); diff --git a/mmu.hh b/mmu.hh index 718a2c895..10f90b053 100644 --- a/mmu.hh +++ b/mmu.hh @@ -32,6 +32,7 @@ namespace mmu { boost::intrusive::set_member_hook<> _vma_list_hook; }; + vma* reserve(void* hint, size_t size); vma* map_file(void* addr, size_t size, unsigned perm, file& file, f_offset offset); vma* map_anon(void* addr, size_t size, unsigned perm); -- GitLab