genode/base/src/core/include/core_mem_alloc.h

173 lines
4.4 KiB
C
Raw Normal View History

2011-12-22 16:19:25 +01:00
/*
* \brief Allocator infrastructure for core
* \author Norman Feske
* \date 2009-10-12
*/
/*
2012-01-03 15:35:05 +01:00
* Copyright (C) 2009-2012 Genode Labs GmbH
2011-12-22 16:19:25 +01:00
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__CORE_MEM_ALLOC_H_
#define _CORE__INCLUDE__CORE_MEM_ALLOC_H_
#include <base/lock.h>
#include <base/sync_allocator.h>
#include <base/allocator_avl.h>
namespace Genode {
/**
* Allocators for physical memory, core's virtual address space,
* and core-local memory. The interface of this class is thread safe.
*/
class Core_mem_allocator : public Allocator
{
public:
typedef Synchronized_range_allocator<Allocator_avl> Phys_allocator;
private:
/**
* Unsynchronized allocator for core-mapped memory
*
* This is an allocator of core-mapped memory. It is meant to be used as
* meta-data allocator for the other allocators and as back end for core's
* synchronized memory allocator.
*/
class Mapped_mem_allocator : public Allocator
{
private:
Allocator_avl _alloc;
Range_allocator *_phys_alloc;
Range_allocator *_virt_alloc;
/**
* Initial chunk to populate the core mem allocator
*
* This chunk is used at platform initialization time.
*/
char _initial_chunk[16*1024];
/**
* Map physical page locally to specified virtual address
*
* \param virt_addr core-local address
* \param phys_addr physical memory address
* \param size_log2 size of memory block to map
* \return true on success
*/
bool _map_local(addr_t virt_addr, addr_t phys_addr, unsigned size_log2);
public:
/**
* Constructor
*
* \param phys_alloc allocator of physical memory
* \param virt_alloc allocator of core-local virtual memory ranges
*/
Mapped_mem_allocator(Range_allocator *phys_alloc,
Range_allocator *virt_alloc)
: _alloc(0), _phys_alloc(phys_alloc), _virt_alloc(virt_alloc)
{
_alloc.add_range((addr_t)_initial_chunk, sizeof(_initial_chunk));
}
/*************************
** Allocator interface **
*************************/
bool alloc(size_t size, void **out_addr);
void free(void *addr, size_t size) { _alloc.free(addr, size); }
size_t consumed() { return _phys_alloc->consumed(); }
size_t overhead(size_t size) { return _phys_alloc->overhead(size); }
};
/**
* Lock used for synchronization of all operations on the
* embedded allocators.
*/
Lock _lock;
/**
* Synchronized allocator of physical memory ranges
*
* This allocator must only be used to allocate memory
* ranges at page granularity.
*/
Phys_allocator _phys_alloc;
/**
* Synchronized allocator of core's virtual memory ranges
*
* This allocator must only be used to allocate memory
* ranges at page granularity.
*/
Phys_allocator _virt_alloc;
/**
* Unsynchronized core-mapped memory allocator
*
* This allocator is internally used within this class for
* allocating meta data for the other allocators. It is not
* synchronized to avoid nested locking. The lock-guarded
* access to this allocator from the outer world is
* provided via the 'Allocator' interface implemented by
* 'Core_mem_allocator'. The allocator works at byte
* granularity.
*/
Mapped_mem_allocator _mem_alloc;
public:
/**
* Constructor
*/
Core_mem_allocator() :
_phys_alloc(&_lock, &_mem_alloc),
_virt_alloc(&_lock, &_mem_alloc),
_mem_alloc(_phys_alloc.raw(), _virt_alloc.raw())
{ }
/**
* Access physical-memory allocator
*/
Phys_allocator *phys_alloc() { return &_phys_alloc; }
/**
* Access core's virtual-memory allocator
*/
Phys_allocator *virt_alloc() { return &_virt_alloc; }
/*************************
** Allocator interface **
*************************/
bool alloc(size_t size, void **out_addr)
{
Lock::Guard lock_guard(_lock);
return _mem_alloc.alloc(size, out_addr);
}
void free(void *addr, size_t size)
{
Lock::Guard lock_guard(_lock);
_mem_alloc.free(addr, size);
}
size_t consumed() { return _phys_alloc.consumed(); }
size_t overhead(size_t size) { return _phys_alloc.overhead(size); }
};
}
#endif /* _CORE__INCLUDE__CORE_MEM_ALLOC_H_ */