From 7fc6c40c5428683f9dbe8a03fc786a82eb388883 Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sun, 11 Apr 2021 04:04:09 -0500 Subject: [PATCH] Wrote memory map in C, removed C++ code --- include/memorymap.h | 20 +++++ src/memorymap.c | 131 ++++++++++++++++++++++++++++++++ src/memorymap.cpp | 172 ------------------------------------------- src/memorymap.hpp | 152 -------------------------------------- src/memoryregion.cpp | 128 -------------------------------- src/memoryregion.hpp | 87 ---------------------- 6 files changed, 151 insertions(+), 539 deletions(-) create mode 100644 include/memorymap.h create mode 100644 src/memorymap.c delete mode 100644 src/memorymap.cpp delete mode 100644 src/memorymap.hpp delete mode 100644 src/memoryregion.cpp delete mode 100644 src/memoryregion.hpp diff --git a/include/memorymap.h b/include/memorymap.h new file mode 100644 index 0000000..e33eb40 --- /dev/null +++ b/include/memorymap.h @@ -0,0 +1,20 @@ +#pragma once + +#include "types/physaddr.h" +#include + +struct memory_region_t +{ + physaddr_t location; + size_t size; + unsigned int type; +}; + +struct memory_map_t +{ + struct memory_region_t *array; + size_t size; + size_t capacity; +}; + +void insert_region(struct memory_map_t *map, physaddr_t location, size_t size, unsigned int type); \ No newline at end of file diff --git a/src/memorymap.c b/src/memorymap.c new file mode 100644 index 0000000..5bc6864 --- /dev/null +++ b/src/memorymap.c @@ -0,0 +1,131 @@ +#include "memorymap.h" +#include + +int compare_regions(struct memory_region_t *lhs, struct memory_region_t *rhs) +{ + if(lhs->location == rhs->location) + { + return lhs->size - rhs->size; + } + else + { + return lhs->location - rhs->location; + } +} + +bool region_overlaps(struct memory_region_t *lhs, struct memory_region_t *rhs) +{ + if(rhs->location < lhs->location) + { + return rhs->location + rhs->size > lhs->location; + } + return rhs->location < lhs->location + lhs->size; +} + +bool region_contains(struct memory_region_t *lhs, struct memory_region_t *rhs) +{ + return (rhs->location >= lhs->location) && + (rhs->location + rhs->size <= lhs->location + lhs->size); +} + +void insert_map_entry(struct memory_map_t *map, physaddr_t location, size_t size, unsigned int type) +{ + struct memory_region_t new_region = {.location = location, .size = size, .type = type}; + unsigned int i = 0; + while(i < map->size) + { + if(compare_regions(&new_region, &map->array[i]) < 0) + { + struct memory_region_t buffer = new_region; + new_region = map->array[i]; + map->array[i] = buffer; + } + i++; + } + map->array[i] = new_region; + map->size++; +} + +void remove_map_entry(struct memory_map_t *map, int index) +{ + if(index >= 0 && index < map->size) + { + for(int i = index; i < map->size - 1; i++) + { + map->array[i] = map->array[i + 1]; + } + map->size--; + } +} + +int trim_map(struct memory_map_t *map, int index) +{ + if(index + 1 >= map->size) + { + return -1; + } + struct memory_region_t left = map->array[index]; + struct memory_region_t right = map->array[index + 1]; + if(region_overlaps(&left, &right)) + { + if(left.type == right.type) + { + left.size = (right.location + right.size > left.location + left.size ? right.location + right.size : left.location + left.size) - left.location; + remove_map_entry(map, index + 1); + return index; + } + else if(left.type < right.type) + { + if(region_contains(&right, &left)) + { + remove_map_entry(map, index); + return index; + } + else if(left.location + left.size <= right.location + right.size) + { + left.size = (right.location > left.location) ? right.location - left.location : 0; + return index + 1; + } + else + { + struct memory_region_t new_right = {.location = right.location + right.size, .size = (left.location + left.size) - (right.location + right.size), .type = left.type}; + left.size = (right.location > left.location) ? right.location - left.location : 0; + if(left.size == 0) + remove_map_entry(map, index); + insert_map_entry(map, new_right.location, new_right.size, new_right.type); + return index + 2; + } + } + else + { + if(region_contains(&left, &right)) + { + remove_map_entry(map, index + 1); + return index; + } + else + { + right.size = (right.location + right.size) - (left.location + left.size); + right.location = left.location + left.size; + return index + 1; + } + } + } + else if((left.location + left.size == right.location) && left.type == right.type) + { + left.size = right.location + right.size - left.location; + remove_map_entry(map, index + 1); + return index; + } + return index + 1; +} + +void insert_region(struct memory_map_t *map, physaddr_t location, size_t size, unsigned int type) +{ + insert_map_entry(map, location, size, type); + unsigned int i = 0; + while(i >= 0) + { + i = trim_map(map, i); + } +} \ No newline at end of file diff --git a/src/memorymap.cpp b/src/memorymap.cpp deleted file mode 100644 index e1b21e9..0000000 --- a/src/memorymap.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include "memorymap.hpp" - -using namespace kernelns; - -MemoryMap::MemoryMap() -{ - this->m_entries = 0; -} - -MemoryMap::MemoryMap(MemoryMap& copy) -{ - for(int i = 0; i < copy.m_entries; i++) - m_map[i] = copy[i]; - this->m_entries = copy.m_entries; -} - -const MemoryRegion& MemoryMap::operator[](size_t index) const -{ - return m_map[index]; -} - -size_t MemoryMap::size() const -{ - return m_entries; -} - -size_t MemoryMap::totalMemory() const -{ - size_t sum = 0; - for(int i = 0; i < m_entries; i++) - { - sum += m_map[i].getSize(); - } - return sum; -} - -size_t MemoryMap::totalMemory(unsigned int type) const -{ - size_t sum = 0; - for(int i = 0; i < m_entries; i++) - { - if(m_map[i].getType() == type) - sum += m_map[i].getSize(); - } - return sum; -} - -bool MemoryMap::overlaps(const MemoryRegion& region) const -{ - for(int i = 0; i < m_entries; i++) - { - if(m_map[i].overlaps(region)) - return true; - } - return false; -} - -bool MemoryMap::contains(const MemoryRegion& region) const -{ - for(int i = 0; i < m_entries; i++) - { - if(m_map[i].contains(region) && m_map[i].getType() == region.getType()) - return true; - } - return false; -} - -void MemoryMap::insertEntry(const MemoryRegion& region) -{ - simpleInsert(region); - unsigned int i = 0; - while(i != invalidIndex) - i = trim(i); -} - -void MemoryMap::insertEntry(physaddr_t location, size_t size, unsigned int type) -{ - insertEntry(MemoryRegion(location, size, type)); -} - -void MemoryMap::remove(unsigned int index) -{ - for(unsigned int i = index; i < (m_entries - 1); i++) - { - m_map[i] = m_map[i+1]; - } - m_entries--; -} - -void MemoryMap::simpleInsert(const MemoryRegion& region) -{ - MemoryRegion newRegion(region); - unsigned int i = 0; - while(i < m_entries) - { - if(newRegion < m_map[i]) - { - MemoryRegion buffer = newRegion; - newRegion = m_map[i]; - m_map[i] = buffer; - } - i++; - } - m_map[i] = newRegion; - m_entries++; -} - -void MemoryMap::simpleInsert(physaddr_t location, size_t size, unsigned int type) -{ - simpleInsert(MemoryRegion(location, size, type)); -} - -unsigned int MemoryMap::trim(unsigned int index) -{ - if(index + 1 >= m_entries) - return invalidIndex; - MemoryRegion& left = m_map[index]; - MemoryRegion& right = m_map[index+1]; - if(left.overlaps(right)) - { - if(left.getType() == right.getType()) - { - left = MemoryRegion(left.getLocation(), - (right.getEnd() > left.getEnd() ? right.getEnd() : left.getEnd()) - left.getLocation(), - left.getType()); - remove(index + 1); - return index; - } - else if(left.getType() < right.getType()) - { - if(right.contains(left)) - { - remove(index); - return index; - } - else if(left.getEnd() <= right.getEnd()) - { - left.truncateRight(right.getLocation()); - return index + 1; - } - else - { - MemoryRegion newRight(right.getEnd(), left.getEnd() - right.getEnd(), left.getType()); - left.truncateRight(right.getLocation()); - if(left.getSize() == 0) - remove(index); - simpleInsert(newRight); - return index + 2; - } - } - else - { - if(left.contains(right)) - { - remove(index + 1); - return index; - } - else - { - right.truncateLeft(left.getEnd()); - return index + 1; - } - } - } - else if(left.bordersLeft(right) && left.getType() == right.getType()) - { - left = MemoryRegion(left.getLocation(), right.getEnd() - left.getLocation(), left.getType()); - remove(index + 1); - return index; - } - return index + 1; -} \ No newline at end of file diff --git a/src/memorymap.hpp b/src/memorymap.hpp deleted file mode 100644 index 6c428af..0000000 --- a/src/memorymap.hpp +++ /dev/null @@ -1,152 +0,0 @@ -#ifndef MEMORYMAP_H -#define MEMORYMAP_H - -#include "systypes.hpp" -#include "memoryregion.hpp" - -namespace kernelns -{ - -class MemoryMap -{ -public: - - MemoryMap(); - - MemoryMap(MemoryMap& copy); - - const MemoryRegion& operator[](size_t index) const; - - /** - * @return The number of memory regions described by this object - */ - size_t size() const; - - /** - * @brief Get the total amount of memory described by this memory map. - * Since no two regions may overlap, this is equivalent to the sum of the - * size of each memory region stored in this object. - * - * @return The total amount of memory described by this memory map. - */ - size_t totalMemory() const; - - /** - * @brief Get the total amount of memory of a specified type described by - * this memory map. Since no two regions overlap, this is equivalent to the - * sum of the size of each memory region stored in this object whose type - * is equal to `type`. - * - * @param type The type of memory region to count - * @return The total amount of memory of the specified type - */ - size_t totalMemory(unsigned int type) const; - - /** - * @brief Checks if `region` overlaps any memory region contained in this - * memory map. - * - * @param region - * @return true if, for any region `k` in this map, `k.overlaps(region)`. - * @return false if there is no region in this map where `k.overlaps(region)`. - */ - bool overlaps(const MemoryRegion& region) const; - - /** - * @brief Checks if `region` is contained an any memory region in this map - * with the same type as `region`. - * - * @param region - * @return true if, for any region `k` in this map, `k.contains(region) - * && k.getType() == region.getType()`. - * @return false if the condition above is not true - */ - bool contains(const MemoryRegion& region) const; - - /** - * @brief Adds `region` into the memory map. Adjusts the map as necessary - * so that no regions overlap. Regions of higher type take precedence over - * regions with lower types; therefore, the lower typed regions are trimmed - * or deleted where they overlap with higher typed regions. Adjacent or - * overlapping regions with identical types are merged. - * - * @param region The memory region to insert - */ - void insertEntry(const MemoryRegion& region); - - /** - * @brief Overload of `insertEntry()`. @see insertRegion(const MemoryRegion&). - * - * @param location - * @param size - * @param type - */ - void insertEntry(physaddr_t location, size_t size, unsigned int type); - -private: - - /** - * @brief Removes the element at `index` in `m_map`. All objects located - * after that index are moved accordingly. - * - * @param index Locatation of the object to delete - */ - void remove(unsigned int index); - - /** - * @brief Inserts a copy of `region` into `m_map`. The new element is - * inserted such that `m_map` is sorted in ascending order. Overlapping - * elements are not trimmed. - * - * @param region The memory region to insert - */ - void simpleInsert(const MemoryRegion& region); - - /** - * @brief Overload of `simpleInsert(const MemoryRegion& region)`. - * - * @param location - * @param size - * @param type - */ - void simpleInsert(physaddr_t location, size_t size, unsigned int type); - - /** - * @brief If `m_map[index].overlaps(m_map[index+1])`, the two elements are - * modified so that they no longer overlap. The following rules apply: - * - * 1. This memory map will describe the same set of locations before and - * after performing this operation. - * - * 2. Adjacent regions of the same type are merged into a single region. - * - * 3. Where two regions of differing types overlap, the higher type takes - * precedence. The region of the lower type is truncated, split, or deleted - * so as to not overlap the region of the higher type. - * - * 4. This operation is local: only `m_map[index]` and `m_map[index+1]` are - * modified (although if a region must be split, a new region will be - * inserted at the location `index+2`). - * - * This function has no effect if `index+1 >= m_entries`, or if - * `m_map[index]` does not overlap the `m_map[index+1]`. - * - * @param index The location of the region to trim. - * - * @return The index of the rightmost region affected. - */ - unsigned int trim(unsigned int index); - - static const unsigned int maxEntries = 16; - - static const unsigned int invalidIndex = 0xFFFF; - - MemoryRegion m_map[maxEntries]; - - size_t m_entries; - -}; - -} - -#endif \ No newline at end of file diff --git a/src/memoryregion.cpp b/src/memoryregion.cpp deleted file mode 100644 index d0eeb15..0000000 --- a/src/memoryregion.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "memoryregion.hpp" - -MemoryRegion::MemoryRegion() -{ - m_location = 0; - m_size = 0; - m_type = 0; -} - -MemoryRegion::MemoryRegion(const MemoryRegion& copy) -{ - m_location = copy.m_location; - m_size = copy.m_size; - m_type = copy.m_type; -} - -MemoryRegion::MemoryRegion(physaddr_t location, size_t size, unsigned int type) -{ - m_location = location; - m_size = size; - m_type = (size_t) type; -} - -const MemoryRegion& MemoryRegion::operator=(const MemoryRegion& rhs) -{ - m_location = rhs.m_location; - m_size = rhs.m_size; - m_type = rhs.m_type; - return rhs; -} - -bool MemoryRegion::operator==(const MemoryRegion& rhs) const -{ - return (m_location == rhs.m_location) && (m_size == rhs.m_size); -} - -bool MemoryRegion::operator!=(const MemoryRegion& rhs) const -{ - return (m_location != rhs.m_location) || (m_size != rhs.m_size); -} - -bool MemoryRegion::operator<(const MemoryRegion& rhs) const -{ - return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size < rhs.m_size)); -} - -bool MemoryRegion::operator>(const MemoryRegion& rhs) const -{ - return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size > rhs.m_size)); -} - -bool MemoryRegion::operator<=(const MemoryRegion& rhs) const -{ - return (m_location < rhs.m_location) || ((m_location == rhs.m_location) && (m_size <= rhs.m_size)); -} - -bool MemoryRegion::operator>=(const MemoryRegion& rhs) const -{ - return (m_location > rhs.m_location) || ((m_location == rhs.m_location) && (m_size >= rhs.m_size)); -} - -physaddr_t MemoryRegion::getLocation() const -{ - return m_location; -} - -size_t MemoryRegion::getSize() const -{ - return m_size; -} - -unsigned int MemoryRegion::getType() const -{ - return m_type; -} - -physaddr_t MemoryRegion::getEnd() const -{ - return m_location + m_size; -} - -bool MemoryRegion::contains(const MemoryRegion& r) const -{ - return contains(r.m_location, r.m_size); -} - -bool MemoryRegion::contains(physaddr_t location, size_t size) const -{ - return (location >= m_location) && - (location + size <= m_location + m_size); -} - -bool MemoryRegion::overlaps(const MemoryRegion& r) const -{ - if(r.m_location < m_location) - return r.m_location + r.m_size > m_location; - else - return r.m_location < getEnd(); -} - -bool MemoryRegion::bordersLeft(const MemoryRegion& right) const -{ - return getEnd() == right.m_location; -} - -bool MemoryRegion::bordersRight(const MemoryRegion& left) const -{ - return m_location == left.m_location + left.m_size; -} - -bool MemoryRegion::borders(const MemoryRegion& r) const -{ - return bordersLeft(r) || bordersRight(r); -} - -void MemoryRegion::truncateLeft(physaddr_t left) -{ - m_size = getEnd() - left; - m_location = left; -} - -void MemoryRegion::truncateRight(physaddr_t right) -{ - if(right > m_location) - m_size = right - m_location; - else - m_size = 0; -} \ No newline at end of file diff --git a/src/memoryregion.hpp b/src/memoryregion.hpp deleted file mode 100644 index 35e57e8..0000000 --- a/src/memoryregion.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef MEMORYBLOCK_H -#define MEMORYBLOCK_H - -#include "systypes.hpp" - -class MemoryRegion -{ -public: - - MemoryRegion(); - - MemoryRegion(const MemoryRegion& copy); - - MemoryRegion(physaddr_t location, size_t size, unsigned int type); - - const MemoryRegion& operator=(const MemoryRegion& rhs); - - /** - * @brief Tests whether this object describes the same region of memory - * as rhs, irrespective of type. - * - * @param rhs The object to compare to - * @return true if and only if the location and size of the two regions are equal - * @return false if the two regions have differing locations or differing sizes - */ - bool operator==(const MemoryRegion& rhs) const; - - /** - * @brief Tests whether this object describes a different region of memory - * than rhs, irrespective of type. - * - * @param rhs The object to compare to - * @return true if the two regions have differing locations or differing sizes - * @return false if and only if the location and size of the two regions are equal - */ - bool operator!=(const MemoryRegion& rhs) const; - - /** - * @brief - * - * @param rhs - * @return true - * @return false - */ - bool operator<(const MemoryRegion& rhs) const; - - bool operator>(const MemoryRegion& rhs) const; - - bool operator<=(const MemoryRegion& rhs) const; - - bool operator>=(const MemoryRegion& rhs) const; - - physaddr_t getLocation() const; - - size_t getSize() const; - - unsigned int getType() const; - - physaddr_t getEnd() const; - - bool contains(const MemoryRegion& r) const; - - bool contains(physaddr_t location, size_t size) const; - - bool overlaps(const MemoryRegion& r) const; - - bool bordersLeft(const MemoryRegion& right) const; - - bool bordersRight(const MemoryRegion& left) const; - - bool borders(const MemoryRegion& r) const; - - void truncateLeft(physaddr_t left); - - void truncateRight(physaddr_t right); - -private: - - physaddr_t m_location; - - size_t m_size; - - unsigned int m_type; - -}; - -#endif \ No newline at end of file