2012-07-16 08:01:56 +00:00
|
|
|
/*
|
2014-01-24 12:18:03 +00:00
|
|
|
* \brief Allocator using bitmaps
|
2012-07-16 08:01:56 +00:00
|
|
|
* \author Alexander Boettcher
|
2014-01-24 12:18:03 +00:00
|
|
|
* \author Stefan Kalkowski
|
2012-07-16 08:01:56 +00:00
|
|
|
* \date 2012-06-14
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 20:44:47 +00:00
|
|
|
* Copyright (C) 2012-2013 Genode Labs GmbH
|
2012-07-16 08:01:56 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
2014-01-24 12:18:03 +00:00
|
|
|
#ifndef _INCLUDE__UTIL__BIT_ALLOCATOR_H_
|
|
|
|
#define _INCLUDE__UTIL__BIT_ALLOCATOR_H_
|
2012-07-16 08:01:56 +00:00
|
|
|
|
2014-01-24 12:18:03 +00:00
|
|
|
#include <util/bit_array.h>
|
2012-07-16 08:01:56 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
namespace Genode { template<unsigned> class Bit_allocator; }
|
2012-07-16 08:01:56 +00:00
|
|
|
|
2013-01-11 22:10:21 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
template<unsigned BITS>
|
|
|
|
class Genode::Bit_allocator
|
|
|
|
{
|
|
|
|
protected:
|
2012-07-16 08:01:56 +00:00
|
|
|
|
2015-06-25 14:24:42 +00:00
|
|
|
enum {
|
|
|
|
BITS_PER_BYTE = 8UL,
|
|
|
|
BITS_PER_WORD = sizeof(addr_t) * BITS_PER_BYTE,
|
|
|
|
BITS_ALIGNED = (BITS + BITS_PER_WORD - 1UL)
|
|
|
|
& ~(BITS_PER_WORD - 1UL),
|
|
|
|
};
|
|
|
|
|
|
|
|
using Array = Bit_array<BITS_ALIGNED>;
|
|
|
|
|
|
|
|
addr_t _next;
|
|
|
|
Array _array;
|
2012-07-16 08:01:56 +00:00
|
|
|
|
2015-03-20 16:50:41 +00:00
|
|
|
/**
|
|
|
|
* Reserve consecutive number of bits
|
|
|
|
*
|
|
|
|
* \noapi
|
|
|
|
*/
|
2015-03-04 20:12:14 +00:00
|
|
|
void _reserve(addr_t bit_start, size_t const num)
|
|
|
|
{
|
|
|
|
if (!num) return;
|
2012-07-16 08:01:56 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
_array.set(bit_start, num);
|
|
|
|
}
|
2012-07-16 08:01:56 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
public:
|
2014-01-24 12:18:03 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
class Out_of_indices : Exception {};
|
2013-08-27 09:14:49 +00:00
|
|
|
|
2015-06-25 14:24:42 +00:00
|
|
|
Bit_allocator() : _next(0) {
|
|
|
|
_reserve(BITS, BITS_ALIGNED - BITS); }
|
2013-08-27 09:14:49 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
addr_t alloc(size_t const num_log2 = 0)
|
|
|
|
{
|
|
|
|
addr_t const step = 1UL << num_log2;
|
|
|
|
addr_t max = ~0UL;
|
2013-08-27 09:14:49 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
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))
|
|
|
|
continue;
|
2013-08-27 09:14:49 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
_array.set(i, step);
|
|
|
|
_next = i + step;
|
|
|
|
return i;
|
|
|
|
}
|
2015-06-25 14:24:42 +00:00
|
|
|
} catch (typename Array::Invalid_index_access) { }
|
2013-08-27 09:14:49 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
max = _next;
|
|
|
|
_next = 0;
|
2012-07-16 08:01:56 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
} while (max != 0);
|
|
|
|
|
|
|
|
throw Out_of_indices();
|
|
|
|
}
|
|
|
|
|
|
|
|
void free(addr_t const bit_start, size_t const num_log2 = 0)
|
|
|
|
{
|
|
|
|
_array.clear(bit_start, 1UL << num_log2);
|
|
|
|
_next = bit_start;
|
|
|
|
}
|
|
|
|
};
|
2012-07-16 08:01:56 +00:00
|
|
|
|
2014-01-24 12:18:03 +00:00
|
|
|
#endif /* _INCLUDE__UTIL__BIT_ALLOCATOR_H_ */
|