genode/repos/base/include/base/allocator_guard.h
Norman Feske 17c79a9e23 base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.

While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).

To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.

Issue #1987
2016-08-29 17:27:10 +02:00

114 lines
2.7 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 _INCLUDE__BASE__ALLOCATOR_GUARD_H_
#define _INCLUDE__BASE__ALLOCATOR_GUARD_H_
#include <base/allocator.h>
#include <base/log.h>
#include <base/stdint.h>
namespace Genode { class Allocator_guard; }
/**
* This class acts as guard for arbitrary allocators to limit
* memory exhaustion
*/
class Genode::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; }
/**
* Consume bytes without actually allocating them
*/
bool withdraw(size_t size)
{
if ((_amount - _consumed) < size)
return false;
_consumed += size;
return true;
}
/*************************
** 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) override
{
if ((_amount - _consumed) < (size + _allocator->overhead(size))) {
warning("Quota exceeded! amount=", _amount,
", size=", (size + _allocator->overhead(size)),
", consumed=", _consumed);
return false;
}
bool const 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) override
{
_allocator->free(addr, size);
_consumed -= size + _allocator->overhead(size);
}
/**
* Return amount of backing store consumed by the allocator
*/
size_t consumed() const override { return _consumed; }
/**
* Return allocation limit
*/
size_t quota() const { return _amount; }
/**
* Return meta-data overhead per block
*/
size_t overhead(size_t size) const override { return _allocator->overhead(size); }
bool need_size_for_free() const override {
return _allocator->need_size_for_free(); }
};
#endif /* _INCLUDE__BASE__ALLOCATOR_GUARD_H_ */