genode/base/include/base/allocator_guard.h
2013-01-10 21:44:47 +01:00

94 lines
2.2 KiB
C++

/*
* \brief A guard for arbitrary allocators to limit memory exhaustion
* \author Stefan Kalkowski
* \date 2010-08-20
*/
/*
* 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.
*/
#ifndef _ALLOCATOR_GUARD_H_
#define _ALLOCATOR_GUARD_H_
#include <base/allocator.h>
#include <base/printf.h>
#include <base/stdint.h>
namespace Genode {
/**
* This class acts as guard for arbitrary allocators to limit
* memory exhaustion
*/
class Allocator_guard : public Allocator
{
private:
Allocator *_allocator; /* allocator to guard */
size_t _amount; /* total amount */
size_t _consumed; /* already consumed bytes */
public:
Allocator_guard(Allocator *allocator, size_t amount)
: _allocator(allocator), _amount(amount), _consumed(0) { }
/**
* Extend allocation limit
*/
void upgrade(size_t additional_amount) {
_amount += additional_amount; }
/*************************
** Allocator interface **
*************************/
/**
* Allocate block
*
* \param size block size to allocate
* \param out_addr resulting pointer to the new block,
* undefined in the error case
* \return true on success
*/
bool alloc(size_t size, void **out_addr)
{
if ((_amount - _consumed) < (size + _allocator->overhead(size))) {
PWRN("Quota exceeded! amount=%zd, size=%zd, consumed=%zd",
_amount, (size + _allocator->overhead(size)), _consumed);
return false;
}
bool b = _allocator->alloc(size, out_addr);
if (b)
_consumed += size + _allocator->overhead(size);
return b;
}
/**
* Free block a previously allocated block
*/
void free(void *addr, size_t size)
{
_allocator->free(addr, size);
_consumed -= size - _allocator->overhead(size);
}
/**
* Return total amount of backing store consumed by the allocator
*/
size_t consumed() { return _consumed; }
/**
* Return meta-data overhead per block
*/
size_t overhead(size_t size) { return _allocator->overhead(size); }
};
}
#endif /* _ALLOCATOR_GUARD_H_ */