mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-18 01:01:57 -04:00
Cleanup and doc
This commit is contained in:
parent
7343b48e8d
commit
0d567e5332
@ -1,6 +1,5 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013-2016.
|
||||
// Distributed under the terms of the MIT License.
|
||||
// Copyright Baptiste Wicht 2013-2016. // Distributed under the terms of the MIT License.
|
||||
// (See accompanying file LICENSE or copy at
|
||||
// http://www.opensource.org/licenses/MIT)
|
||||
//=======================================================================
|
||||
@ -10,13 +9,15 @@
|
||||
|
||||
#include "assert.hpp"
|
||||
|
||||
/*!
|
||||
* \brief A static bitmap.
|
||||
*
|
||||
* This bitmap cannot be extended. The data must be provided via one of its init functions.
|
||||
*/
|
||||
struct static_bitmap {
|
||||
typedef uint64_t data_type;
|
||||
using data_type = uint64_t; ///< The word type
|
||||
|
||||
static constexpr const size_t bits_per_word = sizeof(data_type) * 8;
|
||||
|
||||
size_t words;
|
||||
data_type* data;
|
||||
static constexpr const size_t bits_per_word = sizeof(data_type) * 8; ///< The number of bits stored in each word
|
||||
|
||||
template<typename Array>
|
||||
void init(Array& array){
|
||||
@ -29,33 +30,51 @@ struct static_bitmap {
|
||||
data = d;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the word in which the bit is
|
||||
*/
|
||||
static constexpr size_t word_offset(size_t bit){
|
||||
return bit / bits_per_word;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the offset of the bit inside its word
|
||||
*/
|
||||
static constexpr size_t bit_offset(size_t bit){
|
||||
return bit % bits_per_word;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Constructs a bit mask for the given bit
|
||||
*/
|
||||
static constexpr data_type bit_mask(size_t bit){
|
||||
return static_cast<data_type>(1) << bit_offset(bit);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clear the complete bit map (set everything to zero)
|
||||
*/
|
||||
void clear_all(){
|
||||
for(size_t i = 0; i < words; ++i){
|
||||
data[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Set the complete bit map (set everything to one)
|
||||
*/
|
||||
void set_all(){
|
||||
for(size_t i = 0; i < words; ++i){
|
||||
data[i] = ~static_cast<data_type>(0);
|
||||
}
|
||||
}
|
||||
|
||||
size_t free_bit() const {
|
||||
/*!
|
||||
* \brief Returns the first set bit in the bit map
|
||||
*/
|
||||
size_t set_bit() const {
|
||||
for(size_t w = 0; w < words; ++w){
|
||||
if(data[w] > 0){
|
||||
if(data[w]){
|
||||
for(size_t b = 0; b < bits_per_word; ++b){
|
||||
if(data[w] & bit_mask(b)){
|
||||
return w * bits_per_word + b;
|
||||
@ -67,7 +86,10 @@ struct static_bitmap {
|
||||
thor_unreachable("static_bitmap has no free bit");
|
||||
}
|
||||
|
||||
size_t free_word() const {
|
||||
/*!
|
||||
* \brief Returns the first set word in the bit map
|
||||
*/
|
||||
size_t set_word() const {
|
||||
for(size_t w = 0; w < words; ++w){
|
||||
if(data[w] == ~static_cast<data_type>(0)){
|
||||
return w * bits_per_word;
|
||||
@ -77,17 +99,30 @@ struct static_bitmap {
|
||||
thor_unreachable("static_bitmap has no free word");
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Indicates if the given bit is set
|
||||
*/
|
||||
bool is_set(size_t bit) const {
|
||||
return data[word_offset(bit)] & bit_mask(bit);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the given bit to 1
|
||||
*/
|
||||
void set(size_t bit){
|
||||
data[word_offset(bit)] |= bit_mask(bit);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief clear the given bit to 1
|
||||
*/
|
||||
void unset(size_t bit){
|
||||
data[word_offset(bit)] &= ~bit_mask(bit);
|
||||
}
|
||||
|
||||
private:
|
||||
size_t words; ///< Number of words used in the bitmap
|
||||
data_type* data; ///< The data storage
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -13,32 +13,51 @@
|
||||
#include "bitmap.hpp"
|
||||
#include "logging.hpp"
|
||||
|
||||
/*!
|
||||
* \brief Returns the nth power of x
|
||||
*/
|
||||
template <class T>
|
||||
inline constexpr T pow(T const& x, size_t n){
|
||||
return n > 0 ? x * pow(x, n - 1) : 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Buddy allocator system.
|
||||
*
|
||||
* This is used to allocate physical and virtual memory
|
||||
*/
|
||||
template<size_t Levels, size_t Unit>
|
||||
struct buddy_allocator {
|
||||
static constexpr const size_t levels = Levels;
|
||||
static constexpr const size_t max_block = pow(2, levels - 1);
|
||||
static constexpr const size_t levels = Levels; ///< The number of levels in the allocator
|
||||
static constexpr const size_t max_block = pow(2, levels - 1); ///< The size of the maximum block
|
||||
|
||||
std::array<static_bitmap, levels> bitmaps;
|
||||
std::array<static_bitmap, levels> bitmaps; ///< The bit maps for each level
|
||||
|
||||
size_t first_address;
|
||||
size_t last_address;
|
||||
size_t first_address; ///< The first managed address
|
||||
size_t last_address; ///< The last managed address
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Sets the memory range of the allocator
|
||||
*/
|
||||
void set_memory_range(size_t first, size_t last){
|
||||
first_address = first;
|
||||
last_address = last;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initialize the layer I
|
||||
* \param words The number of words
|
||||
* \param data The memory to use
|
||||
*/
|
||||
template<size_t I>
|
||||
void init(size_t words, uint64_t* data){
|
||||
bitmaps[I].init(words, data);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initialize the allocator
|
||||
*/
|
||||
void init(){
|
||||
//By default all blocks are free
|
||||
for(auto& bitmap : bitmaps){
|
||||
@ -46,6 +65,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Allocate memory for the given amount of pages
|
||||
*/
|
||||
size_t allocate(size_t pages){
|
||||
if(pages > max_block){
|
||||
if(pages > max_block * static_bitmap::bits_per_word){
|
||||
@ -55,7 +77,7 @@ public:
|
||||
} else {
|
||||
// Select a level for which a whole word can hold the necessary pages
|
||||
auto l = word_level(pages);
|
||||
auto index = bitmaps[l].free_word();
|
||||
auto index = bitmaps[l].set_word();
|
||||
auto address = block_start(l, index);
|
||||
|
||||
if(address + level_size(l) >= last_address){
|
||||
@ -72,7 +94,7 @@ public:
|
||||
}
|
||||
} else {
|
||||
auto l = level(pages);
|
||||
auto index = bitmaps[l].free_bit();
|
||||
auto index = bitmaps[l].set_bit();
|
||||
auto address = block_start(l, index);
|
||||
|
||||
if(address + level_size(l) >= last_address){
|
||||
@ -86,6 +108,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Free allocated memory pages
|
||||
* \param address The allocated memory
|
||||
* \param pages The number of pages to free
|
||||
*/
|
||||
void free(size_t address, size_t pages){
|
||||
if(pages > max_block){
|
||||
if(pages > max_block * static_bitmap::bits_per_word){
|
||||
@ -108,17 +135,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The size of the given level
|
||||
*/
|
||||
static size_t level_size(size_t level){
|
||||
size_t size = 1;
|
||||
|
||||
for(size_t i = 0; i < level; ++i){
|
||||
size *= 2;
|
||||
}
|
||||
|
||||
return size;
|
||||
return pow(2, level);
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Returns the level to use for the given amount of pages
|
||||
*/
|
||||
static size_t level(size_t pages){
|
||||
if(pages > 64){
|
||||
return 7;
|
||||
@ -153,6 +180,11 @@ private:
|
||||
return levels;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Mark the given buddy as used
|
||||
* \param l The used level
|
||||
* \param index The used index
|
||||
*/
|
||||
void mark_used(size_t l, size_t index){
|
||||
//Mark all sub blocks as taken
|
||||
taken_down(l, index);
|
||||
@ -164,6 +196,11 @@ private:
|
||||
taken_up(l, index);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Mark the given buddy as free
|
||||
* \param l The freed level
|
||||
* \param index The freeed index
|
||||
*/
|
||||
void mark_free(size_t l, size_t index){
|
||||
//Free all sub blocks
|
||||
free_down(l, index);
|
||||
|
Loading…
x
Reference in New Issue
Block a user