提交 53e47e25 编写于 作者: B Brian Johnson

Refactored existing handling of malloc and realloc to add new pages of memory....

Refactored existing handling of malloc and realloc to add new pages of memory.  Currently, memory pages are fabricated.
上级 70e0930d
......@@ -16,79 +16,73 @@ namespace eos {
* @{
*/
class memory
class memory_manager
{
friend void* malloc(uint32_t size);
friend void* realloc(void* ptr, uint32_t size);
friend void free(void* ptr);
friend void* malloc(uint32_t size);
friend void* realloc(void* ptr, uint32_t size);
friend void free(void* ptr);
public:
memory()
: _offset(0)
memory_manager()
: _current_heap(0)
{
memset(_initial_heap, 0, sizeof(_initial_heap));
}
private:
void* malloc(uint32_t size)
{
if (_offset + size + SIZE_MARKER > INITIAL_HEAP_SIZE || size == 0)
return nullptr;
// first pass of loop never has to initialize the slot in _available_heap
uint32_t needs_init = 0;
char* buffer = nullptr;
uint32_t current_heap = _current_heap;
for (;current_heap < HEAPS_SIZE; ++current_heap)
{
memory& current = _available_heaps[current_heap];
if(!current.is_init())
{
char* new_heap = nullptr;
if (current_heap == 0)
{
memset(_initial_heap, 0, sizeof(_initial_heap));
current.init(_initial_heap, INITIAL_HEAP_SIZE);
}
else
{
// REMOVE logic, just using to test out multiple heap logic till memory can be allocated
char* const new_heap = &_initial_heap[INITIAL_HEAP_SIZE + NEW_HEAP_SIZE * (current_heap - 1)];
_available_heaps[current_heap].init(new_heap, NEW_HEAP_SIZE);
}
}
buffer = current.malloc(size);
if (buffer != nullptr)
break;
}
// only update the current_heap if memory was allocated
if (buffer != nullptr)
{
_current_heap = current_heap;
}
buffer_ptr new_buff(&_initial_heap[_offset + SIZE_MARKER], size);
_offset += size + SIZE_MARKER;
return new_buff.ptr();
return buffer;
}
void* realloc(void* ptr, uint32_t size)
{
char* realloc_ptr = nullptr;
uint32_t orig_ptr_size = 0;
const char* const END_OF_BUFFER = _initial_heap + INITIAL_HEAP_SIZE;
char* const char_ptr = static_cast<char*>(ptr);
if (ptr != nullptr)
{
buffer_ptr orig_buffer(ptr);
if (orig_buffer.size_ptr() >= _initial_heap && ptr < END_OF_BUFFER)
char* const char_ptr = static_cast<char*>(ptr);
for (memory* realloc_heap = _available_heaps; realloc_heap < _available_heaps + HEAPS_SIZE && realloc_heap->is_init(); ++realloc_heap)
{
orig_ptr_size = orig_buffer.size();
// is the passed in pointer valid
char* const orig_buffer_end = orig_buffer.end();
if (orig_buffer_end < END_OF_BUFFER)
{
// is there enough memory to allocate new buffer
if (ptr >= END_OF_BUFFER - size)
{
// not handling in current implementation
return nullptr;
}
const int32_t diff = size - orig_ptr_size;
if (diff < 0)
{
memset(orig_buffer_end + diff, 0, -diff);
// if ptr was the last allocated buffer, we can contract
if (orig_buffer_end == &_initial_heap[_offset])
{
_offset += diff;
}
// else current implementation doesn't worry about freeing excess memory
return ptr;
}
// if ptr was the last allocated buffer, we can expand
else if (orig_buffer_end == &_initial_heap[_offset])
{
orig_buffer.size(size);
_offset += diff;
return ptr;
}
else if (diff == 0)
return ptr;
}
else
if (realloc_heap->is_in_heap(char_ptr))
{
orig_ptr_size = 0;
realloc_ptr = realloc_heap->realloc_in_place(char_ptr, size, &orig_ptr_size);
if (realloc_ptr != nullptr)
return realloc_ptr;
else
break;
}
}
}
......@@ -110,56 +104,168 @@ namespace eos {
// currently no-op
}
class buffer_ptr
class memory
{
public:
buffer_ptr(void* ptr)
: _ptr(static_cast<char*>(ptr))
, _size(*(uint32_t*)(static_cast<char*>(ptr) - SIZE_MARKER))
memory()
: _heap_size(0)
, _heap(nullptr)
, _offset(0)
{
}
buffer_ptr(void* ptr, uint32_t buff_size)
: _ptr(static_cast<char*>(ptr))
void init(char* const mem_heap, uint32_t size)
{
size(buff_size);
_heap_size = size;
_heap = mem_heap;
_offset = 0;
memset(_heap, 0, _heap_size);
}
const void* size_ptr()
uint32_t is_init() const
{
return _ptr - SIZE_MARKER;
return _heap != nullptr;
}
uint32_t size()
uint32_t is_in_heap(const char* const ptr) const
{
return _size;
const char* const END_OF_BUFFER = _heap + _heap_size;
const char* const FIRST_PTR_OF_BUFFER = _heap + SIZE_MARKER;
return ptr >= FIRST_PTR_OF_BUFFER && ptr < END_OF_BUFFER;
}
void size(uint32_t val)
uint32_t is_capacity_remaining() const
{
*reinterpret_cast<uint32_t*>(_ptr - SIZE_MARKER) = val;
_size = val;
return _offset + SIZE_MARKER < _heap_size;
}
char* end()
char* malloc(uint32_t size)
{
return _ptr + _size;
if (_offset + size + SIZE_MARKER > _heap_size || size == 0)
{
return nullptr;
}
buffer_ptr new_buff(&_heap[_offset + SIZE_MARKER], size);
_offset += size + SIZE_MARKER;
return new_buff.ptr();
}
char* realloc_in_place(char* const ptr, uint32_t size, uint32_t* orig_ptr_size)
{
const char* const END_OF_BUFFER = _heap + _heap_size;
buffer_ptr orig_buffer(ptr);
*orig_ptr_size = orig_buffer.size();
// is the passed in pointer valid
char* const orig_buffer_end = orig_buffer.end();
if (orig_buffer_end > END_OF_BUFFER)
{
*orig_ptr_size = 0;
return nullptr;
}
if (ptr > END_OF_BUFFER - size)
{
// cannot resize in place
return nullptr;
}
const int32_t diff = size - *orig_ptr_size;
if (diff < 0)
{
memset(orig_buffer_end + diff, 0, -diff);
// if ptr was the last allocated buffer, we can contract
if (orig_buffer_end == &_heap[_offset])
{
_offset += diff;
}
// else current implementation doesn't worry about freeing excess memory
return ptr;
}
// if ptr was the last allocated buffer, we can expand
else if (orig_buffer_end == &_heap[_offset])
{
orig_buffer.size(size);
_offset += diff;
return ptr;
}
else if (diff == 0)
{
return ptr;
}
// could not resize in place
return nullptr;
}
char* ptr()
void free(char* )
{
return _ptr;
// currently no-op
}
private:
class buffer_ptr
{
public:
buffer_ptr(void* ptr)
: _ptr(static_cast<char*>(ptr))
, _size(*(uint32_t*)(static_cast<char*>(ptr) - SIZE_MARKER))
{
}
buffer_ptr(void* ptr, uint32_t buff_size)
: _ptr(static_cast<char*>(ptr))
{
size(buff_size);
}
const void* size_ptr()
{
return _ptr - SIZE_MARKER;
}
uint32_t size()
{
return _size;
}
void size(uint32_t val)
{
*reinterpret_cast<uint32_t*>(_ptr - SIZE_MARKER) = val;
_size = val;
}
char* end()
{
return _ptr + _size;
}
char* ptr()
{
return _ptr;
}
private:
char* const _ptr;
uint32_t _size;
};
char* const _ptr;
uint32_t _size;
uint32_t _heap_size;
char* _heap;
uint32_t _offset;
};
static const uint32_t SIZE_MARKER = sizeof(uint32_t);
static const uint32_t INITIAL_HEAP_SIZE = 8192;//32768;
char _initial_heap[INITIAL_HEAP_SIZE];
uint32_t _offset;
static const uint32_t NEW_HEAP_SIZE = 1024; // should be 65536
static const uint32_t HEAPS_SIZE = 4; // _initial_heap plus 3 pages (64K each)
// should be just INITIAL_HEAP_SIZE, adding extra space for testing multiple buffers
char _initial_heap[INITIAL_HEAP_SIZE + NEW_HEAP_SIZE * (HEAPS_SIZE - 1)];
memory _available_heaps[HEAPS_SIZE];
uint32_t _current_heap;
} memory_heap;
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册