diff --git a/repos/base-hw/src/core/include/rpc_cap_factory.h b/repos/base-hw/src/core/include/rpc_cap_factory.h index 03522f9a0..4db2f2b67 100644 --- a/repos/base-hw/src/core/include/rpc_cap_factory.h +++ b/repos/base-hw/src/core/include/rpc_cap_factory.h @@ -56,7 +56,7 @@ class Genode::Rpc_cap_factory Rpc_cap_factory(Allocator &md_alloc) : - _slab(&md_alloc, (Slab_block*)&_initial_slab_block) + _slab(&md_alloc, &_initial_slab_block) { } ~Rpc_cap_factory() diff --git a/repos/base-hw/src/core/include/signal_broker.h b/repos/base-hw/src/core/include/signal_broker.h index 05139725c..4ee20657d 100644 --- a/repos/base-hw/src/core/include/signal_broker.h +++ b/repos/base-hw/src/core/include/signal_broker.h @@ -38,8 +38,7 @@ class Genode::Signal_broker public: Slab(Allocator * const allocator) - : Tslab(allocator, - (Slab_block*)&_first_block) { } + : Tslab(allocator, &_first_block) { } }; Allocator &_md_alloc; diff --git a/repos/base-hw/src/core/kernel/ipc_node.cc b/repos/base-hw/src/core/kernel/ipc_node.cc index 3e9af268f..c114d0f65 100644 --- a/repos/base-hw/src/core/kernel/ipc_node.cc +++ b/repos/base-hw/src/core/kernel/ipc_node.cc @@ -30,6 +30,12 @@ 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) { 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 (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; } @@ -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 (!oir) { _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; } @@ -68,9 +74,9 @@ void Ipc_node::copy_msg(Ipc_node * const sender) if (!dst_oir && (pd() != core_pd())) { dst_oir = oir->factory(_obj_id_ref_ptr[i], *pd()); 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 */ - 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(); diff --git a/repos/base-hw/src/core/platform_pd.cc b/repos/base-hw/src/core/platform_pd.cc index 239b1e33b..7b108f871 100644 --- a/repos/base-hw/src/core/platform_pd.cc +++ b/repos/base-hw/src/core/platform_pd.cc @@ -108,13 +108,13 @@ Hw::Address_space::~Address_space() *************************************/ Capability_space::Capability_space() -: _slab(nullptr, (Slab_block*)&_initial_sb) { } +: _slab(nullptr, &_initial_sb) { } void Capability_space::upgrade_slab(Allocator &alloc) { for (;;) { - Slab_block * block; + void *block = nullptr; /* * 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. */ if (!alloc.alloc(SLAB_SIZE, &block)) return; - block = construct_at(block, &_slab); _slab.insert_sb(block); } } diff --git a/repos/base/include/base/slab.h b/repos/base/include/base/slab.h index a8eb1f87e..6faff1d66 100644 --- a/repos/base/include/base/slab.h +++ b/repos/base/include/base/slab.h @@ -17,148 +17,14 @@ #include #include -namespace Genode { - - class Slab; - class Slab_block; - class Slab_entry; -} - +namespace Genode { class Slab; } /** - * 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 -{ - 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)); } -}; +namespace Genode { typedef void Slab_block; } /** @@ -168,27 +34,55 @@ class Genode::Slab : public Allocator { private: - size_t _slab_size; /* size of one slab entry */ - size_t _block_size; /* size of slab block */ - 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' */ + struct Block; + struct Entry; - 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 */ - 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: - 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 * @@ -197,7 +91,7 @@ class Genode::Slab : public Allocator * especially for the allocation of the second slab * 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); /** @@ -206,40 +100,17 @@ class Genode::Slab : public Allocator ~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 - * - * \noapi + * Return a used slab element, or nullptr if empty */ - void remove_sb(Slab_block *sb); - - /** - * 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); + void *any_used_elem(); /** * Define/request backing-store allocator @@ -255,6 +126,7 @@ class Genode::Slab : public Allocator */ Allocator *backing_store() { return _backing_store; } + /************************* ** Allocator interface ** *************************/ @@ -266,9 +138,9 @@ class Genode::Slab : public Allocator * preconfigured slab-entry size are allocated. */ 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 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; } }; diff --git a/repos/base/include/base/tslab.h b/repos/base/include/base/tslab.h index 3c5dc4330..d4adfcfaf 100644 --- a/repos/base/include/base/tslab.h +++ b/repos/base/include/base/tslab.h @@ -22,12 +22,11 @@ namespace Genode { template struct Tslab; } template struct Genode::Tslab : Slab { - Tslab(Allocator *backing_store, - Slab_block *initial_sb = 0) + Tslab(Allocator *backing_store, void *initial_sb = 0) : 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_ */ diff --git a/repos/base/src/base/allocator/slab.cc b/repos/base/src/base/allocator/slab.cc index 57d5d3984..b45ea4d47 100644 --- a/repos/base/src/base/allocator/slab.cc +++ b/repos/base/src/base/allocator/slab.cc @@ -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 * under the terms of the GNU General Public License version 2. */ #include +#include #include 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 ** ****************/ -/** - * 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) +Slab::Entry *Slab::Block::_slab_entry(int idx) { /* * The slab slots start after the state array that consists * of 'num_elem' bytes. We align the first slot to a four-aligned * 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) { - return ((addr_t)e - (addr_t)slab_entry(0))/_slab->entry_size(); } - - -void *Slab_block::alloc() +int Slab::Block::_slab_entry_idx(Slab::Entry *e) { - size_t num_elem = _slab->num_elem(); - for (unsigned i = 0; i < num_elem; i++) - if (state(i) == FREE) { - state(i, USED); - Slab_entry *e = slab_entry(i); - e->occupy(this); - return e->addr(); - } - return 0; + size_t const entry_size = sizeof(Entry) + _slab._slab_size; + return ((addr_t)e - (addr_t)_slab_entry(0))/entry_size; } -Slab_entry *Slab_block::first_used_entry() +void *Slab::Block::alloc() { - size_t num_elem = _slab->num_elem(); - for (unsigned i = 0; i < num_elem; i++) - if (state(i) == USED) - return slab_entry(i); - return 0; + for (unsigned i = 0; i < _slab._entries_per_block; i++) { + if (_state(i) != FREE) + continue; + + _state(i, USED); + Entry * const e = _slab_entry(i); + construct_at(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 */ - int idx = slab_entry_idx(e); - state(idx, FREE); + int const idx = _slab_entry_idx(&e); + _state(idx, FREE); _avail++; /* search previous block with higher avail value than this' */ - Slab_block *at = prev; + Block *at = prev; while (at && (at->avail() < _avail)) 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 * previous block, do not reposition the block in the list. */ - if (prev == 0 || at == prev) + if (prev == nullptr || at == prev) return; /* reposition block in list after block with higher avail value */ - _slab->remove_sb(this); - _slab->insert_sb(this, at); + _slab._remove_sb(this); + _slab._insert_sb(this, at); } -void Slab_block::dec_avail() +void Slab::Block::dec_avail() { _avail--; /* search subsequent block with lower avail value than this' */ - Slab_block *at = this; + Block *at = this; while (at->next && at->next->avail() > _avail) at = at->next; if (at == this) return; - _slab->remove_sb(this); - _slab->insert_sb(this, at); + _slab._remove_sb(this); + _slab._insert_sb(this, at); } @@ -125,31 +237,33 @@ void Slab_block::dec_avail() ** Slab ** **********/ -Slab::Slab(size_t slab_size, size_t block_size, Slab_block *initial_sb, - Allocator *backing_store) -: _slab_size(slab_size), - _block_size(block_size), - _first_sb(initial_sb), - _initial_sb(initial_sb), - _alloc_state(false), - _backing_store(backing_store) -{ +Slab::Slab(size_t slab_size, size_t block_size, void *initial_sb, + Allocator *backing_store) +: + _slab_size(slab_size), + _block_size(block_size), + /* * Calculate number of entries per slab block. * * The 'sizeof(umword_t)' is for the alignment of the first slab entry. * The 1 is for one byte state entry. */ - _num_elem = (_block_size - sizeof(Slab_block) - sizeof(umword_t)) - / (entry_size() + 1); + _entries_per_block((_block_size - sizeof(Block) - sizeof(umword_t)) + / (_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 (!_first_sb && _backing_store) _first_sb = _new_slab_block(); /* init first slab block */ if (_first_sb) - _first_sb->slab(this); + construct_at(_first_sb, *this); } @@ -157,8 +271,8 @@ Slab::~Slab() { /* free backing store */ while (_first_sb) { - Slab_block *sb = _first_sb; - remove_sb(_first_sb); + Block * const sb = _first_sb; + _remove_sb(_first_sb); /* * 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)) - return 0; + return nullptr; - /* call constructor by using the placement new operator */ - return new(sb) Slab_block(this); + return construct_at(sb, *this); } -void Slab::remove_sb(Slab_block *sb) +void Slab::_remove_sb(Block *sb) { - Slab_block *prev = sb->prev; - Slab_block *next = sb->next; + Block *prev = sb->prev; + Block *next = sb->next; if (prev) prev->next = next; if (next) next->prev = prev; @@ -192,14 +305,14 @@ void Slab::remove_sb(Slab_block *sb) if (_first_sb == sb) _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 */ - Slab_block **nextptr_to_sb = at ? &at->next : &_first_sb; + Block **nextptr_to_sb = at ? &at->next : &_first_sb; /* insert current 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; - 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(); if (cnt > n) 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(ptr, *this)); +} + + bool Slab::alloc(size_t size, void **out_addr) { /* 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 * 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 */ _alloc_state = true; - Slab_block *sb = _new_slab_block(); + Block *sb = _new_slab_block(); _alloc_state = 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 * list. */ - insert_sb(sb); + _insert_sb(sb); } *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 */ - if (b->avail() == _num_elem) + if (b->avail() == _entries_per_block) continue; /* found a block with used elements - return address of the first one */ - Slab_entry *e = b->first_used_entry(); - if (e) return e->addr(); + Entry *e = b->any_used_entry(); + if (e) return e->data; } - return 0; + return nullptr; } @@ -289,7 +409,7 @@ size_t Slab::consumed() const { /* count number of slab blocks */ 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++; return sb_cnt * _block_size; diff --git a/repos/dde_bsd/src/lib/audio/mem.cc b/repos/dde_bsd/src/lib/audio/mem.cc index 1d649eb29..7a6383e6f 100644 --- a/repos/dde_bsd/src/lib/audio/mem.cc +++ b/repos/dde_bsd/src/lib/audio/mem.cc @@ -127,31 +127,29 @@ class Bsd::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 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(Genode::Slab_entry)) - + sizeof(Genode::Slab_block); + Genode::size_t const block_size = 16*object_size; return Genode::align_addr(block_size, 12); } public: - Slab_alloc(size_t object_size, Slab_backend_alloc &allocator) - : Slab(object_size, _calculate_block_size(object_size), 0, &allocator) { } + 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) + { } - /** - * Convenience slabe-entry allocation - */ - addr_t alloc() + Genode::addr_t alloc() { - addr_t result; - return (Slab::alloc(slab_size(), (void **)&result) ? result : 0); + Genode::addr_t result; + 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 { 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, }; diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc b/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc index c43413201..94afd1bc6 100644 --- a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc +++ b/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc @@ -503,33 +503,36 @@ struct Slab_backend_alloc : public Genode::Allocator, }; -struct Slab_alloc : public Genode::Slab +class Slab_alloc : public Genode::Slab { - /* - * 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); - } + private: - Slab_alloc(Genode::size_t object_size, Slab_backend_alloc &allocator) - : Slab(object_size, _calculate_block_size(object_size), 0, &allocator) { } + Genode::size_t const _object_size; - /** - * Convenience slabe-entry allocation - */ - Genode::addr_t alloc() - { - Genode::addr_t result; - return (Slab::alloc(slab_size(), (void **)&result) ? result : 0); - } + static Genode::size_t _calculate_block_size(Genode::size_t object_size) + { + Genode::size_t const block_size = 8*object_size; + return Genode::align_addr(block_size, 12); + } + + 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 { enum { diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/slab_alloc.h b/repos/dde_linux/src/include/lx_emul/impl/internal/slab_alloc.h index 7aaa1ccc7..3b17fe6c5 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/slab_alloc.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/slab_alloc.h @@ -18,6 +18,7 @@ /* Genode includes */ #include +#include /* Linux emulation environment includes */ #include @@ -28,6 +29,8 @@ class Lx::Slab_alloc : public Genode::Slab { private: + 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 @@ -35,15 +38,17 @@ class Lx::Slab_alloc : public Genode::Slab */ static size_t _calculate_block_size(size_t object_size) { - size_t block_size = 8 * (object_size + sizeof(Genode::Slab_entry)) - + sizeof(Genode::Slab_block); + size_t block_size = 16*object_size; return Genode::align_addr(block_size, 12); } public: 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 @@ -51,7 +56,12 @@ class Lx::Slab_alloc : public Genode::Slab Genode::addr_t alloc() { 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); } }; diff --git a/repos/dde_linux/src/lib/lxip/lxcc_emul.cc b/repos/dde_linux/src/lib/lxip/lxcc_emul.cc index 69f7c9c27..b5bab2f07 100644 --- a/repos/dde_linux/src/lib/lxip/lxcc_emul.cc +++ b/repos/dde_linux/src/lib/lxip/lxcc_emul.cc @@ -152,23 +152,29 @@ class Genode::Slab_alloc : public Genode::Slab { 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); } public: 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() - { - addr_t result; - return (Slab::alloc(slab_size(), (void **)&result) ? result : 0); - } + inline 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); } }; /** diff --git a/repos/dde_linux/src/lib/usb/lx_emul.cc b/repos/dde_linux/src/lib/usb/lx_emul.cc index b69446b22..d86983ea4 100644 --- a/repos/dde_linux/src/lib/usb/lx_emul.cc +++ b/repos/dde_linux/src/lib/usb/lx_emul.cc @@ -169,23 +169,29 @@ class Genode::Slab_alloc : public Genode::Slab { 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); - return align_addr(block_size, 12); + Genode::size_t const block_size = 16*object_size; + return Genode::align_addr(block_size, 12); } public: - Slab_alloc(size_t object_size, Slab_backend_alloc *allocator) - : Slab(object_size, _calculate_block_size(object_size), 0, allocator) - { } + 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) + { } - inline addr_t alloc() - { - addr_t result; - return (Slab::alloc(slab_size(), (void **)&result) ? result : 0); - } + 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); } }; @@ -247,7 +253,7 @@ class Malloc /* init slab allocators */ for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++) _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; } diff --git a/repos/dde_linux/src/lib/wifi/lxcc_emul.cc b/repos/dde_linux/src/lib/wifi/lxcc_emul.cc index f152610bc..bb74bcea4 100644 --- a/repos/dde_linux/src/lib/wifi/lxcc_emul.cc +++ b/repos/dde_linux/src/lib/wifi/lxcc_emul.cc @@ -191,31 +191,29 @@ class Lx::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 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(Genode::Slab_entry)) - + sizeof(Genode::Slab_block); + Genode::size_t const block_size = 16*object_size; return Genode::align_addr(block_size, 12); } public: - Slab_alloc(size_t object_size, Slab_backend_alloc &allocator) - : Slab(object_size, _calculate_block_size(object_size), 0, &allocator) { } + 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) + { } - /** - * Convenience slabe-entry allocation - */ - addr_t alloc() + Genode::addr_t alloc() { - addr_t result; - return (Slab::alloc(slab_size(), (void **)&result) ? result : 0); + Genode::addr_t result; + return (Slab::alloc(_object_size, (void **)&result) ? result : 0); } + + void free(void *ptr) { Slab::free(ptr, _object_size); } }; diff --git a/repos/dde_linux/src/lib/wifi/nic.cc b/repos/dde_linux/src/lib/wifi/nic.cc index 57d481607..e1c6a18ec 100644 --- a/repos/dde_linux/src/lib/wifi/nic.cc +++ b/repos/dde_linux/src/lib/wifi/nic.cc @@ -65,6 +65,10 @@ class Wifi_session_component : public Nic::Session_component } 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); unsigned char *data = skb_put(skb, packet.size()); diff --git a/repos/libports/src/lib/libc/malloc.cc b/repos/libports/src/lib/libc/malloc.cc index 911be4b16..f8fc1cd62 100644 --- a/repos/libports/src/lib/libc/malloc.cc +++ b/repos/libports/src/lib/libc/malloc.cc @@ -32,23 +32,31 @@ namespace Genode { class Slab_alloc : public Slab { + private: + + size_t const _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); } public: 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; - 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); } }; } diff --git a/repos/os/src/drivers/platform/spec/x86/pci_device_component.h b/repos/os/src/drivers/platform/spec/x86/pci_device_component.h index a241bf7c8..8cbfb63ff 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_device_component.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_device_component.h @@ -67,11 +67,9 @@ class Platform::Device_component : public Genode::Rpc_object, }; Genode::Tslab _slab_ioport; - Genode::Slab_block _slab_ioport_block; char _slab_ioport_block_data[IO_BLOCK_SIZE]; Genode::Tslab _slab_iomem; - Genode::Slab_block _slab_iomem_block; char _slab_iomem_block_data[IO_MEM_SIZE]; char _mem_irq_component[sizeof(Irq_session_component)]; @@ -200,20 +198,14 @@ class Platform::Device_component : public Genode::Rpc_object, _irq_line(_device_config.read(&_config_access, PCI_IRQ_LINE, Platform::Device::ACCESS_8BIT)), _irq_session(nullptr), - _slab_ioport(md_alloc, &_slab_ioport_block), - _slab_iomem(md_alloc, &_slab_iomem_block) + _slab_ioport(md_alloc, &_slab_ioport_block_data), + _slab_iomem(md_alloc, &_slab_iomem_block_data) { for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) { _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(); - } /** @@ -226,8 +218,8 @@ class Platform::Device_component : public Genode::Rpc_object, _ep(ep), _session(session), _irq_line(irq), _irq_session(nullptr), - _slab_ioport(0, &_slab_ioport_block), - _slab_iomem(0, &_slab_iomem_block) + _slab_ioport(0, &_slab_ioport_block_data), + _slab_iomem(0, &_slab_iomem_block_data) { for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) _io_port_conn[i] = nullptr;