safeguard the synchronized allocator template

* Move the Synced_interface from os -> base
* Align the naming of "synchronized" helpers to "Synced_*"
* Move Synced_range_allocator to core's private headers
* Remove the raw() and lock() members from Synced_allocator and
  Synced_range_allocator, and re-use the Synced_interface for them
* Make core's Mapped_mem_allocator a friend class of Synced_range_allocator
  to enable the needed "unsafe" access of its physical and virtual allocators

Fix #1697
This commit is contained in:
Stefan Kalkowski 2015-09-17 14:16:59 +02:00 committed by Christian Helmuth
parent 53eb666ed0
commit ccb968ff7d
35 changed files with 432 additions and 519 deletions

View File

@ -15,9 +15,9 @@
#ifndef _CORE__INCLUDE__PLATFORM_H_
#define _CORE__INCLUDE__PLATFORM_H_
#include <base/sync_allocator.h>
#include <base/allocator_avl.h>
#include "synced_range_allocator.h"
#include "platform_generic.h"
#include "platform_thread.h"
#include "platform_pd.h"
@ -33,7 +33,7 @@ namespace Genode {
/*
* Shortcut for the type of allocator instances for physical resources
*/
typedef Synchronized_range_allocator<Allocator_avl> Phys_allocator;
typedef Synced_range_allocator<Allocator_avl> Phys_allocator;
char _core_label[1]; /* to satisfy _core_pd */
Platform_pd *_core_pd; /* core protection domain object */

View File

@ -49,9 +49,9 @@ static const bool verbose_region_alloc = false;
** Core address space management **
***********************************/
static Synchronized_range_allocator<Allocator_avl> &_core_address_ranges()
static Synced_range_allocator<Allocator_avl> &_core_address_ranges()
{
static Synchronized_range_allocator<Allocator_avl> _core_address_ranges(0);
static Synced_range_allocator<Allocator_avl> _core_address_ranges(nullptr);
return _core_address_ranges;
}
@ -457,7 +457,7 @@ void Platform::_setup_rom()
Platform::Platform() :
_ram_alloc(0), _io_mem_alloc(core_mem_alloc()),
_ram_alloc(nullptr), _io_mem_alloc(core_mem_alloc()),
_io_port_alloc(core_mem_alloc()), _irq_alloc(core_mem_alloc()),
_region_alloc(core_mem_alloc())
{
@ -475,13 +475,13 @@ Platform::Platform() :
_setup_rom();
if (verbose) {
printf(":ram_alloc: "); _ram_alloc.raw()->dump_addr_tree();
printf(":region_alloc: "); _region_alloc.raw()->dump_addr_tree();
printf(":io_mem: "); _io_mem_alloc.raw()->dump_addr_tree();
printf(":io_port: "); _io_port_alloc.raw()->dump_addr_tree();
printf(":irq: "); _irq_alloc.raw()->dump_addr_tree();
printf(":ram_alloc: "); _ram_alloc()->dump_addr_tree();
printf(":region_alloc: "); _region_alloc()->dump_addr_tree();
printf(":io_mem: "); _io_mem_alloc()->dump_addr_tree();
printf(":io_port: "); _io_port_alloc()->dump_addr_tree();
printf(":irq: "); _irq_alloc()->dump_addr_tree();
printf(":rom_fs: "); _rom_fs.print_fs();
printf(":core ranges: "); _core_address_ranges().raw()->dump_addr_tree();
printf(":core ranges: "); _core_address_ranges()()->dump_addr_tree();
}
Fiasco::l4_threadid_t myself = Fiasco::l4_myself();

View File

@ -18,7 +18,7 @@
#include <base/allocator_avl.h>
#include <base/exception.h>
#include <base/lock.h>
#include <base/sync_allocator.h>
#include <synced_range_allocator.h>
namespace Genode {
@ -33,8 +33,8 @@ namespace Genode {
CAP_ID_OFFSET = 1 << 2
};
Synchronized_range_allocator<Allocator_avl> _id_alloc;
Lock _lock;
Synced_range_allocator<Allocator_avl> _id_alloc;
Lock _lock;
public:

View File

@ -17,7 +17,7 @@
#define _CORE__INCLUDE__PLATFORM_H_
/* Genode includes */
#include <base/sync_allocator.h>
#include <base/synced_allocator.h>
#include <base/allocator_avl.h>
/* Core includes */
@ -51,7 +51,7 @@ namespace Genode {
/*
* Shortcut for the type of allocator instances for physical resources
*/
typedef Synchronized_range_allocator<Allocator_avl> Phys_allocator;
typedef Synced_range_allocator<Allocator_avl> Phys_allocator;
Platform_pd *_core_pd; /* core protection domain object */
Phys_allocator _ram_alloc; /* RAM allocator */

View File

@ -21,7 +21,7 @@
/* Genode includes */
#include <base/allocator_avl.h>
#include <base/exception.h>
#include <base/sync_allocator.h>
#include <base/synced_allocator.h>
#include <platform_thread.h>
#include <base/thread.h>

View File

@ -53,9 +53,9 @@ static const bool verbose_region_alloc = false;
** Core address space management **
***********************************/
static Synchronized_range_allocator<Allocator_avl> &_core_address_ranges()
static Synced_range_allocator<Allocator_avl> &_core_address_ranges()
{
static Synchronized_range_allocator<Allocator_avl> _core_address_ranges(0);
static Synced_range_allocator<Allocator_avl> _core_address_ranges(nullptr);
return _core_address_ranges;
}
@ -465,7 +465,7 @@ void Platform::_setup_rom()
Platform::Platform() :
_ram_alloc(0), _io_mem_alloc(core_mem_alloc()),
_ram_alloc(nullptr), _io_mem_alloc(core_mem_alloc()),
_io_port_alloc(core_mem_alloc()), _irq_alloc(core_mem_alloc()),
_region_alloc(core_mem_alloc()), _cap_id_alloc(core_mem_alloc()),
_sigma0(cap_map()->insert(_cap_id_alloc.alloc(), Fiasco::L4_BASE_PAGER_CAP))
@ -484,13 +484,13 @@ Platform::Platform() :
_setup_rom();
if (verbose) {
printf(":ram_alloc: "); _ram_alloc.raw()->dump_addr_tree();
printf(":region_alloc: "); _region_alloc.raw()->dump_addr_tree();
printf(":io_mem: "); _io_mem_alloc.raw()->dump_addr_tree();
printf(":io_port: "); _io_port_alloc.raw()->dump_addr_tree();
printf(":irq: "); _irq_alloc.raw()->dump_addr_tree();
printf(":ram_alloc: "); _ram_alloc()->dump_addr_tree();
printf(":region_alloc: "); _region_alloc()->dump_addr_tree();
printf(":io_mem: "); _io_mem_alloc()->dump_addr_tree();
printf(":io_port: "); _io_port_alloc()->dump_addr_tree();
printf(":irq: "); _irq_alloc()->dump_addr_tree();
printf(":rom_fs: "); _rom_fs.print_fs();
printf(":core ranges: "); _core_address_ranges().raw()->dump_addr_tree();
printf(":core ranges: "); _core_address_ranges()()->dump_addr_tree();
}
Core_cap_index* pdi =

View File

@ -16,7 +16,7 @@
#define _CORE__INCLUDE__PLATFORM_H_
/* Genode includes */
#include <base/sync_allocator.h>
#include <base/synced_allocator.h>
#include <base/allocator_avl.h>
#include <irq_session/irq_session.h>
@ -46,8 +46,6 @@ namespace Genode {
{
private:
typedef Core_mem_allocator::Phys_allocator Phys_allocator;
Core_mem_allocator _core_mem_alloc; /* core-accessible memory */
Phys_allocator _io_mem_alloc; /* MMIO allocator */
Phys_allocator _io_port_alloc; /* I/O port allocator */

View File

@ -59,7 +59,7 @@ class Hw::Address_space : public Genode::Address_space
private:
friend class Genode::Platform;
friend class Genode::Core_mem_allocator::Mapped_mem_allocator;
friend class Genode::Mapped_mem_allocator;
using Table_allocator =
Translation_table_allocator_tpl<DEFAULT_TRANSLATION_TABLE_MAX>;

View File

@ -159,23 +159,23 @@ Platform::Platform()
if (VERBOSE) {
printf("Core virtual memory allocator\n");
printf("---------------------\n");
_core_mem_alloc.virt_alloc()->raw()->dump_addr_tree();
(*_core_mem_alloc.virt_alloc())()->dump_addr_tree();
printf("\n");
printf("RAM memory allocator\n");
printf("---------------------\n");
_core_mem_alloc.phys_alloc()->raw()->dump_addr_tree();
(*_core_mem_alloc.phys_alloc())()->dump_addr_tree();
printf("\n");
printf("IO memory allocator\n");
printf("-------------------\n");
_io_mem_alloc.raw()->dump_addr_tree();
_io_mem_alloc()->dump_addr_tree();
printf("\n");
printf("IO port allocator\n");
printf("-------------------\n");
_io_port_alloc.raw()->dump_addr_tree();
_io_port_alloc()->dump_addr_tree();
printf("\n");
printf("IRQ allocator\n");
printf("-------------------\n");
_irq_alloc.raw()->dump_addr_tree();
_irq_alloc()->dump_addr_tree();
printf("\n");
printf("ROM filesystem\n");
printf("--------------\n");
@ -217,12 +217,10 @@ bool Genode::unmap_local(addr_t virt_addr, size_t num_pages)
}
bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr,
addr_t phys_addr,
unsigned size) {
bool Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr,
unsigned size) {
return ::map_local(phys_addr, virt_addr, size / get_page_size()); }
bool Core_mem_allocator::Mapped_mem_allocator::_unmap_local(addr_t virt_addr,
unsigned size) {
bool Mapped_mem_allocator::_unmap_local(addr_t virt_addr, unsigned size) {
return ::unmap_local(virt_addr, size / get_page_size()); }

View File

@ -15,13 +15,13 @@
#ifndef _CORE__INCLUDE__LINUX__PLATFORM_H_
#define _CORE__INCLUDE__LINUX__PLATFORM_H_
#include <base/sync_allocator.h>
#include <base/allocator_avl.h>
#include <base/lock_guard.h>
#include <platform_generic.h>
#include <platform_pd.h>
#include <platform_thread.h>
#include <synced_range_allocator.h>
namespace Genode {
@ -34,7 +34,7 @@ namespace Genode {
/**
* Allocator for core-internal meta data
*/
Synchronized_range_allocator<Allocator_avl> _core_mem_alloc;
Synced_range_allocator<Allocator_avl> _core_mem_alloc;
/**
* Allocator for pseudo physical memory

View File

@ -84,7 +84,7 @@ static void sigchld_handler(int signnum)
Platform::Platform()
: _core_mem_alloc(0)
: _core_mem_alloc(nullptr)
{
/* catch control-c */
lx_sigaction(LX_SIGINT, sigint_handler);

View File

@ -27,8 +27,6 @@ namespace Genode {
{
private:
typedef Core_mem_allocator::Phys_allocator Phys_allocator;
Core_mem_allocator _core_mem_alloc; /* core-accessible memory */
Phys_allocator _io_mem_alloc; /* MMIO allocator */
Phys_allocator _io_port_alloc; /* I/O port allocator */

View File

@ -620,9 +620,9 @@ Platform::Platform() :
_gsi_base_sel = (hip->mem_desc_offset - hip->cpu_desc_offset) / hip->cpu_desc_size;
if (verbose_boot_info) {
printf(":virt_alloc: "); _core_mem_alloc.virt_alloc()->raw()->dump_addr_tree();
printf(":phys_alloc: "); _core_mem_alloc.phys_alloc()->raw()->dump_addr_tree();
printf(":io_mem_alloc: "); _io_mem_alloc.raw()->dump_addr_tree();
printf(":virt_alloc: "); (*_core_mem_alloc.virt_alloc())()->dump_addr_tree();
printf(":phys_alloc: "); (*_core_mem_alloc.phys_alloc())()->dump_addr_tree();
printf(":io_mem_alloc: "); _io_mem_alloc()->dump_addr_tree();
}
/* add capability selector ranges to map */
@ -696,9 +696,8 @@ Platform::Platform() :
** Support for core memory management **
****************************************/
bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr,
addr_t phys_addr,
unsigned size)
bool Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr,
unsigned size)
{
map_local((Utcb *)Thread_base::myself()->utcb(), phys_addr,
virt_addr, size / get_page_size(),
@ -707,8 +706,7 @@ bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr,
}
bool Core_mem_allocator::Mapped_mem_allocator::_unmap_local(addr_t virt_addr,
unsigned size)
bool Mapped_mem_allocator::_unmap_local(addr_t virt_addr, unsigned size)
{
unmap_local((Utcb *)Thread_base::myself()->utcb(),
virt_addr, size / get_page_size());

View File

@ -35,7 +35,6 @@ namespace Genode {
{
private:
using Phys_allocator = Core_mem_allocator::Phys_allocator;
using Rom_slab = Tslab<Rom_module, get_page_size()>;
using Thread_slab = Tslab<Platform_thread, get_page_size()>;

View File

@ -53,14 +53,12 @@ static int num_boot_module_objects;
** Support for core memory management **
****************************************/
bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr,
addr_t phys_addr,
unsigned size) {
bool Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr,
unsigned size) {
return map_local(phys_addr, virt_addr, size / get_page_size()); }
bool Core_mem_allocator::Mapped_mem_allocator::_unmap_local(addr_t virt_addr,
unsigned size) {
bool Mapped_mem_allocator::_unmap_local(addr_t virt_addr, unsigned size) {
return unmap_local(virt_addr, size / get_page_size()); }
@ -284,11 +282,11 @@ Platform::Platform() :
* hold the meta data for the ROM modules as initialized by '_setup_rom'.
*/
if (verbose_boot_info) {
printf(":phys_alloc: "); _core_mem_alloc.phys_alloc()->raw()->dump_addr_tree();
printf(":virt_alloc: "); _core_mem_alloc.virt_alloc()->raw()->dump_addr_tree();
printf(":io_mem: "); _io_mem_alloc.raw()->dump_addr_tree();
printf(":io_port: "); _io_port_alloc.raw()->dump_addr_tree();
printf(":irq: "); _irq_alloc.raw()->dump_addr_tree();
printf(":phys_alloc: "); (*_core_mem_alloc.phys_alloc())()->dump_addr_tree();
printf(":virt_alloc: "); (*_core_mem_alloc.virt_alloc())()->dump_addr_tree();
printf(":io_mem: "); _io_mem_alloc()->dump_addr_tree();
printf(":io_port: "); _io_port_alloc()->dump_addr_tree();
printf(":irq: "); _irq_alloc()->dump_addr_tree();
printf(":rom_fs: "); _rom_fs.print_fs();
}

View File

@ -15,9 +15,9 @@
#ifndef _CORE__INCLUDE__PLATFORM_H_
#define _CORE__INCLUDE__PLATFORM_H_
#include <base/sync_allocator.h>
#include <base/allocator_avl.h>
#include "synced_range_allocator.h"
#include "platform_generic.h"
#include "platform_thread.h"
#include "platform_pd.h"
@ -33,7 +33,7 @@ namespace Genode {
/*
* Shortcut for the type of allocator instances for physical resources
*/
typedef Synchronized_range_allocator<Allocator_avl> Phys_allocator;
typedef Synced_range_allocator<Allocator_avl> Phys_allocator;
Phys_allocator _ram_alloc; /* RAM allocator */
Phys_allocator _io_mem_alloc; /* MMIO allocator */

View File

@ -50,9 +50,9 @@ static const bool verbose_region_alloc = false;
** Core address space management **
***********************************/
static Synchronized_range_allocator<Allocator_avl> &_core_address_ranges()
static Synced_range_allocator<Allocator_avl> &_core_address_ranges()
{
static Synchronized_range_allocator<Allocator_avl> _core_address_ranges(0);
static Synced_range_allocator<Allocator_avl> _core_address_ranges(nullptr);
return _core_address_ranges;
}
@ -625,7 +625,7 @@ Platform_pd *Platform::core_pd()
Platform::Platform() :
_ram_alloc(0), _io_mem_alloc(core_mem_alloc()),
_ram_alloc(nullptr), _io_mem_alloc(core_mem_alloc()),
_io_port_alloc(core_mem_alloc()), _irq_alloc(core_mem_alloc()),
_region_alloc(core_mem_alloc())
{
@ -649,13 +649,13 @@ Platform::Platform() :
* hold the meta data for the ROM modules as initialized by '_setup_rom'.
*/
if (verbose) {
printf(":ram_alloc: "); _ram_alloc.raw()->dump_addr_tree();
printf(":region_alloc: "); _region_alloc.raw()->dump_addr_tree();
printf(":io_mem: "); _io_mem_alloc.raw()->dump_addr_tree();
printf(":io_port: "); _io_port_alloc.raw()->dump_addr_tree();
printf(":irq: "); _irq_alloc.raw()->dump_addr_tree();
printf(":ram_alloc: "); _ram_alloc()->dump_addr_tree();
printf(":region_alloc: "); _region_alloc()->dump_addr_tree();
printf(":io_mem: "); _io_mem_alloc()->dump_addr_tree();
printf(":io_port: "); _io_port_alloc()->dump_addr_tree();
printf(":irq: "); _irq_alloc()->dump_addr_tree();
printf(":rom_fs: "); _rom_fs.print_fs();
printf(":core ranges: "); _core_address_ranges().raw()->dump_addr_tree();
printf(":core ranges: "); _core_address_ranges()()->dump_addr_tree();
}
/*

View File

@ -16,6 +16,7 @@
#include <rm_session/rm_session.h>
#include <ram_session/ram_session.h>
#include <base/printf.h>
#include <base/synced_allocator.h>
#include <base/thread.h>
/* local includes */
@ -42,8 +43,8 @@ class Context_area_rm_session : public Rm_session
{
private:
using Ds_slab = Synchronized_allocator<Tslab<Dataspace_component,
get_page_size()> >;
using Ds_slab = Synced_allocator<Tslab<Dataspace_component,
get_page_size()> >;
Ds_slab _ds_slab { platform()->core_mem_alloc() };

View File

@ -30,9 +30,6 @@ class Genode::Platform : public Platform_generic
{
private:
typedef Core_mem_allocator::Phys_allocator Phys_allocator;
Core_mem_allocator _core_mem_alloc; /* core-accessible memory */
Phys_allocator _io_mem_alloc; /* MMIO allocator */
Phys_allocator _io_port_alloc; /* I/O port allocator */

View File

@ -56,9 +56,8 @@ extern int _boot_modules_binaries_end;
** Support for core memory management **
****************************************/
bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr,
addr_t phys_addr,
unsigned size)
bool Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr,
unsigned size)
{
size_t const num_pages = size / get_page_size();
@ -68,8 +67,7 @@ bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr,
}
bool Core_mem_allocator::Mapped_mem_allocator::_unmap_local(addr_t virt_addr,
unsigned size)
bool Mapped_mem_allocator::_unmap_local(addr_t virt_addr, unsigned size)
{
return unmap_local(virt_addr, size / get_page_size());
}
@ -364,10 +362,10 @@ Platform::Platform()
printf("VM area at [%08lx,%08lx)\n", _vm_base, _vm_base + _vm_size);
if (verbose_boot_info) {
printf(":phys_alloc: "); _core_mem_alloc.phys_alloc()->raw()->dump_addr_tree();
printf(":unused_phys_alloc:"); _unused_phys_alloc.raw()->dump_addr_tree();
printf(":virt_alloc: "); _core_mem_alloc.virt_alloc()->raw()->dump_addr_tree();
printf(":io_mem_alloc: "); _io_mem_alloc.raw()->dump_addr_tree();
printf(":phys_alloc: "); (*_core_mem_alloc.phys_alloc())()->dump_addr_tree();
printf(":unused_phys_alloc:"); _unused_phys_alloc()->dump_addr_tree();
printf(":virt_alloc: "); (*_core_mem_alloc.virt_alloc())()->dump_addr_tree();
printf(":io_mem_alloc: "); _io_mem_alloc()->dump_addr_tree();
}
_init_rom_modules();

View File

@ -1,261 +0,0 @@
/*
* \brief Lock-guarded allocator interface
* \author Norman Feske
* \date 2008-08-05
*/
/*
* Copyright (C) 2008-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__BASE__SYNC_ALLOCATOR_H_
#define _INCLUDE__BASE__SYNC_ALLOCATOR_H_
#include <base/allocator.h>
#include <base/lock.h>
namespace Genode {
template <typename> class Synchronized_allocator;
template <typename> class Synchronized_range_allocator;
}
/**
* Lock-guarded allocator
*
* This class wraps the complete 'Allocator' interface while
* preventing concurrent calls to the wrapped allocator implementation.
*
* \param ALLOCATOR_IMPL class implementing the 'Allocator'
* interface
*/
template <typename ALLOCATOR_IMPL>
class Genode::Synchronized_allocator : public Allocator
{
private:
Lock _default_lock;
Lock *_lock;
ALLOCATOR_IMPL _alloc;
public:
/**
* Constructor
*
* This constructor uses an embedded lock for synchronizing the
* access to the allocator.
*/
Synchronized_allocator()
: _lock(&_default_lock) { }
/**
* Constructor
*
* This constructor uses an embedded lock for synchronizing the
* access to the allocator.
*/
explicit Synchronized_allocator(Allocator *metadata_alloc)
: _lock(&_default_lock), _alloc(metadata_alloc) { }
/**
* Return reference to wrapped (non-thread-safe) allocator
*
* This is needed, for example, if the wrapped allocator implements
* methods in addition to the Range_allocator interface.
*/
ALLOCATOR_IMPL *raw() { return &_alloc; }
/*************************
** Allocator interface **
*************************/
bool alloc(size_t size, void **out_addr) override
{
Lock::Guard lock_guard(*_lock);
return _alloc.alloc(size, out_addr);
}
void free(void *addr, size_t size) override
{
Lock::Guard lock_guard(*_lock);
_alloc.free(addr, size);
}
size_t consumed() const override
{
Lock::Guard lock_guard(*_lock);
return _alloc.consumed();
}
size_t overhead(size_t size) const override
{
Lock::Guard lock_guard(*_lock);
return _alloc.overhead(size);
}
bool need_size_for_free() const override
{
Lock::Guard lock_guard(*_lock);
return _alloc.need_size_for_free();
}
};
/**
* Lock-guarded range allocator
*
* This class wraps the complete 'Range_allocator' interface while
* preventing concurrent calls to the wrapped allocator implementation.
*
* \param ALLOCATOR_IMPL class implementing the 'Range_allocator'
* interface
*/
template <typename ALLOCATOR_IMPL>
class Genode::Synchronized_range_allocator : public Range_allocator
{
private:
Lock _default_lock;
Lock *_lock;
ALLOCATOR_IMPL _alloc;
public:
/**
* Constructor
*
* This constructor uses an embedded lock for synchronizing the
* access to the allocator.
*/
Synchronized_range_allocator()
: _lock(&_default_lock) { }
/**
* Constructor
*
* This constructor uses an embedded lock for synchronizing the
* access to the allocator.
*/
explicit Synchronized_range_allocator(Allocator *metadata_alloc)
: _lock(&_default_lock), _alloc(metadata_alloc) { }
/**
* Constructor
*
* \param lock use specified lock rather then an embedded lock for
* synchronization
*
* This constructor is useful if multiple allocators must be
* synchronized with each other. In such as case, the shared
* lock can be passed to each 'Synchronized_range_allocator'
* instance.
*/
Synchronized_range_allocator(Lock *lock, Allocator *metadata_alloc)
: _lock(lock), _alloc(metadata_alloc) { }
/**
* Return reference to wrapped (non-thread-safe) allocator
*
* This is needed, for example, if the wrapped allocator implements
* methods in addition to the Range_allocator interface.
*
* NOTE: Synchronize accesses to the raw allocator by facilitating
* the lock() method.
*/
ALLOCATOR_IMPL *raw() { return &_alloc; }
/**
* Return reference to synchronization lock
*/
Lock *lock() { return _lock; }
/*************************
** Allocator interface **
*************************/
bool alloc(size_t size, void **out_addr) override
{
Lock::Guard lock_guard(*_lock);
return _alloc.alloc(size, out_addr);
}
void free(void *addr, size_t size) override
{
Lock::Guard lock_guard(*_lock);
_alloc.free(addr, size);
}
size_t consumed() const override
{
Lock::Guard lock_guard(*_lock);
return _alloc.consumed();
}
size_t overhead(size_t size) const override
{
Lock::Guard lock_guard(*_lock);
return _alloc.overhead(size);
}
bool need_size_for_free() const override
{
Lock::Guard lock_guard(*_lock);
return _alloc.need_size_for_free();
}
/*******************************
** Range-allocator interface **
*******************************/
int add_range(addr_t base, size_t size) override
{
Lock::Guard lock_guard(*_lock);
return _alloc.add_range(base, size);
}
int remove_range(addr_t base, size_t size) override
{
Lock::Guard lock_guard(*_lock);
return _alloc.remove_range(base, size);
}
Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0,
addr_t from = 0, addr_t to = ~0UL) override
{
Lock::Guard lock_guard(*_lock);
return _alloc.alloc_aligned(size, out_addr, align, from, to);
}
Alloc_return alloc_addr(size_t size, addr_t addr) override
{
Lock::Guard lock_guard(*_lock);
return _alloc.alloc_addr(size, addr);
}
void free(void *addr) override
{
Lock::Guard lock_guard(*_lock);
_alloc.free(addr);
}
size_t avail() const override
{
Lock::Guard lock_guard(*_lock);
return _alloc.avail();
}
bool valid_addr(addr_t addr) const override
{
Lock::Guard lock_guard(*_lock);
return _alloc.valid_addr(addr);
}
};
#endif /* _INCLUDE__BASE__SYNC_ALLOCATOR_H_ */

View File

@ -0,0 +1,75 @@
/*
* \brief Lock-guarded allocator interface
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2008-08-05
*/
/*
* Copyright (C) 2008-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__BASE__SYNCED_ALLOCATOR_H_
#define _INCLUDE__BASE__SYNCED_ALLOCATOR_H_
#include <base/allocator.h>
#include <base/synced_interface.h>
namespace Genode {
template <typename> class Synced_allocator;
}
/**
* Lock-guarded allocator
*
* This class wraps the complete 'Allocator' interface while
* preventing concurrent calls to the wrapped allocator implementation.
*
* \param ALLOC class implementing the 'Allocator' interface
*/
template <typename ALLOC>
class Genode::Synced_allocator : public Allocator
{
private:
Lock _lock;
ALLOC _alloc;
Synced_interface<ALLOC, Lock> _synced_object;
public:
using Guard = typename Synced_interface<ALLOC, Lock>::Guard;
template <typename... ARGS>
Synced_allocator(ARGS &&... args)
: _alloc(args...), _synced_object(_lock, &_alloc) { }
Guard operator () () { return _synced_object(); }
Guard operator () () const { return _synced_object(); }
/*************************
** Allocator interface **
*************************/
bool alloc(size_t size, void **out_addr) override {
return _synced_object()->alloc(size, out_addr); }
void free(void *addr, size_t size) override {
_synced_object()->free(addr, size); }
size_t consumed() const override {
return _synced_object()->consumed(); }
size_t overhead(size_t size) const override {
return _synced_object()->overhead(size); }
bool need_size_for_free() const override {
return _synced_object()->need_size_for_free(); }
};
#endif /* _INCLUDE__BASE__SYNCED_ALLOCATOR_H_ */

View File

@ -4,8 +4,8 @@
* \date 2013-05-16
*/
#ifndef _INCLUDE__OS__SYNCED_INTERFACE_H_
#define _INCLUDE__OS__SYNCED_INTERFACE_H_
#ifndef _INCLUDE__BASE__SYNCED_INTERFACE_H_
#define _INCLUDE__BASE__SYNCED_INTERFACE_H_
/* Genode includes */
#include <base/lock.h>
@ -67,6 +67,11 @@ class Genode::Synced_interface
{
return Guard(_lock, _interface);
}
Guard operator () () const
{
return Guard(_lock, _interface);
}
};
#endif /* _INCLUDE__OS__SYNCED_INTERFACE_H_ */
#endif /* _INCLUDE__BASE__SYNCED_INTERFACE_H_ */

View File

@ -16,6 +16,7 @@
#include <rm_session/rm_session.h>
#include <ram_session/ram_session.h>
#include <base/printf.h>
#include <base/synced_allocator.h>
#include <base/thread.h>
/* local includes */
@ -42,8 +43,8 @@ class Context_area_rm_session : public Rm_session
{
private:
using Ds_slab = Synchronized_allocator<Tslab<Dataspace_component,
get_page_size()> >;
using Ds_slab = Synced_allocator<Tslab<Dataspace_component,
get_page_size()> >;
Ds_slab _ds_slab { platform()->core_mem_alloc() };

View File

@ -24,7 +24,7 @@ using namespace Genode;
static const bool verbose_core_mem_alloc = false;
void * Core_mem_allocator::Mapped_avl_allocator::map_addr(void * addr)
void * Mapped_avl_allocator::map_addr(void * addr)
{
Block *b = static_cast<Block *>(_find_by_address((addr_t)addr));
@ -36,7 +36,7 @@ void * Core_mem_allocator::Mapped_avl_allocator::map_addr(void * addr)
Range_allocator::Alloc_return
Core_mem_allocator::Mapped_mem_allocator::alloc_aligned(size_t size, void **out_addr, int align, addr_t from, addr_t to)
Mapped_mem_allocator::alloc_aligned(size_t size, void **out_addr, int align, addr_t from, addr_t to)
{
size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask();
void *phys_addr = 0;
@ -77,7 +77,7 @@ Core_mem_allocator::Mapped_mem_allocator::alloc_aligned(size_t size, void **out_
}
void Core_mem_allocator::Mapped_mem_allocator::free(void *addr, size_t size)
void Mapped_mem_allocator::free(void *addr, size_t size)
{
using Block = Mapped_avl_allocator::Block;
Block *b = static_cast<Block *>(_virt_alloc->_find_by_address((addr_t)addr));
@ -89,7 +89,7 @@ void Core_mem_allocator::Mapped_mem_allocator::free(void *addr, size_t size)
}
void Core_mem_allocator::Mapped_mem_allocator::free(void *addr)
void Mapped_mem_allocator::free(void *addr)
{
PWRN("Not implemented!");
}

View File

@ -16,13 +16,22 @@
#define _CORE__INCLUDE__CORE_MEM_ALLOC_H_
#include <base/lock.h>
#include <base/sync_allocator.h>
#include <base/allocator_avl.h>
#include <synced_range_allocator.h>
#include <util.h>
namespace Genode {
class Core_mem_translator;
class Core_mem_allocator;
struct Metadata;
class Mapped_mem_allocator;
class Mapped_avl_allocator;
using Page_allocator = Allocator_avl_tpl<Empty, get_page_size()>;
using Phys_allocator = Synced_range_allocator<Page_allocator>;
using Synced_mapped_allocator =
Synced_range_allocator<Mapped_avl_allocator>;
};
@ -50,6 +59,131 @@ class Genode::Core_mem_translator : public Genode::Range_allocator
};
/**
* Metadata for allocator blocks that stores a related address
*/
struct Genode::Metadata { void * map_addr; };
/**
* Page-size granular allocator that links ranges to related ones.
*/
class Genode::Mapped_avl_allocator
: public Genode::Allocator_avl_tpl<Genode::Metadata, Genode::get_page_size()>
{
friend class Mapped_mem_allocator;
public:
/**
* Constructor
*
* \param md_alloc metadata allocator
*/
explicit Mapped_avl_allocator(Allocator *md_alloc)
: Allocator_avl_tpl<Metadata, get_page_size()>(md_alloc) {}
/**
* Returns related address for allocated range
*
* \param addr address within allocated range
*/
void * map_addr(void * addr);
};
/**
* 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 Genode::Mapped_mem_allocator : public Genode::Core_mem_translator
{
private:
Mapped_avl_allocator *_phys_alloc;
Mapped_avl_allocator *_virt_alloc;
public:
/**
* Constructor
*
* \param phys_alloc allocator of physical memory
* \param virt_alloc allocator of core-local virtual memory ranges
*/
Mapped_mem_allocator(Synced_mapped_allocator &phys_alloc,
Synced_mapped_allocator &virt_alloc)
: _phys_alloc(&phys_alloc._alloc), _virt_alloc(&virt_alloc._alloc) { }
/**
* Establish mapping between physical and virtual address range
*
* Note: has to be implemented by platform specific code
*
* \param virt_addr start address of virtual range
* \param phys_addr start address of physical range
* \param size size of range
*/
bool _map_local(addr_t virt_addr, addr_t phys_addr, unsigned size);
/**
* Destroy mapping between physical and virtual address range
*
* Note: has to be implemented by platform specific code
*
* \param virt_addr start address of virtual range
* \param size size of range
*/
bool _unmap_local(addr_t virt_addr, unsigned size);
/***********************************
** Core_mem_translator interface **
***********************************/
void * phys_addr(void * addr) {
return _virt_alloc->map_addr(addr); }
void * virt_addr(void * addr) {
return _phys_alloc->map_addr(addr); }
/*******************************
** Range allocator interface **
*******************************/
int add_range(addr_t base, size_t size) override { return -1; }
int remove_range(addr_t base, size_t size) override { return -1; }
Alloc_return alloc_aligned(size_t size, void **out_addr,
int align = 0, addr_t from = 0,
addr_t to = ~0UL) override;
Alloc_return alloc_addr(size_t size, addr_t addr) override {
return Alloc_return::RANGE_CONFLICT; }
void free(void *addr) override;
size_t avail() const override { return _phys_alloc->avail(); }
bool valid_addr(addr_t addr) const override {
return _virt_alloc->valid_addr(addr); }
/*************************
** Allocator interface **
*************************/
bool alloc(size_t size, void **out_addr) override {
return alloc_aligned(size, out_addr).is_ok(); }
void free(void *addr, size_t) override;
size_t consumed() const override { return _phys_alloc->consumed(); }
size_t overhead(size_t size) const override {
return _phys_alloc->overhead(size); }
bool need_size_for_free() const override {
return _phys_alloc->need_size_for_free(); }
};
/**
* Allocators for physical memory, core's virtual address space,
* and core-local memory. The interface of this class is thread safe.
@ -60,135 +194,6 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator
{
public:
using Page_allocator = Allocator_avl_tpl<Empty, get_page_size()>;
using Phys_allocator = Synchronized_range_allocator<Page_allocator>;
/**
* Metadata for allocator blocks that stores a related address
*/
struct Metadata { void * map_addr; };
class Mapped_mem_allocator;
/**
* Page-size granular allocator that links ranges to related ones.
*/
class Mapped_avl_allocator
: public Allocator_avl_tpl<Metadata, get_page_size()>
{
friend class Mapped_mem_allocator;
public:
/**
* Constructor
*
* \param md_alloc metadata allocator
*/
explicit Mapped_avl_allocator(Allocator *md_alloc)
: Allocator_avl_tpl<Metadata, get_page_size()>(md_alloc) {}
/**
* Returns related address for allocated range
*
* \param addr address within allocated range
*/
void * map_addr(void * addr);
};
using Synchronized_mapped_allocator =
Synchronized_range_allocator<Mapped_avl_allocator>;
/**
* 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 Genode::Core_mem_translator
{
private:
Mapped_avl_allocator *_phys_alloc;
Mapped_avl_allocator *_virt_alloc;
public:
/**
* Constructor
*
* \param phys_alloc allocator of physical memory
* \param virt_alloc allocator of core-local virtual memory ranges
*/
Mapped_mem_allocator(Mapped_avl_allocator *phys_alloc,
Mapped_avl_allocator *virt_alloc)
: _phys_alloc(phys_alloc), _virt_alloc(virt_alloc) { }
/**
* Establish mapping between physical and virtual address range
*
* Note: has to be implemented by platform specific code
*
* \param virt_addr start address of virtual range
* \param phys_addr start address of physical range
* \param size size of range
*/
bool _map_local(addr_t virt_addr, addr_t phys_addr, unsigned size);
/**
* Destroy mapping between physical and virtual address range
*
* Note: has to be implemented by platform specific code
*
* \param virt_addr start address of virtual range
* \param size size of range
*/
bool _unmap_local(addr_t virt_addr, unsigned size);
/***********************************
** Core_mem_translator interface **
***********************************/
void * phys_addr(void * addr) {
return _virt_alloc->map_addr(addr); }
void * virt_addr(void * addr) {
return _phys_alloc->map_addr(addr); }
/*******************************
** Range allocator interface **
*******************************/
int add_range(addr_t base, size_t size) override { return -1; }
int remove_range(addr_t base, size_t size) override { return -1; }
Alloc_return alloc_aligned(size_t size, void **out_addr,
int align = 0, addr_t from = 0,
addr_t to = ~0UL) override;
Alloc_return alloc_addr(size_t size, addr_t addr) override {
return Alloc_return::RANGE_CONFLICT; }
void free(void *addr) override;
size_t avail() const override { return _phys_alloc->avail(); }
bool valid_addr(addr_t addr) const override {
return _virt_alloc->valid_addr(addr); }
/*************************
** Allocator interface **
*************************/
bool alloc(size_t size, void **out_addr) override {
return alloc_aligned(size, out_addr).is_ok(); }
void free(void *addr, size_t) override;
size_t consumed() const override { return _phys_alloc->consumed(); }
size_t overhead(size_t size) const override {
return _phys_alloc->overhead(size); }
bool need_size_for_free() const override {
return _phys_alloc->need_size_for_free(); }
};
protected:
@ -204,7 +209,7 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator
* This allocator must only be used to allocate memory
* ranges at page granularity.
*/
Synchronized_mapped_allocator _phys_alloc;
Synced_mapped_allocator _phys_alloc;
/**
* Synchronized allocator of core's virtual memory ranges
@ -212,7 +217,7 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator
* This allocator must only be used to allocate memory
* ranges at page granularity.
*/
Synchronized_mapped_allocator _virt_alloc;
Synced_mapped_allocator _virt_alloc;
/**
* Unsynchronized core-mapped memory allocator
@ -233,24 +238,19 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator
* Constructor
*/
Core_mem_allocator()
: _phys_alloc(&_lock, &_mem_alloc),
_virt_alloc(&_lock, &_mem_alloc),
_mem_alloc(_phys_alloc.raw(), _virt_alloc.raw()) { }
: _phys_alloc(_lock, &_mem_alloc),
_virt_alloc(_lock, &_mem_alloc),
_mem_alloc(_phys_alloc, _virt_alloc) { }
/**
* Access physical-memory allocator
*/
Synchronized_mapped_allocator *phys_alloc() { return &_phys_alloc; }
Synced_mapped_allocator *phys_alloc() { return &_phys_alloc; }
/**
* Access core's virtual-memory allocator
*/
Synchronized_mapped_allocator *virt_alloc() { return &_virt_alloc; }
/**
* Access core's local memory allocator unsynchronized
*/
Mapped_mem_allocator *raw() { return &_mem_alloc; }
Synced_mapped_allocator *virt_alloc() { return &_virt_alloc; }
/***********************************
@ -259,14 +259,12 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator
void * phys_addr(void * addr)
{
Lock::Guard lock_guard(_lock);
return _virt_alloc.raw()->map_addr(addr);
return _virt_alloc()->map_addr(addr);
}
void * virt_addr(void * addr)
{
Lock::Guard lock_guard(_lock);
return _phys_alloc.raw()->map_addr(addr);
return _phys_alloc()->map_addr(addr);
}

View File

@ -19,7 +19,7 @@
#include <base/tslab.h>
#include <base/rpc_server.h>
#include <base/allocator_guard.h>
#include <base/sync_allocator.h>
#include <base/synced_allocator.h>
/* core includes */
#include <dataspace_component.h>
@ -40,8 +40,7 @@ namespace Genode {
static constexpr size_t SBS = get_page_size();
using Ds_slab = Synchronized_allocator<Tslab<Dataspace_component,
SBS> >;
using Ds_slab = Synced_allocator<Tslab<Dataspace_component, SBS> >;
Rpc_entrypoint *_ds_ep;
Rpc_entrypoint *_ram_session_ep;

View File

@ -22,7 +22,7 @@
#include <pager.h>
#include <base/allocator_avl.h>
#include <base/allocator_guard.h>
#include <base/sync_allocator.h>
#include <base/synced_allocator.h>
#include <base/signal.h>
#include <base/rpc_server.h>
#include <util/list.h>
@ -263,7 +263,7 @@ namespace Genode {
};
typedef Synchronized_allocator<Tslab<Rm_client, 1024> > Client_slab_alloc;
typedef Synced_allocator<Tslab<Rm_client, 1024> > Client_slab_alloc;
Client_slab_alloc _client_slab; /* backing store for
client structures, synchronized */
Tslab<Rm_region_ref, 1024> _ref_slab; /* backing store for

View File

@ -0,0 +1,111 @@
/*
* \brief Lock-guarded allocator interface
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2008-08-05
*/
/*
* Copyright (C) 2008-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _SRC__CORE__INCLUDE__SYNCED_RANGE_ALLOCATOR_H_
#define _SRC__CORE__INCLUDE__SYNCED_RANGE_ALLOCATOR_H_
#include <base/allocator.h>
#include <base/synced_interface.h>
namespace Genode {
class Mapped_mem_allocator;
template <typename> class Synced_range_allocator;
}
/**
* Lock-guarded range allocator
*
* This class wraps the complete 'Range_allocator' interface while
* preventing concurrent calls to the wrapped allocator implementation.
*
* \param ALLOC class implementing the 'Range_allocator' interface
*/
template <typename ALLOC>
class Genode::Synced_range_allocator : public Range_allocator
{
private:
friend class Mapped_mem_allocator;
Lock _default_lock;
Lock &_lock;
ALLOC _alloc;
Synced_interface<ALLOC, Lock> _synced_object;
public:
using Guard = typename Synced_interface<ALLOC, Lock>::Guard;
template <typename... ARGS>
Synced_range_allocator(Lock &lock, ARGS &&... args)
: _lock(lock), _alloc(args...), _synced_object(_lock, &_alloc) { }
template <typename... ARGS>
Synced_range_allocator(ARGS &&... args)
: _lock(_default_lock), _alloc(args...),
_synced_object(_lock, &_alloc) { }
Guard operator () () { return _synced_object(); }
Guard operator () () const { return _synced_object(); }
/*************************
** Allocator interface **
*************************/
bool alloc(size_t size, void **out_addr) override {
return _synced_object()->alloc(size, out_addr); }
void free(void *addr, size_t size) override {
_synced_object()->free(addr, size); }
size_t consumed() const override {
return _synced_object()->consumed(); }
size_t overhead(size_t size) const override {
return _synced_object()->overhead(size); }
bool need_size_for_free() const override {
return _synced_object()->need_size_for_free(); }
/*******************************
** Range-allocator interface **
*******************************/
int add_range(addr_t base, size_t size) override {
return _synced_object()->add_range(base, size); }
int remove_range(addr_t base, size_t size) override {
return _synced_object()->remove_range(base, size); }
Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0,
addr_t from = 0, addr_t to = ~0UL) override {
return _synced_object()->alloc_aligned(size, out_addr, align, from, to); }
Alloc_return alloc_addr(size_t size, addr_t addr) override {
return _synced_object()->alloc_addr(size, addr); }
void free(void *addr) override {
_synced_object()->free(addr); }
size_t avail() const override {
return _synced_object()->avail(); }
bool valid_addr(addr_t addr) const override {
return _synced_object()->valid_addr(addr); }
};
#endif /* _SRC__CORE__INCLUDE__SYNCED_RANGE_ALLOCATOR_H_ */

View File

@ -291,7 +291,7 @@ Ram_session_component::Ram_session_component(Rpc_entrypoint *ds_ep,
Ram_session_component::~Ram_session_component()
{
/* destroy all dataspaces */
for (Dataspace_component *ds; (ds = _ds_slab.raw()->first_object()); _free_ds(ds));
for (Dataspace_component *ds; (ds = _ds_slab()->first_object()); _free_ds(ds));
if (_payload != 0)
PWRN("Remaining payload of %zu in ram session to destroy", _payload);

View File

@ -754,7 +754,7 @@ Rm_session_component::~Rm_session_component()
faulter->dissolve_from_faulting_rm_session(this);
/* remove all clients, invalidate rm_client pointers in cpu_thread objects */
while (Rm_client *cl = _client_slab.raw()->first_object()) {
while (Rm_client *cl = _client_slab()->first_object()) {
cl->dissolve_from_faulting_rm_session(this);
Thread_capability thread_cap = cl->thread_cap();

View File

@ -12,7 +12,7 @@
*/
/* Genode includes */
#include <os/synced_interface.h>
#include <base/synced_interface.h>
#include <base/printf.h>

View File

@ -28,7 +28,7 @@
#include <base/thread.h>
#include <block_session/connection.h>
#include <util/string.h>
#include <base/sync_allocator.h>
#include <base/synced_allocator.h>
/* local includes */
#include "synced_motherboard.h"
@ -100,17 +100,17 @@ class Vancouver_disk : public Genode::Thread<8192>, public StaticReceiver<Vancou
/* slabs for temporary holding DMADescriptor and MessageDisk objects */
typedef Genode::Tslab<MessageDisk, 128> MessageDisk_Slab;
typedef Genode::Synchronized_allocator<MessageDisk_Slab> MessageDisk_Slab_Sync;
typedef Genode::Synced_allocator<MessageDisk_Slab> MessageDisk_Slab_Sync;
typedef Genode::Tslab<DmaDescriptor, 256> DmaDesc_Slab;
typedef Genode::Synchronized_allocator<DmaDesc_Slab> DmaDesc_Slab_Sync;
typedef Genode::Synced_allocator<DmaDesc_Slab> DmaDesc_Slab_Sync;
MessageDisk_Slab_Sync _tslab_msg;
DmaDesc_Slab_Sync _tslab_dma;
/* Structure to find back the MessageDisk object out of a Block Ack */
typedef Genode::Tslab<Avl_entry, 128> Avl_entry_slab;
typedef Genode::Synchronized_allocator<Avl_entry_slab> Avl_entry_slab_sync;
typedef Genode::Synced_allocator<Avl_entry_slab> Avl_entry_slab_sync;
Avl_entry_slab_sync _tslab_avl;

View File

@ -44,7 +44,7 @@
#include <nic/packet_allocator.h>
#include <os/config.h>
#include <os/alarm.h>
#include <os/synced_interface.h>
#include <base/synced_interface.h>
#include <timer_session/connection.h>
#include <rtc_session/connection.h>

View File

@ -15,7 +15,7 @@
#define _SYNCED_MOTHERBOARD_H_
#include <nul/motherboard.h>
#include <os/synced_interface.h>
#include <base/synced_interface.h>
typedef Genode::Synced_interface<Motherboard> Synced_motherboard;