From 66c5887bd34330ed1a73b8a3162dd81016eed769 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 24 Jan 2014 13:18:03 +0100 Subject: [PATCH] Move Bit_allocator from base-nova to base Change the template parameter for Bit_allocator, and Bit_array. Instead of assigning words to be used by the bit array, you can now tell the count of items that shall be used. Moreover, some dead code, previously using the Bit_allocator, was removed. Related to #1024 --- base-nova/src/base/env/cap_sel_alloc.cc | 71 ----------------- .../include/util}/bit_allocator.h | 40 +++++----- .../base => base/include/util}/bit_array.h | 79 +++++++++---------- 3 files changed, 56 insertions(+), 134 deletions(-) delete mode 100644 base-nova/src/base/env/cap_sel_alloc.cc rename {base-nova/include/base => base/include/util}/bit_allocator.h (56%) rename {base-nova/include/base => base/include/util}/bit_array.h (53%) diff --git a/base-nova/src/base/env/cap_sel_alloc.cc b/base-nova/src/base/env/cap_sel_alloc.cc deleted file mode 100644 index bf496d8cf5..0000000000 --- a/base-nova/src/base/env/cap_sel_alloc.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* - * \brief Capability-selector allocator - * \author Norman Feske - * \author Sebastian Sumpf - * \author Alexander Boettcher - * \date 2010-01-19 - * - * This is a NOVA-specific addition to the process environment. - */ - -/* - * Copyright (C) 2010-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. - */ - -/* Genode includes */ -#include - -/* NOVA includes */ -#include -#include - -using namespace Genode; - -/** - * Return lock used to protect capability selector allocations - */ -static Genode::Lock &alloc_lock() -{ - static Genode::Lock alloc_lock_inst; - return alloc_lock_inst; -} - - -addr_t Cap_selector_allocator::alloc(size_t num_caps_log2) -{ - Lock::Guard guard(alloc_lock()); - return Bit_allocator::alloc(num_caps_log2); -} - - -void Cap_selector_allocator::free(addr_t cap, size_t num_caps_log2) -{ - Lock::Guard guard(alloc_lock()); - Bit_allocator::free(cap, num_caps_log2); -} - - -Cap_selector_allocator::Cap_selector_allocator() : Bit_allocator() -{ - /* initialize lock */ - alloc_lock(); - - /** - * The first selectors are reserved for exception portals and special - * purpose usage as defined in the nova syscall header file - */ - Bit_allocator::_reserve(0, Nova::NUM_INITIAL_PT_RESERVED); -} - - -namespace Genode { - - Cap_selector_allocator *cap_selector_allocator() - { - static Cap_selector_allocator inst; - return &inst; - } -} diff --git a/base-nova/include/base/bit_allocator.h b/base/include/util/bit_allocator.h similarity index 56% rename from base-nova/include/base/bit_allocator.h rename to base/include/util/bit_allocator.h index 71e62b1ffa..d97ea8bbc7 100644 --- a/base-nova/include/base/bit_allocator.h +++ b/base/include/util/bit_allocator.h @@ -1,6 +1,7 @@ /* - * \brief Allocator using bitmaps to maintain cap space + * \brief Allocator using bitmaps * \author Alexander Boettcher + * \author Stefan Kalkowski * \date 2012-06-14 */ @@ -11,41 +12,41 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__BASE__BIT_ALLOCATOR_H_ -#define _INCLUDE__BASE__BIT_ALLOCATOR_H_ +#ifndef _INCLUDE__UTIL__BIT_ALLOCATOR_H_ +#define _INCLUDE__UTIL__BIT_ALLOCATOR_H_ -#include +#include namespace Genode { - template + template class Bit_allocator { protected: - addr_t _next; - Bit_array _array; + addr_t _next; + Bit_array _array; - void _reserve(addr_t bit_start, size_t const num_cap) + void _reserve(addr_t bit_start, size_t const num) { - if (!num_cap) return; + if (!num) return; - _array.set(bit_start, num_cap); + _array.set(bit_start, num); } public: + class Out_of_indices : Exception {}; + Bit_allocator() : _next(0) { } - addr_t alloc(size_t const num_log2) + addr_t alloc(size_t const num_log2 = 0) { addr_t const step = 1UL << num_log2; addr_t max = ~0UL; - do - { - try - { + do { + try { /* throws exception if array is accessed outside bounds */ for (addr_t i = _next & ~(step - 1); i < max; i += step) { if (_array.get(i, step)) @@ -55,22 +56,21 @@ namespace Genode { _next = i + step; return i; } - } catch (Bit_array_invalid_index_access) { } + } catch (typename Bit_array::Invalid_index_access) { } max = _next; _next = 0; } while (max != 0); - throw Bit_array_out_of_indexes(); + throw Out_of_indices(); } - void free(addr_t const bit_start, size_t const num_log2) + void free(addr_t const bit_start, size_t const num_log2 = 0) { _array.clear(bit_start, 1UL << num_log2); _next = bit_start; } - }; } -#endif /* _INCLUDE__BASE__BIT_ALLOCATOR_H_ */ +#endif /* _INCLUDE__UTIL__BIT_ALLOCATOR_H_ */ diff --git a/base-nova/include/base/bit_array.h b/base/include/util/bit_array.h similarity index 53% rename from base-nova/include/base/bit_array.h rename to base/include/util/bit_array.h index 3756369a4a..e49a466f77 100644 --- a/base-nova/include/base/bit_array.h +++ b/base/include/util/bit_array.h @@ -1,6 +1,7 @@ /* - * \brief Allocator using bitmaps to maintain cap space + * \brief Allocator using bitmaps * \author Alexander Boettcher + * \author Stefan Kalkowski * \date 2012-06-14 */ @@ -11,42 +12,45 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__BASE__BIT_ARRAY_H_ -#define _INCLUDE__BASE__BIT_ARRAY_H_ +#ifndef _INCLUDE__UTIL__BIT_ARRAY_H_ +#define _INCLUDE__UTIL__BIT_ARRAY_H_ +#include #include namespace Genode { - class Bit_array_invalid_index_access{}; - class Bit_array_invalid_clear{}; - class Bit_array_invalid_set{}; - class Bit_array_out_of_indexes{}; - - template + template class Bit_array { + public: + + class Invalid_index_access : public Exception {}; + class Invalid_clear : public Exception {}; + class Invalid_set : public Exception {}; + private: - enum { - _BITS_PER_BYTE = 8UL, - _BITS_PER_WORD = sizeof(addr_t) * _BITS_PER_BYTE, - }; + static constexpr size_t _BITS_PER_BYTE = 8UL; + static constexpr size_t _BITS_PER_WORD = sizeof(addr_t) * + _BITS_PER_BYTE; + static constexpr size_t _WORDS = BITS / _BITS_PER_WORD; - addr_t _words[WORDS]; + static_assert(BITS % _BITS_PER_WORD == 0, + "Count of bits need to be word aligned!"); - addr_t _word(addr_t index) const - { - return index / _BITS_PER_WORD; - } + addr_t _words[_WORDS]; + + addr_t _word(addr_t index) const { + return index / _BITS_PER_WORD; } void _check_range(addr_t const index, addr_t const width) const { - if ((index >= WORDS * _BITS_PER_WORD) || - width > WORDS * _BITS_PER_WORD || - WORDS * _BITS_PER_WORD - width < index) - throw Bit_array_invalid_index_access(); + if ((index >= _WORDS * _BITS_PER_WORD) || + width > _WORDS * _BITS_PER_WORD || + _WORDS * _BITS_PER_WORD - width < index) + throw Invalid_index_access(); } addr_t _mask(addr_t const index, addr_t const width, @@ -57,11 +61,8 @@ namespace Genode { rest = width + shift > _BITS_PER_WORD ? width + shift - _BITS_PER_WORD : 0; - if (width >= _BITS_PER_WORD) - return ~0UL << shift; - else - return ((1UL << width) - 1) << shift; - + return (width >= _BITS_PER_WORD) ? ~0UL << shift + : ((1UL << width) - 1) << shift; } void _set(addr_t index, addr_t width, bool free) @@ -75,26 +76,22 @@ namespace Genode { if (free) { if ((_words[word] & mask) != mask) - throw Bit_array_invalid_clear(); + throw Invalid_clear(); _words[word] &= ~mask; } else { if (_words[word] & mask) - throw Bit_array_invalid_set(); + throw Invalid_set(); _words[word] |= mask; } index = (_word(index) + 1) * _BITS_PER_WORD; width = rest; - } while (rest); } public: - Bit_array() - { - for (addr_t i = 0; i < WORDS; i++) _words[i] = 0UL; - } + Bit_array() { memset(&_words, 0, sizeof(_words)); } /** * Return true if at least one bit is set between @@ -116,16 +113,12 @@ namespace Genode { return used; } - void set(addr_t const index, addr_t const width) - { - _set(index, width, false); - } + void set(addr_t const index, addr_t const width) { + _set(index, width, false); } - void clear(addr_t const index, addr_t const width) - { - _set(index, width, true); - } + void clear(addr_t const index, addr_t const width) { + _set(index, width, true); } }; } -#endif /* _INCLUDE__BASE__BIT_ARRAY_H_ */ +#endif /* _INCLUDE__UTIL__BIT_ARRAY_H_ */