genode/repos/base/include/base/synced_allocator.h
Norman Feske dc39a8db62 base: introduce Allocator::try_alloc
This patch changes the 'Allocator' interface to the use of 'Attempt'
return values instead of using exceptions for propagating errors.

To largely uphold compatibility with components using the original
exception-based interface - in particluar use cases where an 'Allocator'
is passed to the 'new' operator - the traditional 'alloc' is still
supported. But it existes merely as a wrapper around the new
'try_alloc'.

Issue #4324
2021-11-29 15:11:52 +01:00

76 lines
1.9 KiB
C++

/*
* \brief Mutex-guarded allocator interface
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2008-08-05
*/
/*
* Copyright (C) 2008-2020 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__BASE__SYNCED_ALLOCATOR_H_
#define _INCLUDE__BASE__SYNCED_ALLOCATOR_H_
#include <base/allocator.h>
#include <base/synced_interface.h>
namespace Genode {
template <typename> class Synced_allocator;
}
/**
* Mutex-guarded allocator
*
* This class wraps the complete 'Allocator' interface while
* preventing concurrent calls to the wrapped allocator implementation.
*
* \param ALLOC class implementing the 'Allocator' interface
*/
template <typename ALLOC>
class Genode::Synced_allocator : public Allocator
{
private:
Mutex _mutex { };
ALLOC _alloc;
Synced_interface<ALLOC, Mutex> _synced_object;
public:
using Guard = typename Synced_interface<ALLOC, Mutex>::Guard;
template <typename... ARGS>
Synced_allocator(ARGS &&... args)
: _alloc(args...), _synced_object(_mutex, &_alloc) { }
Guard operator () () { return _synced_object(); }
Guard operator () () const { return _synced_object(); }
/*************************
** Allocator interface **
*************************/
Alloc_result try_alloc(size_t size) override {
return _synced_object()->try_alloc(size); }
void free(void *addr, size_t size) override {
_synced_object()->free(addr, size); }
size_t consumed() const override {
return _synced_object()->consumed(); }
size_t overhead(size_t size) const override {
return _synced_object()->overhead(size); }
bool need_size_for_free() const override {
return _synced_object()->need_size_for_free(); }
};
#endif /* _INCLUDE__BASE__SYNCED_ALLOCATOR_H_ */