1
/*
2
* \brief Allocator using bitmaps
3
* \author Alexander Boettcher
4
* \author Stefan Kalkowski
5
* \date 2012-06-14
6
*/
7
8
/*
9
* Copyright (C) 2012-2013 Genode Labs GmbH
10
*
11
* This file is part of the Genode OS framework, which is distributed
12
* under the terms of the GNU General Public License version 2.
13
*/
14
15
#
ifndef _INCLUDE__UTIL__BIT_ALLOCATOR_H_
16
#
define _INCLUDE__UTIL__BIT_ALLOCATOR_H_
17
18
#
include <util/bit_array.h>
19
20
namespace
Genode {
template
<
unsigned
>
class
Bit_allocator;
}
21
22
23
template
<
unsigned
BITS
>
24
class
Genode::
Bit_allocator
25
{
26
protected
:
27
28
enum
{
29
BITS_PER_BYTE =
8UL
,
30
BITS_PER_WORD
=
sizeof
(
addr_t)
*
BITS_PER_BYTE
,
31
BITS_ALIGNED
=
(
BITS +
BITS_PER_WORD -
1UL)
32
&
~
(
BITS_PER_WORD -
1UL)
,
33
}
;
34
35
using
Array =
Bit_array<
BITS_ALIGNED
>
;
36
37
addr_t _next;
38
Array _array;
39
40
/**
41
* Reserve consecutive number of bits
42
*
43
* \noapi
44
*/
45
void
_reserve(
addr_t
bit_start
,
size_t const
num
)
46
{
47
if
(
!
num)
return
;
48
49
_array.
set(
bit_start,
num)
;
50
}
51
52
public
:
53
54
class
Out_of_indices :
Exception
{
}
;
55
56
Bit_allocator(
)
:
_next(
0)
{
57
_reserve(
BITS,
BITS_ALIGNED -
BITS)
;
}
58
59
addr_t
alloc(
size_t const
num_log2
=
0
)
60
{
61
addr_t const
step =
1UL <<
num_log2;
62
addr_t max =
~
0UL;
63
64
do
{
65
try
{
66
/* throws exception if array is accessed outside bounds */
67
for
(
addr_t i =
_next &
~
(
step -
1)
; i <
max; i +=
step)
{
68
if
(
_array.
get(
i,
step)
)
69
continue
;
70
71
_array.
set(
i,
step)
;
72
_next =
i +
step;
73
return
i
;
74
}
75
}
catch
(
typename
Array::
Invalid_index_access)
{
}
76
77
max =
_next;
78
_next =
0;
79
80
}
while
(
max !=
0)
;
81
82
throw
Out_of_indices(
)
;
83
}
84
85
void
free(
addr_t const
bit_start
,
size_t const
num_log2
=
0
)
86
{
87
_array.
clear(
bit_start,
1UL <<
num_log2)
;
88
_next =
bit_start;
89
}
90
}
;
91
92
#
endif /* _INCLUDE__UTIL__BIT_ALLOCATOR_H_ */