Wrote memory map in C, removed C++ code

This commit is contained in:
2021-04-11 04:04:09 -05:00
parent 557f3194ed
commit 7fc6c40c54
6 changed files with 151 additions and 539 deletions

131
src/memorymap.c Normal file
View File

@@ -0,0 +1,131 @@
#include "memorymap.h"
#include <stdbool.h>
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);
}
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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