mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[kutil] Add unreserve/uncommit to vm_space
Added the functionality for unreseve and uncommit to vm_space. Also added the documented but not implemented ability to pass a 0 address to get any address region with the given size.
This commit is contained in:
@@ -51,16 +51,11 @@ public:
|
|||||||
void unreserve(uintptr_t start, size_t size);
|
void unreserve(uintptr_t start, size_t size);
|
||||||
|
|
||||||
/// Mark a section of address space as committed.
|
/// Mark a section of address space as committed.
|
||||||
/// \arg start Starting address of reservaion
|
/// \arg start Starting address of reservaion, or 0 for any address
|
||||||
/// \arg size Size of reservation in bytes
|
/// \arg size Size of reservation in bytes
|
||||||
/// \returns The address of the reservation, or 0 on failure
|
/// \returns The address of the reservation, or 0 on failure
|
||||||
uintptr_t commit(uintptr_t start, size_t size);
|
uintptr_t commit(uintptr_t start, size_t size);
|
||||||
|
|
||||||
/// Mark a section of address space as uncommitted, but still reserved.
|
|
||||||
/// \arg start Starting address of reservaion
|
|
||||||
/// \arg size Size of reservation in bytes
|
|
||||||
void uncommit(uintptr_t start, size_t size);
|
|
||||||
|
|
||||||
/// Check the state of the given address.
|
/// Check the state of the given address.
|
||||||
/// \arg addr The address to check
|
/// \arg addr The address to check
|
||||||
/// \returns The state of the memory if known, or 'unknown'
|
/// \returns The state of the memory if known, or 'unknown'
|
||||||
@@ -72,6 +67,7 @@ private:
|
|||||||
|
|
||||||
node_type * split_out(node_type* node, uintptr_t start, size_t size, vm_state state);
|
node_type * split_out(node_type* node, uintptr_t start, size_t size, vm_state state);
|
||||||
node_type * consolidate(node_type* needle);
|
node_type * consolidate(node_type* needle);
|
||||||
|
node_type * find_empty(node_type* node, size_t size, vm_state state);
|
||||||
|
|
||||||
tree_type m_ranges;
|
tree_type m_ranges;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ vm_space::vm_space()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static bool
|
||||||
|
contains(node_type *node, uintptr_t start, size_t size)
|
||||||
|
{
|
||||||
|
return start >= node->address &&
|
||||||
|
size <= node->size;
|
||||||
|
}
|
||||||
|
|
||||||
inline static bool
|
inline static bool
|
||||||
overlaps(node_type *node, uintptr_t start, size_t size)
|
overlaps(node_type *node, uintptr_t start, size_t size)
|
||||||
{
|
{
|
||||||
@@ -52,12 +59,8 @@ node_type *
|
|||||||
vm_space::split_out(node_type *node, uintptr_t start, size_t size, vm_state state)
|
vm_space::split_out(node_type *node, uintptr_t start, size_t size, vm_state state)
|
||||||
{
|
{
|
||||||
// No cross-boundary splits allowed for now
|
// No cross-boundary splits allowed for now
|
||||||
bool contained =
|
const bool contained = contains(node, start, size);
|
||||||
start >= node->address &&
|
kassert(contained, "Tried to split an address range across existing boundaries");
|
||||||
start+size <= node->end();
|
|
||||||
|
|
||||||
kassert(contained,
|
|
||||||
"Tried to split an address range across existing boundaries");
|
|
||||||
if (!contained)
|
if (!contained)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -76,7 +79,6 @@ vm_space::split_out(node_type *node, uintptr_t start, size_t size, vm_state stat
|
|||||||
size_t leading = start - node->address;
|
size_t leading = start - node->address;
|
||||||
|
|
||||||
node_type *next = new node_type;
|
node_type *next = new node_type;
|
||||||
next->state = state;
|
|
||||||
next->address = start;
|
next->address = start;
|
||||||
next->size = node->size - leading;
|
next->size = node->size - leading;
|
||||||
|
|
||||||
@@ -118,6 +120,27 @@ vm_space::split_out(node_type *node, uintptr_t start, size_t size, vm_state stat
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node_type *
|
||||||
|
vm_space::find_empty(node_type *node, size_t size, vm_state state)
|
||||||
|
{
|
||||||
|
if (node->state == vm_state::none && node->size >= size)
|
||||||
|
return split_out(node, node->address, size, state);
|
||||||
|
|
||||||
|
if (node->left()) {
|
||||||
|
node_type *found = find_empty(node->left(), size, state);
|
||||||
|
if (found)
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->right()) {
|
||||||
|
node_type *found = find_empty(node->right(), size, state);
|
||||||
|
if (found)
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
inline void gather(node_type *node, node_vec &vec)
|
inline void gather(node_type *node, node_vec &vec)
|
||||||
{
|
{
|
||||||
if (node) {
|
if (node) {
|
||||||
@@ -160,16 +183,25 @@ vm_space::consolidate(node_type *needle)
|
|||||||
uintptr_t
|
uintptr_t
|
||||||
vm_space::reserve(uintptr_t start, size_t size)
|
vm_space::reserve(uintptr_t start, size_t size)
|
||||||
{
|
{
|
||||||
log::debug(logs::vmem, "Reserving region %016llx-%016llx", start, start+size);
|
|
||||||
|
|
||||||
|
if (start == 0) {
|
||||||
|
log::debug(logs::vmem, "Reserving any region of size %llx", size);
|
||||||
|
node_type *node = find_empty(m_ranges.root(), size, vm_state::reserved);
|
||||||
|
if (!node) {
|
||||||
|
log::debug(logs::vmem, " found no large enough region");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node->address;
|
||||||
|
}
|
||||||
|
|
||||||
|
log::debug(logs::vmem, "Reserving region %016llx-%016llx",
|
||||||
|
start, start+size);
|
||||||
node_type *node = find_overlapping(m_ranges.root(), start, size);
|
node_type *node = find_overlapping(m_ranges.root(), start, size);
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
log::debug(logs::vmem, " found no match");
|
log::debug(logs::vmem, " found no match");
|
||||||
return 0;
|
return 0;
|
||||||
} else if (node->state != vm_state::none) {
|
|
||||||
log::debug(logs::vmem, " found wrong state %016llx-%016llx[%d]",
|
|
||||||
node->address, node->address + node->size, node->state);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node = split_out(node, start, size, vm_state::reserved);
|
node = split_out(node, start, size, vm_state::reserved);
|
||||||
@@ -179,36 +211,44 @@ vm_space::reserve(uintptr_t start, size_t size)
|
|||||||
void
|
void
|
||||||
vm_space::unreserve(uintptr_t start, size_t size)
|
vm_space::unreserve(uintptr_t start, size_t size)
|
||||||
{
|
{
|
||||||
|
log::debug(logs::vmem, "Unreserving region %016llx-%016llx", start, start+size);
|
||||||
|
node_type *node = find_overlapping(m_ranges.root(), start, size);
|
||||||
|
|
||||||
|
if (!node || !contains(node, start, size)) {
|
||||||
|
log::debug(logs::vmem, " found no match");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
split_out(node, start, size, vm_state::none);
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t
|
uintptr_t
|
||||||
vm_space::commit(uintptr_t start, size_t size)
|
vm_space::commit(uintptr_t start, size_t size)
|
||||||
{
|
{
|
||||||
log::debug(logs::vmem, "Committing region %016llx-%016llx", start, start+size);
|
if (start == 0) {
|
||||||
|
log::debug(logs::vmem, "Committing any region of size %llx", size);
|
||||||
|
node_type *node = find_empty(m_ranges.root(), size, vm_state::reserved);
|
||||||
|
if (!node) {
|
||||||
|
log::debug(logs::vmem, " found no large enough region");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node->address;
|
||||||
|
}
|
||||||
|
|
||||||
|
log::debug(logs::vmem, "Committing region %016llx-%016llx",
|
||||||
|
start, start+size);
|
||||||
|
|
||||||
node_type *node = find_overlapping(m_ranges.root(), start, size);
|
node_type *node = find_overlapping(m_ranges.root(), start, size);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
log::debug(logs::vmem, " found no match");
|
log::debug(logs::vmem, " found no match");
|
||||||
return 0;
|
return 0;
|
||||||
} else if (node->state == vm_state::unknown || node->state == vm_state::mapped) {
|
|
||||||
log::debug(logs::vmem, " found wrong state %016llx-%016llx[%d]",
|
|
||||||
node->address, node->address + node->size, node->state);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->address <= start && node->size >= size && node->state == vm_state::committed)
|
|
||||||
return start;
|
|
||||||
|
|
||||||
node = split_out(node, start, size, vm_state::committed);
|
node = split_out(node, start, size, vm_state::committed);
|
||||||
return node ? start : 0;
|
return node ? start : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
vm_space::uncommit(uintptr_t start, size_t size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vm_state
|
vm_state
|
||||||
vm_space::get(uintptr_t addr)
|
vm_space::get(uintptr_t addr)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user