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
This commit is contained in:
Stefan Kalkowski 2014-01-24 13:18:03 +01:00 committed by Christian Helmuth
parent 1645587b6a
commit 66c5887bd3
3 changed files with 56 additions and 134 deletions

View File

@ -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 <base/cap_sel_alloc.h>
/* NOVA includes */
#include <nova/syscalls.h>
#include <nova/util.h>
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;
}
}

View File

@ -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 <base/bit_array.h>
#include <util/bit_array.h>
namespace Genode {
template<addr_t WORDS>
template<unsigned BITS>
class Bit_allocator
{
protected:
addr_t _next;
Bit_array<WORDS> _array;
addr_t _next;
Bit_array<BITS> _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<BITS>::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_ */

View File

@ -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 <base/exception.h>
#include <base/stdint.h>
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 <addr_t WORDS>
template <unsigned BITS>
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_ */