1
/*
2
* \brief A guard for arbitrary allocators to limit memory exhaustion
3
* \author Stefan Kalkowski
4
* \date 2010-08-20
5
*/
6
7
/*
8
* Copyright (C) 2010-2013 Genode Labs GmbH
9
*
10
* This file is part of the Genode OS framework, which is distributed
11
* under the terms of the GNU General Public License version 2.
12
*/
13
14
#
ifndef _INCLUDE__BASE__ALLOCATOR_GUARD_H_
15
#
define _INCLUDE__BASE__ALLOCATOR_GUARD_H_
16
17
#
include <base/allocator.h>
18
#
include <base/printf.h>
19
#
include <base/stdint.h>
20
21
namespace
Genode {
class
Allocator_guard;
}
22
23
24
/**
25
* This class acts as guard for arbitrary allocators to limit
26
* memory exhaustion
27
*/
28
class
Genode::
Allocator_guard :
public
Allocator
29
{
30
private
:
31
32
Allocator *
_allocator;
/* allocator to guard */
33
size_t _amount;
/* total amount */
34
size_t _consumed;
/* already consumed bytes */
35
36
public
:
37
38
Allocator_guard(
Allocator *
allocator
,
size_t
amount
)
39
:
_allocator(
allocator)
,
_amount(
amount)
,
_consumed(
0)
{
}
40
41
/**
42
* Extend allocation limit
43
*/
44
void
upgrade(
size_t
additional_amount
)
{
45
_amount +=
additional_amount;
}
46
47
/**
48
* Consume bytes without actually allocating them
49
*/
50
bool
withdraw(
size_t
size
)
51
{
52
if
(
(
_amount -
_consumed)
<
size)
53
return
false
;
54
55
_consumed +=
size;
56
return
true
;
57
}
58
59
/*************************
60
** Allocator interface **
61
*************************/
62
63
/**
64
* Allocate block
65
*
66
* \param size block size to allocate
67
* \param out_addr resulting pointer to the new block,
68
* undefined in the error case
69
* \return true on success
70
*/
71
bool
alloc(
size_t
size
,
void *
*
out_addr
)
override
72
{
73
if
(
(
_amount -
_consumed)
<
(
size +
_allocator->
overhead(
size)
)
)
{
74
PWRN(
"Quota exceeded! amount=%zu, size=%zu, consumed=%zu"
,
75
_amount,
(
size +
_allocator->
overhead(
size)
)
,
_consumed)
;
76
return
false
;
77
}
78
bool b =
_allocator->
alloc(
size,
out_addr)
;
79
if
(
b)
80
_consumed +=
size +
_allocator->
overhead(
size)
;
81
return
b
;
82
}
83
84
/**
85
* Free block a previously allocated block
86
*/
87
void
free(
void *
addr
,
size_t
size
)
override
88
{
89
_allocator->
free(
addr,
size)
;
90
_consumed -=
size +
_allocator->
overhead(
size)
;
91
}
92
93
/**
94
* Return amount of backing store consumed by the allocator
95
*/
96
size_t
consumed(
)
const
override
{
return
_consumed
;
}
97
98
/**
99
* Return allocation limit
100
*/
101
size_t
quota(
)
const
{
return
_amount
;
}
102
103
/**
104
* Return meta-data overhead per block
105
*/
106
size_t
overhead(
size_t
size
)
const
override
{
return
_allocator->
overhead(
size)
;
}
107
108
bool
need_size_for_free(
)
const
override
{
109
return
_allocator->
need_size_for_free(
)
;
}
110
}
;
111
112
#
endif /* _INCLUDE__BASE__ALLOCATOR_GUARD_H_ */