mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
parent
db5969e6cc
commit
fbc35cb796
@ -56,7 +56,7 @@ class Genode::Rpc_cap_factory
|
|||||||
|
|
||||||
Rpc_cap_factory(Allocator &md_alloc)
|
Rpc_cap_factory(Allocator &md_alloc)
|
||||||
:
|
:
|
||||||
_slab(&md_alloc, (Slab_block*)&_initial_slab_block)
|
_slab(&md_alloc, &_initial_slab_block)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Rpc_cap_factory()
|
~Rpc_cap_factory()
|
||||||
|
@ -38,8 +38,7 @@ class Genode::Signal_broker
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Slab(Allocator * const allocator)
|
Slab(Allocator * const allocator)
|
||||||
: Tslab<T, BLOCK_SIZE>(allocator,
|
: Tslab<T, BLOCK_SIZE>(allocator, &_first_block) { }
|
||||||
(Slab_block*)&_first_block) { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Allocator &_md_alloc;
|
Allocator &_md_alloc;
|
||||||
|
@ -30,6 +30,12 @@
|
|||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
|
|
||||||
|
static inline void free_obj_id_ref(Pd *pd, void *ptr)
|
||||||
|
{
|
||||||
|
pd->platform_pd()->capability_slab().free(ptr, sizeof(Object_identity_reference));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ipc_node::copy_msg(Ipc_node * const sender)
|
void Ipc_node::copy_msg(Ipc_node * const sender)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
@ -46,7 +52,7 @@ void Ipc_node::copy_msg(Ipc_node * const sender)
|
|||||||
|
|
||||||
/* if there is no capability to send, just free the pre-allocation */
|
/* if there is no capability to send, just free the pre-allocation */
|
||||||
if (i >= sender->_utcb->cap_cnt()) {
|
if (i >= sender->_utcb->cap_cnt()) {
|
||||||
pd()->platform_pd()->capability_slab().free(_obj_id_ref_ptr[i]);
|
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +63,7 @@ void Ipc_node::copy_msg(Ipc_node * const sender)
|
|||||||
/* if the caller's capability is invalid, free the pre-allocation */
|
/* if the caller's capability is invalid, free the pre-allocation */
|
||||||
if (!oir) {
|
if (!oir) {
|
||||||
_utcb->cap_add(cap_id_invalid());
|
_utcb->cap_add(cap_id_invalid());
|
||||||
pd()->platform_pd()->capability_slab().free(_obj_id_ref_ptr[i]);
|
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,9 +74,9 @@ void Ipc_node::copy_msg(Ipc_node * const sender)
|
|||||||
if (!dst_oir && (pd() != core_pd())) {
|
if (!dst_oir && (pd() != core_pd())) {
|
||||||
dst_oir = oir->factory(_obj_id_ref_ptr[i], *pd());
|
dst_oir = oir->factory(_obj_id_ref_ptr[i], *pd());
|
||||||
if (!dst_oir)
|
if (!dst_oir)
|
||||||
pd()->platform_pd()->capability_slab().free(_obj_id_ref_ptr[i]);
|
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||||
} else /* otherwise free the pre-allocation */
|
} else /* otherwise free the pre-allocation */
|
||||||
pd()->platform_pd()->capability_slab().free(_obj_id_ref_ptr[i]);
|
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||||
|
|
||||||
if (dst_oir) dst_oir->add_to_utcb();
|
if (dst_oir) dst_oir->add_to_utcb();
|
||||||
|
|
||||||
|
@ -108,13 +108,13 @@ Hw::Address_space::~Address_space()
|
|||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
Capability_space::Capability_space()
|
Capability_space::Capability_space()
|
||||||
: _slab(nullptr, (Slab_block*)&_initial_sb) { }
|
: _slab(nullptr, &_initial_sb) { }
|
||||||
|
|
||||||
|
|
||||||
void Capability_space::upgrade_slab(Allocator &alloc)
|
void Capability_space::upgrade_slab(Allocator &alloc)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Slab_block * block;
|
void *block = nullptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On every upgrade we try allocating as many blocks as possible.
|
* On every upgrade we try allocating as many blocks as possible.
|
||||||
@ -122,7 +122,6 @@ void Capability_space::upgrade_slab(Allocator &alloc)
|
|||||||
* this is normal as we use it as indication when to exit the loop.
|
* this is normal as we use it as indication when to exit the loop.
|
||||||
*/
|
*/
|
||||||
if (!alloc.alloc(SLAB_SIZE, &block)) return;
|
if (!alloc.alloc(SLAB_SIZE, &block)) return;
|
||||||
block = construct_at<Slab_block>(block, &_slab);
|
|
||||||
_slab.insert_sb(block);
|
_slab.insert_sb(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,148 +17,14 @@
|
|||||||
#include <base/allocator.h>
|
#include <base/allocator.h>
|
||||||
#include <base/stdint.h>
|
#include <base/stdint.h>
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode { class Slab; }
|
||||||
|
|
||||||
class Slab;
|
|
||||||
class Slab_block;
|
|
||||||
class Slab_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A slab block holds an array of slab entries.
|
* Transitional type definition, for API compatibility only
|
||||||
|
*
|
||||||
|
* \deprecated To be removed once all Slab users are updated.
|
||||||
*/
|
*/
|
||||||
class Genode::Slab_block
|
namespace Genode { typedef void Slab_block; }
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
Slab_block *next; /* next block */
|
|
||||||
Slab_block *prev; /* previous block */
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
enum { FREE, USED };
|
|
||||||
|
|
||||||
Slab *_slab; /* back reference to slab allocator */
|
|
||||||
size_t _avail; /* free entries of this block */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Each slab block consists of three areas, a fixed-size header
|
|
||||||
* that contains the member variables declared above, a byte array
|
|
||||||
* called state table that holds the allocation state for each slab
|
|
||||||
* entry, and an area holding the actual slab entries. The number
|
|
||||||
* of state-table elements corresponds to the maximum number of slab
|
|
||||||
* entries per slab block (the '_num_elem' member variable of the
|
|
||||||
* Slab allocator).
|
|
||||||
*/
|
|
||||||
|
|
||||||
char _data[]; /* dynamic data (state table and slab entries) */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Caution! no member variables allowed below this line!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the allocation state of a slab entry
|
|
||||||
*/
|
|
||||||
inline bool state(int idx) { return _data[idx]; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the allocation state of a slab entry
|
|
||||||
*/
|
|
||||||
inline void state(int idx, bool state) { _data[idx] = state; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request address of slab entry by its index
|
|
||||||
*/
|
|
||||||
Slab_entry *slab_entry(int idx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine block index of specified slab entry
|
|
||||||
*/
|
|
||||||
int slab_entry_idx(Slab_entry *e);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* Normally, Slab_blocks are constructed by a Slab allocator
|
|
||||||
* that specifies itself as constructor argument.
|
|
||||||
*/
|
|
||||||
explicit Slab_block(Slab *s = 0) { if (s) slab(s); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure block to be managed by the specified slab allocator
|
|
||||||
*/
|
|
||||||
void slab(Slab *slab);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request number of available entries in block
|
|
||||||
*/
|
|
||||||
unsigned avail() const { return _avail; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate slab entry from block
|
|
||||||
*/
|
|
||||||
void *alloc();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a used slab block entry
|
|
||||||
*/
|
|
||||||
Slab_entry *first_used_entry();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* These functions are called by Slab_entry.
|
|
||||||
*/
|
|
||||||
void inc_avail(Slab_entry *e);
|
|
||||||
void dec_avail();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debug and test hooks
|
|
||||||
*/
|
|
||||||
void dump();
|
|
||||||
int check_bounds();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Genode::Slab_entry
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
Slab_block *_sb;
|
|
||||||
char _data[];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Caution! no member variables allowed below this line!
|
|
||||||
*/
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void init() { _sb = 0; }
|
|
||||||
|
|
||||||
void occupy(Slab_block *sb)
|
|
||||||
{
|
|
||||||
_sb = sb;
|
|
||||||
_sb->dec_avail();
|
|
||||||
}
|
|
||||||
|
|
||||||
void free()
|
|
||||||
{
|
|
||||||
_sb->inc_avail(this);
|
|
||||||
_sb = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *addr() { return _data; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lookup Slab_entry by given address
|
|
||||||
*
|
|
||||||
* The specified address is supposed to point to _data[0].
|
|
||||||
*/
|
|
||||||
static Slab_entry *slab_entry(void *addr) {
|
|
||||||
return (Slab_entry *)((addr_t)addr - sizeof(Slab_entry)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,27 +34,55 @@ class Genode::Slab : public Allocator
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
size_t _slab_size; /* size of one slab entry */
|
struct Block;
|
||||||
size_t _block_size; /* size of slab block */
|
struct Entry;
|
||||||
size_t _num_elem; /* number of slab entries per block */
|
|
||||||
Slab_block *_first_sb; /* first slab block */
|
|
||||||
Slab_block *_initial_sb; /* initial (static) slab block */
|
|
||||||
bool _alloc_state; /* indicator for 'currently in service' */
|
|
||||||
|
|
||||||
Allocator *_backing_store;
|
size_t const _slab_size; /* size of one slab entry */
|
||||||
|
size_t const _block_size; /* size of slab block */
|
||||||
|
size_t const _entries_per_block; /* number of slab entries per block */
|
||||||
|
|
||||||
|
Block *_first_sb; /* first slab block */
|
||||||
|
Block *_initial_sb; /* initial (static) slab block */
|
||||||
|
bool _alloc_state; /* indicator for 'currently in service' */
|
||||||
|
|
||||||
|
Allocator *_backing_store;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate and initialize new slab block
|
* Allocate and initialize new slab block
|
||||||
*/
|
*/
|
||||||
Slab_block *_new_slab_block();
|
Block *_new_slab_block();
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************
|
||||||
|
** Methods used by 'Block' **
|
||||||
|
*****************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove block from slab block list
|
||||||
|
*
|
||||||
|
* \noapi
|
||||||
|
*/
|
||||||
|
void _remove_sb(Block *sb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert block into slab block list
|
||||||
|
*
|
||||||
|
* \noapi
|
||||||
|
*/
|
||||||
|
void _insert_sb(Block *sb, Block *at = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free slab entry
|
||||||
|
*/
|
||||||
|
void _free(void *addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if number of free slab entries is higher than n
|
||||||
|
*/
|
||||||
|
bool _num_free_entries_higher_than(int n);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline size_t slab_size() const { return _slab_size; }
|
|
||||||
inline size_t block_size() const { return _block_size; }
|
|
||||||
inline size_t num_elem() const { return _num_elem; }
|
|
||||||
inline size_t entry_size() const { return sizeof(Slab_entry) + _slab_size; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@ -197,7 +91,7 @@ class Genode::Slab : public Allocator
|
|||||||
* especially for the allocation of the second slab
|
* especially for the allocation of the second slab
|
||||||
* block.
|
* block.
|
||||||
*/
|
*/
|
||||||
Slab(size_t slab_size, size_t block_size, Slab_block *initial_sb,
|
Slab(size_t slab_size, size_t block_size, void *initial_sb,
|
||||||
Allocator *backing_store = 0);
|
Allocator *backing_store = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,40 +100,17 @@ class Genode::Slab : public Allocator
|
|||||||
~Slab();
|
~Slab();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug function for dumping the current slab block list
|
* Add new slab block as backing store
|
||||||
*
|
*
|
||||||
* \noapi
|
* The specified 'ptr' has to point to a buffer with the size of one
|
||||||
|
* slab block.
|
||||||
*/
|
*/
|
||||||
void dump_sb_list();
|
void insert_sb(void *ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove block from slab block list
|
* Return a used slab element, or nullptr if empty
|
||||||
*
|
|
||||||
* \noapi
|
|
||||||
*/
|
*/
|
||||||
void remove_sb(Slab_block *sb);
|
void *any_used_elem();
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert block into slab block list
|
|
||||||
*
|
|
||||||
* \noapi
|
|
||||||
*/
|
|
||||||
void insert_sb(Slab_block *sb, Slab_block *at = 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Free slab entry
|
|
||||||
*/
|
|
||||||
static void free(void *addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a used slab element
|
|
||||||
*/
|
|
||||||
void *first_used_elem();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if number of free slab entries is higher than n
|
|
||||||
*/
|
|
||||||
bool num_free_entries_higher_than(int n);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define/request backing-store allocator
|
* Define/request backing-store allocator
|
||||||
@ -255,6 +126,7 @@ class Genode::Slab : public Allocator
|
|||||||
*/
|
*/
|
||||||
Allocator *backing_store() { return _backing_store; }
|
Allocator *backing_store() { return _backing_store; }
|
||||||
|
|
||||||
|
|
||||||
/*************************
|
/*************************
|
||||||
** Allocator interface **
|
** Allocator interface **
|
||||||
*************************/
|
*************************/
|
||||||
@ -266,9 +138,9 @@ class Genode::Slab : public Allocator
|
|||||||
* preconfigured slab-entry size are allocated.
|
* preconfigured slab-entry size are allocated.
|
||||||
*/
|
*/
|
||||||
bool alloc(size_t size, void **addr) override;
|
bool alloc(size_t size, void **addr) override;
|
||||||
void free(void *addr, size_t) override { free(addr); }
|
void free(void *addr, size_t) override { _free(addr); }
|
||||||
size_t consumed() const override;
|
size_t consumed() const override;
|
||||||
size_t overhead(size_t) const override { return _block_size/_num_elem; }
|
size_t overhead(size_t) const override { return _block_size/_entries_per_block; }
|
||||||
bool need_size_for_free() const override { return false; }
|
bool need_size_for_free() const override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,12 +22,11 @@ namespace Genode { template <typename, size_t> struct Tslab; }
|
|||||||
template <typename T, Genode::size_t BLOCK_SIZE>
|
template <typename T, Genode::size_t BLOCK_SIZE>
|
||||||
struct Genode::Tslab : Slab
|
struct Genode::Tslab : Slab
|
||||||
{
|
{
|
||||||
Tslab(Allocator *backing_store,
|
Tslab(Allocator *backing_store, void *initial_sb = 0)
|
||||||
Slab_block *initial_sb = 0)
|
|
||||||
: Slab(sizeof(T), BLOCK_SIZE, initial_sb, backing_store)
|
: Slab(sizeof(T), BLOCK_SIZE, initial_sb, backing_store)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
T *first_object() { return (T *)Slab::first_used_elem(); }
|
T *first_object() { return (T *)Slab::any_used_elem(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__BASE__TSLAB_H_ */
|
#endif /* _INCLUDE__BASE__TSLAB_H_ */
|
||||||
|
@ -5,88 +5,200 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
* Copyright (C) 2006-2016 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <base/slab.h>
|
#include <base/slab.h>
|
||||||
|
#include <util/construct_at.h>
|
||||||
#include <util/misc_math.h>
|
#include <util/misc_math.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slab block holds an array of slab entries.
|
||||||
|
*/
|
||||||
|
class Genode::Slab::Block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Block *next = nullptr; /* next block */
|
||||||
|
Block *prev = nullptr; /* previous block */
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum { FREE, USED };
|
||||||
|
|
||||||
|
Slab &_slab; /* back reference to slab */
|
||||||
|
size_t _avail = _slab._entries_per_block; /* free entries of this block */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each slab block consists of three areas, a fixed-size header
|
||||||
|
* that contains the member variables declared above, a byte array
|
||||||
|
* called state table that holds the allocation state for each slab
|
||||||
|
* entry, and an area holding the actual slab entries. The number
|
||||||
|
* of state-table elements corresponds to the maximum number of slab
|
||||||
|
* entries per slab block (the '_entries_per_block' member variable of
|
||||||
|
* the Slab allocator).
|
||||||
|
*/
|
||||||
|
|
||||||
|
char _data[]; /* dynamic data (state table and slab entries) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Caution! no member variables allowed below this line!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the allocation state of a slab entry
|
||||||
|
*/
|
||||||
|
inline bool _state(int idx) { return _data[idx]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the allocation state of a slab entry
|
||||||
|
*/
|
||||||
|
inline void _state(int idx, bool state) { _data[idx] = state; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request address of slab entry by its index
|
||||||
|
*/
|
||||||
|
Entry *_slab_entry(int idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine block index of specified slab entry
|
||||||
|
*/
|
||||||
|
int _slab_entry_idx(Entry *e);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
explicit Block(Slab &slab) : _slab(slab)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < _avail; i++)
|
||||||
|
_state(i, FREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request number of available entries in block
|
||||||
|
*/
|
||||||
|
unsigned avail() const { return _avail; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate slab entry from block
|
||||||
|
*/
|
||||||
|
void *alloc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a used slab block entry
|
||||||
|
*/
|
||||||
|
Entry *any_used_entry();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These functions are called by Slab::Entry.
|
||||||
|
*/
|
||||||
|
void inc_avail(Entry &e);
|
||||||
|
void dec_avail();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug and test hooks
|
||||||
|
*/
|
||||||
|
void dump();
|
||||||
|
int check_bounds();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Genode::Slab::Entry
|
||||||
|
{
|
||||||
|
Block █
|
||||||
|
char data[];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Caution! no member variables allowed below this line!
|
||||||
|
*/
|
||||||
|
|
||||||
|
explicit Entry(Block &block) : block(block)
|
||||||
|
{
|
||||||
|
block.dec_avail();
|
||||||
|
}
|
||||||
|
|
||||||
|
~Entry()
|
||||||
|
{
|
||||||
|
block.inc_avail(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup Entry by given address
|
||||||
|
*
|
||||||
|
* The specified address is supposed to point to _data[0].
|
||||||
|
*/
|
||||||
|
static Entry *slab_entry(void *addr) {
|
||||||
|
return (Entry *)((addr_t)addr - sizeof(Entry)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
** Slab block **
|
** Slab block **
|
||||||
****************/
|
****************/
|
||||||
|
|
||||||
/**
|
Slab::Entry *Slab::Block::_slab_entry(int idx)
|
||||||
* Placement operator - tool for directly calling a constructor
|
|
||||||
*/
|
|
||||||
inline void *operator new(size_t, void *at) { return at; }
|
|
||||||
|
|
||||||
|
|
||||||
void Slab_block::slab(Slab *slab)
|
|
||||||
{
|
|
||||||
_slab = slab;
|
|
||||||
_avail = _slab->num_elem();
|
|
||||||
next = prev = 0;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < _avail; i++)
|
|
||||||
state(i, FREE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Slab_entry *Slab_block::slab_entry(int idx)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The slab slots start after the state array that consists
|
* The slab slots start after the state array that consists
|
||||||
* of 'num_elem' bytes. We align the first slot to a four-aligned
|
* of 'num_elem' bytes. We align the first slot to a four-aligned
|
||||||
* address.
|
* address.
|
||||||
*/
|
*/
|
||||||
return (Slab_entry *)&_data[align_addr(_slab->num_elem(), log2(sizeof(addr_t)))
|
|
||||||
+ _slab->entry_size()*idx];
|
size_t const entry_size = sizeof(Entry) + _slab._slab_size;
|
||||||
|
return (Entry *)&_data[align_addr(_slab._entries_per_block, log2(sizeof(addr_t)))
|
||||||
|
+ entry_size*idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Slab_block::slab_entry_idx(Slab_entry *e) {
|
int Slab::Block::_slab_entry_idx(Slab::Entry *e)
|
||||||
return ((addr_t)e - (addr_t)slab_entry(0))/_slab->entry_size(); }
|
|
||||||
|
|
||||||
|
|
||||||
void *Slab_block::alloc()
|
|
||||||
{
|
{
|
||||||
size_t num_elem = _slab->num_elem();
|
size_t const entry_size = sizeof(Entry) + _slab._slab_size;
|
||||||
for (unsigned i = 0; i < num_elem; i++)
|
return ((addr_t)e - (addr_t)_slab_entry(0))/entry_size;
|
||||||
if (state(i) == FREE) {
|
|
||||||
state(i, USED);
|
|
||||||
Slab_entry *e = slab_entry(i);
|
|
||||||
e->occupy(this);
|
|
||||||
return e->addr();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Slab_entry *Slab_block::first_used_entry()
|
void *Slab::Block::alloc()
|
||||||
{
|
{
|
||||||
size_t num_elem = _slab->num_elem();
|
for (unsigned i = 0; i < _slab._entries_per_block; i++) {
|
||||||
for (unsigned i = 0; i < num_elem; i++)
|
if (_state(i) != FREE)
|
||||||
if (state(i) == USED)
|
continue;
|
||||||
return slab_entry(i);
|
|
||||||
return 0;
|
_state(i, USED);
|
||||||
|
Entry * const e = _slab_entry(i);
|
||||||
|
construct_at<Entry>(e, *this);
|
||||||
|
return e->data;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Slab_block::inc_avail(Slab_entry *e)
|
Slab::Entry *Slab::Block::any_used_entry()
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < _slab._entries_per_block; i++)
|
||||||
|
if (_state(i) == USED)
|
||||||
|
return _slab_entry(i);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Slab::Block::inc_avail(Entry &e)
|
||||||
{
|
{
|
||||||
/* mark slab entry as free */
|
/* mark slab entry as free */
|
||||||
int idx = slab_entry_idx(e);
|
int const idx = _slab_entry_idx(&e);
|
||||||
state(idx, FREE);
|
_state(idx, FREE);
|
||||||
_avail++;
|
_avail++;
|
||||||
|
|
||||||
/* search previous block with higher avail value than this' */
|
/* search previous block with higher avail value than this' */
|
||||||
Slab_block *at = prev;
|
Block *at = prev;
|
||||||
|
|
||||||
while (at && (at->avail() < _avail))
|
while (at && (at->avail() < _avail))
|
||||||
at = at->prev;
|
at = at->prev;
|
||||||
@ -95,29 +207,29 @@ void Slab_block::inc_avail(Slab_entry *e)
|
|||||||
* If we already are the first block or our avail value is lower than the
|
* If we already are the first block or our avail value is lower than the
|
||||||
* previous block, do not reposition the block in the list.
|
* previous block, do not reposition the block in the list.
|
||||||
*/
|
*/
|
||||||
if (prev == 0 || at == prev)
|
if (prev == nullptr || at == prev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* reposition block in list after block with higher avail value */
|
/* reposition block in list after block with higher avail value */
|
||||||
_slab->remove_sb(this);
|
_slab._remove_sb(this);
|
||||||
_slab->insert_sb(this, at);
|
_slab._insert_sb(this, at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Slab_block::dec_avail()
|
void Slab::Block::dec_avail()
|
||||||
{
|
{
|
||||||
_avail--;
|
_avail--;
|
||||||
|
|
||||||
/* search subsequent block with lower avail value than this' */
|
/* search subsequent block with lower avail value than this' */
|
||||||
Slab_block *at = this;
|
Block *at = this;
|
||||||
|
|
||||||
while (at->next && at->next->avail() > _avail)
|
while (at->next && at->next->avail() > _avail)
|
||||||
at = at->next;
|
at = at->next;
|
||||||
|
|
||||||
if (at == this) return;
|
if (at == this) return;
|
||||||
|
|
||||||
_slab->remove_sb(this);
|
_slab._remove_sb(this);
|
||||||
_slab->insert_sb(this, at);
|
_slab._insert_sb(this, at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -125,31 +237,33 @@ void Slab_block::dec_avail()
|
|||||||
** Slab **
|
** Slab **
|
||||||
**********/
|
**********/
|
||||||
|
|
||||||
Slab::Slab(size_t slab_size, size_t block_size, Slab_block *initial_sb,
|
Slab::Slab(size_t slab_size, size_t block_size, void *initial_sb,
|
||||||
Allocator *backing_store)
|
Allocator *backing_store)
|
||||||
: _slab_size(slab_size),
|
:
|
||||||
_block_size(block_size),
|
_slab_size(slab_size),
|
||||||
_first_sb(initial_sb),
|
_block_size(block_size),
|
||||||
_initial_sb(initial_sb),
|
|
||||||
_alloc_state(false),
|
|
||||||
_backing_store(backing_store)
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Calculate number of entries per slab block.
|
* Calculate number of entries per slab block.
|
||||||
*
|
*
|
||||||
* The 'sizeof(umword_t)' is for the alignment of the first slab entry.
|
* The 'sizeof(umword_t)' is for the alignment of the first slab entry.
|
||||||
* The 1 is for one byte state entry.
|
* The 1 is for one byte state entry.
|
||||||
*/
|
*/
|
||||||
_num_elem = (_block_size - sizeof(Slab_block) - sizeof(umword_t))
|
_entries_per_block((_block_size - sizeof(Block) - sizeof(umword_t))
|
||||||
/ (entry_size() + 1);
|
/ (_slab_size + sizeof(Entry) + 1)),
|
||||||
|
|
||||||
|
_first_sb((Block *)initial_sb),
|
||||||
|
_initial_sb(_first_sb),
|
||||||
|
_alloc_state(false),
|
||||||
|
_backing_store(backing_store)
|
||||||
|
{
|
||||||
/* if no initial slab block was specified, try to get one */
|
/* if no initial slab block was specified, try to get one */
|
||||||
if (!_first_sb && _backing_store)
|
if (!_first_sb && _backing_store)
|
||||||
_first_sb = _new_slab_block();
|
_first_sb = _new_slab_block();
|
||||||
|
|
||||||
/* init first slab block */
|
/* init first slab block */
|
||||||
if (_first_sb)
|
if (_first_sb)
|
||||||
_first_sb->slab(this);
|
construct_at<Block>(_first_sb, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -157,8 +271,8 @@ Slab::~Slab()
|
|||||||
{
|
{
|
||||||
/* free backing store */
|
/* free backing store */
|
||||||
while (_first_sb) {
|
while (_first_sb) {
|
||||||
Slab_block *sb = _first_sb;
|
Block * const sb = _first_sb;
|
||||||
remove_sb(_first_sb);
|
_remove_sb(_first_sb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only free slab blocks that we allocated. This is not the case for
|
* Only free slab blocks that we allocated. This is not the case for
|
||||||
@ -170,21 +284,20 @@ Slab::~Slab()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Slab_block *Slab::_new_slab_block()
|
Slab::Block *Slab::_new_slab_block()
|
||||||
{
|
{
|
||||||
void *sb = 0;
|
void *sb = nullptr;
|
||||||
if (!_backing_store || !_backing_store->alloc(_block_size, &sb))
|
if (!_backing_store || !_backing_store->alloc(_block_size, &sb))
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
/* call constructor by using the placement new operator */
|
return construct_at<Block>(sb, *this);
|
||||||
return new(sb) Slab_block(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Slab::remove_sb(Slab_block *sb)
|
void Slab::_remove_sb(Block *sb)
|
||||||
{
|
{
|
||||||
Slab_block *prev = sb->prev;
|
Block *prev = sb->prev;
|
||||||
Slab_block *next = sb->next;
|
Block *next = sb->next;
|
||||||
|
|
||||||
if (prev) prev->next = next;
|
if (prev) prev->next = next;
|
||||||
if (next) next->prev = prev;
|
if (next) next->prev = prev;
|
||||||
@ -192,14 +305,14 @@ void Slab::remove_sb(Slab_block *sb)
|
|||||||
if (_first_sb == sb)
|
if (_first_sb == sb)
|
||||||
_first_sb = next;
|
_first_sb = next;
|
||||||
|
|
||||||
sb->prev = sb->next = 0;
|
sb->prev = sb->next = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Slab::insert_sb(Slab_block *sb, Slab_block *at)
|
void Slab::_insert_sb(Block *sb, Block *at)
|
||||||
{
|
{
|
||||||
/* determine next-pointer where to assign the current sb */
|
/* determine next-pointer where to assign the current sb */
|
||||||
Slab_block **nextptr_to_sb = at ? &at->next : &_first_sb;
|
Block **nextptr_to_sb = at ? &at->next : &_first_sb;
|
||||||
|
|
||||||
/* insert current sb */
|
/* insert current sb */
|
||||||
sb->next = *nextptr_to_sb;
|
sb->next = *nextptr_to_sb;
|
||||||
@ -213,11 +326,11 @@ void Slab::insert_sb(Slab_block *sb, Slab_block *at)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Slab::num_free_entries_higher_than(int n)
|
bool Slab::_num_free_entries_higher_than(int n)
|
||||||
{
|
{
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
for (Slab_block *b = _first_sb; b && b->avail() > 0; b = b->next) {
|
for (Block *b = _first_sb; b && b->avail() > 0; b = b->next) {
|
||||||
cnt += b->avail();
|
cnt += b->avail();
|
||||||
if (cnt > n)
|
if (cnt > n)
|
||||||
return true;
|
return true;
|
||||||
@ -226,6 +339,12 @@ bool Slab::num_free_entries_higher_than(int n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Slab::insert_sb(void *ptr)
|
||||||
|
{
|
||||||
|
_insert_sb(construct_at<Block>(ptr, *this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Slab::alloc(size_t size, void **out_addr)
|
bool Slab::alloc(size_t size, void **out_addr)
|
||||||
{
|
{
|
||||||
/* sanity check if first slab block is gone */
|
/* sanity check if first slab block is gone */
|
||||||
@ -239,11 +358,11 @@ bool Slab::alloc(size_t size, void **out_addr)
|
|||||||
* new slab block early enough - that is if there are only three free slab
|
* new slab block early enough - that is if there are only three free slab
|
||||||
* entries left.
|
* entries left.
|
||||||
*/
|
*/
|
||||||
if (_backing_store && !num_free_entries_higher_than(3) && !_alloc_state) {
|
if (_backing_store && !_num_free_entries_higher_than(3) && !_alloc_state) {
|
||||||
|
|
||||||
/* allocate new block for slab */
|
/* allocate new block for slab */
|
||||||
_alloc_state = true;
|
_alloc_state = true;
|
||||||
Slab_block *sb = _new_slab_block();
|
Block *sb = _new_slab_block();
|
||||||
_alloc_state = false;
|
_alloc_state = false;
|
||||||
|
|
||||||
if (!sb) return false;
|
if (!sb) return false;
|
||||||
@ -253,35 +372,36 @@ bool Slab::alloc(size_t size, void **out_addr)
|
|||||||
* so we can insert it at the beginning of the sorted block
|
* so we can insert it at the beginning of the sorted block
|
||||||
* list.
|
* list.
|
||||||
*/
|
*/
|
||||||
insert_sb(sb);
|
_insert_sb(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_addr = _first_sb->alloc();
|
*out_addr = _first_sb->alloc();
|
||||||
return *out_addr == 0 ? false : true;
|
return *out_addr == nullptr ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Slab::free(void *addr)
|
void Slab::_free(void *addr)
|
||||||
{
|
{
|
||||||
Slab_entry *e = addr ? Slab_entry::slab_entry(addr) : 0;
|
Entry *e = addr ? Entry::slab_entry(addr) : nullptr;
|
||||||
|
|
||||||
if (e) e->free();
|
if (e)
|
||||||
|
e->~Entry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *Slab::first_used_elem()
|
void *Slab::any_used_elem()
|
||||||
{
|
{
|
||||||
for (Slab_block *b = _first_sb; b; b = b->next) {
|
for (Block *b = _first_sb; b; b = b->next) {
|
||||||
|
|
||||||
/* skip completely free slab blocks */
|
/* skip completely free slab blocks */
|
||||||
if (b->avail() == _num_elem)
|
if (b->avail() == _entries_per_block)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* found a block with used elements - return address of the first one */
|
/* found a block with used elements - return address of the first one */
|
||||||
Slab_entry *e = b->first_used_entry();
|
Entry *e = b->any_used_entry();
|
||||||
if (e) return e->addr();
|
if (e) return e->data;
|
||||||
}
|
}
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -289,7 +409,7 @@ size_t Slab::consumed() const
|
|||||||
{
|
{
|
||||||
/* count number of slab blocks */
|
/* count number of slab blocks */
|
||||||
unsigned sb_cnt = 0;
|
unsigned sb_cnt = 0;
|
||||||
for (Slab_block *sb = _first_sb; sb; sb = sb->next)
|
for (Block *sb = _first_sb; sb; sb = sb->next)
|
||||||
sb_cnt++;
|
sb_cnt++;
|
||||||
|
|
||||||
return sb_cnt * _block_size;
|
return sb_cnt * _block_size;
|
||||||
|
@ -127,31 +127,29 @@ class Bsd::Slab_alloc : public Genode::Slab
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*
|
Genode::size_t const _object_size;
|
||||||
* Each slab block in the slab contains about 8 objects (slab entries)
|
|
||||||
* as proposed in the paper by Bonwick and block sizes are multiples of
|
static Genode::size_t _calculate_block_size(Genode::size_t object_size)
|
||||||
* page size.
|
|
||||||
*/
|
|
||||||
static size_t _calculate_block_size(size_t object_size)
|
|
||||||
{
|
{
|
||||||
size_t block_size = 8 * (object_size + sizeof(Genode::Slab_entry))
|
Genode::size_t const block_size = 16*object_size;
|
||||||
+ sizeof(Genode::Slab_block);
|
|
||||||
return Genode::align_addr(block_size, 12);
|
return Genode::align_addr(block_size, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Slab_alloc(size_t object_size, Slab_backend_alloc &allocator)
|
Slab_alloc(Genode::size_t object_size, Slab_backend_alloc &allocator)
|
||||||
: Slab(object_size, _calculate_block_size(object_size), 0, &allocator) { }
|
:
|
||||||
|
Slab(object_size, _calculate_block_size(object_size), 0, &allocator),
|
||||||
|
_object_size(object_size)
|
||||||
|
{ }
|
||||||
|
|
||||||
/**
|
Genode::addr_t alloc()
|
||||||
* Convenience slabe-entry allocation
|
|
||||||
*/
|
|
||||||
addr_t alloc()
|
|
||||||
{
|
{
|
||||||
addr_t result;
|
Genode::addr_t result;
|
||||||
return (Slab::alloc(slab_size(), (void **)&result) ? result : 0);
|
return (Slab::alloc(_object_size, (void **)&result) ? result : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free(void *ptr) { Slab::free(ptr, _object_size); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -164,7 +162,7 @@ class Bsd::Malloc
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
SLAB_START_LOG2 = 5, /* 32 B */
|
SLAB_START_LOG2 = 5, /* 32 B */
|
||||||
SLAB_STOP_LOG2 = 17, /* 64 KiB */
|
SLAB_STOP_LOG2 = 16, /* 64 KiB */
|
||||||
NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1,
|
NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -503,33 +503,36 @@ struct Slab_backend_alloc : public Genode::Allocator,
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Slab_alloc : public Genode::Slab
|
class Slab_alloc : public Genode::Slab
|
||||||
{
|
{
|
||||||
/*
|
private:
|
||||||
* Each slab block in the slab contains about 8 objects (slab entries)
|
|
||||||
* as proposed in the paper by Bonwick and block sizes are multiples of
|
|
||||||
* page size.
|
|
||||||
*/
|
|
||||||
static Genode::size_t _calculate_block_size(Genode::size_t object_size)
|
|
||||||
{
|
|
||||||
Genode::size_t block_size = 8 * (object_size + sizeof(Genode::Slab_entry))
|
|
||||||
+ sizeof(Genode::Slab_block);
|
|
||||||
return Genode::align_addr(block_size, 12);
|
|
||||||
}
|
|
||||||
|
|
||||||
Slab_alloc(Genode::size_t object_size, Slab_backend_alloc &allocator)
|
Genode::size_t const _object_size;
|
||||||
: Slab(object_size, _calculate_block_size(object_size), 0, &allocator) { }
|
|
||||||
|
|
||||||
/**
|
static Genode::size_t _calculate_block_size(Genode::size_t object_size)
|
||||||
* Convenience slabe-entry allocation
|
{
|
||||||
*/
|
Genode::size_t const block_size = 8*object_size;
|
||||||
Genode::addr_t alloc()
|
return Genode::align_addr(block_size, 12);
|
||||||
{
|
}
|
||||||
Genode::addr_t result;
|
|
||||||
return (Slab::alloc(slab_size(), (void **)&result) ? result : 0);
|
public:
|
||||||
}
|
|
||||||
|
Slab_alloc(Genode::size_t object_size, Slab_backend_alloc &allocator)
|
||||||
|
:
|
||||||
|
Slab(object_size, _calculate_block_size(object_size), 0, &allocator),
|
||||||
|
_object_size(object_size)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Genode::addr_t alloc()
|
||||||
|
{
|
||||||
|
Genode::addr_t result;
|
||||||
|
return (Slab::alloc(_object_size, (void **)&result) ? result : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void *ptr) { Slab::free(ptr, _object_size); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Slab
|
struct Slab
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/slab.h>
|
#include <base/slab.h>
|
||||||
|
#include <util/misc_math.h>
|
||||||
|
|
||||||
/* Linux emulation environment includes */
|
/* Linux emulation environment includes */
|
||||||
#include <lx_emul/impl/internal/slab_backend_alloc.h>
|
#include <lx_emul/impl/internal/slab_backend_alloc.h>
|
||||||
@ -28,6 +29,8 @@ class Lx::Slab_alloc : public Genode::Slab
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
size_t const _object_size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each slab block in the slab contains about 8 objects (slab entries)
|
* Each slab block in the slab contains about 8 objects (slab entries)
|
||||||
* as proposed in the paper by Bonwick and block sizes are multiples of
|
* as proposed in the paper by Bonwick and block sizes are multiples of
|
||||||
@ -35,15 +38,17 @@ class Lx::Slab_alloc : public Genode::Slab
|
|||||||
*/
|
*/
|
||||||
static size_t _calculate_block_size(size_t object_size)
|
static size_t _calculate_block_size(size_t object_size)
|
||||||
{
|
{
|
||||||
size_t block_size = 8 * (object_size + sizeof(Genode::Slab_entry))
|
size_t block_size = 16*object_size;
|
||||||
+ sizeof(Genode::Slab_block);
|
|
||||||
return Genode::align_addr(block_size, 12);
|
return Genode::align_addr(block_size, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Slab_alloc(size_t object_size, Slab_backend_alloc &allocator)
|
Slab_alloc(size_t object_size, Slab_backend_alloc &allocator)
|
||||||
: Slab(object_size, _calculate_block_size(object_size), 0, &allocator) { }
|
:
|
||||||
|
Slab(object_size, _calculate_block_size(object_size), 0, &allocator),
|
||||||
|
_object_size(object_size)
|
||||||
|
{ }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience slabe-entry allocation
|
* Convenience slabe-entry allocation
|
||||||
@ -51,7 +56,12 @@ class Lx::Slab_alloc : public Genode::Slab
|
|||||||
Genode::addr_t alloc()
|
Genode::addr_t alloc()
|
||||||
{
|
{
|
||||||
Genode::addr_t result;
|
Genode::addr_t result;
|
||||||
return (Slab::alloc(slab_size(), (void **)&result) ? result : 0);
|
return (Slab::alloc(_object_size, (void **)&result) ? result : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void *ptr)
|
||||||
|
{
|
||||||
|
Slab::free(ptr, _object_size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -152,23 +152,29 @@ class Genode::Slab_alloc : public Genode::Slab
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
size_t _calculate_block_size(size_t object_size)
|
Genode::size_t const _object_size;
|
||||||
|
|
||||||
|
static Genode::size_t _calculate_block_size(Genode::size_t object_size)
|
||||||
{
|
{
|
||||||
size_t block_size = 8 * (object_size + sizeof(Slab_entry)) + sizeof(Slab_block);
|
Genode::size_t const block_size = 16*object_size;
|
||||||
return align_addr(block_size, 12);
|
return align_addr(block_size, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Slab_alloc(size_t object_size, Backend_alloc *allocator)
|
Slab_alloc(size_t object_size, Backend_alloc *allocator)
|
||||||
: Slab(object_size, _calculate_block_size(object_size), 0, allocator)
|
:
|
||||||
{ }
|
Slab(object_size, _calculate_block_size(object_size), 0, allocator),
|
||||||
|
_object_size(object_size)
|
||||||
|
{ }
|
||||||
|
|
||||||
inline addr_t alloc()
|
inline addr_t alloc()
|
||||||
{
|
{
|
||||||
addr_t result;
|
Genode::addr_t result;
|
||||||
return (Slab::alloc(slab_size(), (void **)&result) ? result : 0);
|
return (Slab::alloc(_object_size, (void **)&result) ? result : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free(void *ptr) { Slab::free(ptr, _object_size); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -169,23 +169,29 @@ class Genode::Slab_alloc : public Genode::Slab
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
size_t _calculate_block_size(size_t object_size)
|
Genode::size_t const _object_size;
|
||||||
|
|
||||||
|
static Genode::size_t _calculate_block_size(Genode::size_t object_size)
|
||||||
{
|
{
|
||||||
size_t block_size = 8 * (object_size + sizeof(Slab_entry)) + sizeof(Slab_block);
|
Genode::size_t const block_size = 16*object_size;
|
||||||
return align_addr(block_size, 12);
|
return Genode::align_addr(block_size, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Slab_alloc(size_t object_size, Slab_backend_alloc *allocator)
|
Slab_alloc(Genode::size_t object_size, Slab_backend_alloc &allocator)
|
||||||
: Slab(object_size, _calculate_block_size(object_size), 0, allocator)
|
:
|
||||||
{ }
|
Slab(object_size, _calculate_block_size(object_size), 0, &allocator),
|
||||||
|
_object_size(object_size)
|
||||||
|
{ }
|
||||||
|
|
||||||
inline addr_t alloc()
|
Genode::addr_t alloc()
|
||||||
{
|
{
|
||||||
addr_t result;
|
Genode::addr_t result;
|
||||||
return (Slab::alloc(slab_size(), (void **)&result) ? result : 0);
|
return (Slab::alloc(_object_size, (void **)&result) ? result : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free(void *ptr) { Slab::free(ptr, _object_size); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -247,7 +253,7 @@ class Malloc
|
|||||||
/* init slab allocators */
|
/* init slab allocators */
|
||||||
for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++)
|
for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++)
|
||||||
_allocator[i - SLAB_START_LOG2] = new (Genode::env()->heap())
|
_allocator[i - SLAB_START_LOG2] = new (Genode::env()->heap())
|
||||||
Slab_alloc(1U << i, alloc);
|
Slab_alloc(1U << i, *alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long max_alloc() { return 1U << SLAB_STOP_LOG2; }
|
static unsigned long max_alloc() { return 1U << SLAB_STOP_LOG2; }
|
||||||
|
@ -191,31 +191,29 @@ class Lx::Slab_alloc : public Genode::Slab
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*
|
Genode::size_t const _object_size;
|
||||||
* Each slab block in the slab contains about 8 objects (slab entries)
|
|
||||||
* as proposed in the paper by Bonwick and block sizes are multiples of
|
static Genode::size_t _calculate_block_size(Genode::size_t object_size)
|
||||||
* page size.
|
|
||||||
*/
|
|
||||||
static size_t _calculate_block_size(size_t object_size)
|
|
||||||
{
|
{
|
||||||
size_t block_size = 8 * (object_size + sizeof(Genode::Slab_entry))
|
Genode::size_t const block_size = 16*object_size;
|
||||||
+ sizeof(Genode::Slab_block);
|
|
||||||
return Genode::align_addr(block_size, 12);
|
return Genode::align_addr(block_size, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Slab_alloc(size_t object_size, Slab_backend_alloc &allocator)
|
Slab_alloc(Genode::size_t object_size, Slab_backend_alloc &allocator)
|
||||||
: Slab(object_size, _calculate_block_size(object_size), 0, &allocator) { }
|
:
|
||||||
|
Slab(object_size, _calculate_block_size(object_size), 0, &allocator),
|
||||||
|
_object_size(object_size)
|
||||||
|
{ }
|
||||||
|
|
||||||
/**
|
Genode::addr_t alloc()
|
||||||
* Convenience slabe-entry allocation
|
|
||||||
*/
|
|
||||||
addr_t alloc()
|
|
||||||
{
|
{
|
||||||
addr_t result;
|
Genode::addr_t result;
|
||||||
return (Slab::alloc(slab_size(), (void **)&result) ? result : 0);
|
return (Slab::alloc(_object_size, (void **)&result) ? result : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free(void *ptr) { Slab::free(ptr, _object_size); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,6 +65,10 @@ class Wifi_session_component : public Nic::Session_component
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sk_buff *skb = ::alloc_skb(packet.size() + HEAD_ROOM, GFP_KERNEL);
|
struct sk_buff *skb = ::alloc_skb(packet.size() + HEAD_ROOM, GFP_KERNEL);
|
||||||
|
if (skb == nullptr) {
|
||||||
|
PERR("Could not allocate new sk_buff");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
skb_reserve(skb, HEAD_ROOM);
|
skb_reserve(skb, HEAD_ROOM);
|
||||||
|
|
||||||
unsigned char *data = skb_put(skb, packet.size());
|
unsigned char *data = skb_put(skb, packet.size());
|
||||||
|
@ -32,23 +32,31 @@ namespace Genode {
|
|||||||
|
|
||||||
class Slab_alloc : public Slab
|
class Slab_alloc : public Slab
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
size_t const _object_size;
|
||||||
|
|
||||||
size_t _calculate_block_size(size_t object_size)
|
size_t _calculate_block_size(size_t object_size)
|
||||||
{
|
{
|
||||||
size_t block_size = 8 * (object_size + sizeof(Slab_entry)) + sizeof(Slab_block);
|
size_t block_size = 16*object_size;
|
||||||
return align_addr(block_size, 12);
|
return align_addr(block_size, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Slab_alloc(size_t object_size, Allocator *backing_store)
|
Slab_alloc(size_t object_size, Allocator *backing_store)
|
||||||
: Slab(object_size, _calculate_block_size(object_size), 0, backing_store)
|
:
|
||||||
|
Slab(object_size, _calculate_block_size(object_size), 0, backing_store),
|
||||||
|
_object_size(object_size)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
inline void *alloc()
|
void *alloc()
|
||||||
{
|
{
|
||||||
void *result;
|
void *result;
|
||||||
return (Slab::alloc(slab_size(), &result) ? result : 0);
|
return (Slab::alloc(_object_size, &result) ? result : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free(void *ptr) { Slab::free(ptr, _object_size); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,11 +67,9 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
|||||||
};
|
};
|
||||||
|
|
||||||
Genode::Tslab<Genode::Io_port_connection, IO_BLOCK_SIZE> _slab_ioport;
|
Genode::Tslab<Genode::Io_port_connection, IO_BLOCK_SIZE> _slab_ioport;
|
||||||
Genode::Slab_block _slab_ioport_block;
|
|
||||||
char _slab_ioport_block_data[IO_BLOCK_SIZE];
|
char _slab_ioport_block_data[IO_BLOCK_SIZE];
|
||||||
|
|
||||||
Genode::Tslab<Io_mem, IO_MEM_SIZE> _slab_iomem;
|
Genode::Tslab<Io_mem, IO_MEM_SIZE> _slab_iomem;
|
||||||
Genode::Slab_block _slab_iomem_block;
|
|
||||||
char _slab_iomem_block_data[IO_MEM_SIZE];
|
char _slab_iomem_block_data[IO_MEM_SIZE];
|
||||||
|
|
||||||
char _mem_irq_component[sizeof(Irq_session_component)];
|
char _mem_irq_component[sizeof(Irq_session_component)];
|
||||||
@ -200,20 +198,14 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
|||||||
_irq_line(_device_config.read(&_config_access, PCI_IRQ_LINE,
|
_irq_line(_device_config.read(&_config_access, PCI_IRQ_LINE,
|
||||||
Platform::Device::ACCESS_8BIT)),
|
Platform::Device::ACCESS_8BIT)),
|
||||||
_irq_session(nullptr),
|
_irq_session(nullptr),
|
||||||
_slab_ioport(md_alloc, &_slab_ioport_block),
|
_slab_ioport(md_alloc, &_slab_ioport_block_data),
|
||||||
_slab_iomem(md_alloc, &_slab_iomem_block)
|
_slab_iomem(md_alloc, &_slab_iomem_block_data)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) {
|
for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) {
|
||||||
_io_port_conn[i] = nullptr;
|
_io_port_conn[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_slab_ioport.num_elem() != Device::NUM_RESOURCES)
|
|
||||||
PERR("incorrect amount of space for io port resources");
|
|
||||||
if (_slab_iomem.num_elem() != Device::NUM_RESOURCES)
|
|
||||||
PERR("incorrect amount of space for io mem resources");
|
|
||||||
|
|
||||||
_disable_bus_master_dma();
|
_disable_bus_master_dma();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -226,8 +218,8 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
|||||||
_ep(ep), _session(session),
|
_ep(ep), _session(session),
|
||||||
_irq_line(irq),
|
_irq_line(irq),
|
||||||
_irq_session(nullptr),
|
_irq_session(nullptr),
|
||||||
_slab_ioport(0, &_slab_ioport_block),
|
_slab_ioport(0, &_slab_ioport_block_data),
|
||||||
_slab_iomem(0, &_slab_iomem_block)
|
_slab_iomem(0, &_slab_iomem_block_data)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < Device::NUM_RESOURCES; i++)
|
for (unsigned i = 0; i < Device::NUM_RESOURCES; i++)
|
||||||
_io_port_conn[i] = nullptr;
|
_io_port_conn[i] = nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user