/* * \brief A guard for RAM session clients to limit memory exhaustion * \author Christian Prochaska * \date 2012-04-25 */ /* * Copyright (C) 2012 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 _RAM_SESSION_CLIENT_GUARD_H_ #define _RAM_SESSION_CLIENT_GUARD_H_ #include #include #include #include namespace Genode { class Ram_session_client_guard : public Ram_session_client { private: size_t _amount; /* total amount */ size_t _consumed; /* already consumed bytes */ Lock _consumed_lock; public: Ram_session_client_guard(Ram_session_capability session, size_t amount) : Ram_session_client(session), _amount(amount), _consumed(0) { } Ram_dataspace_capability alloc(size_t size, bool cached) { Lock::Guard _consumed_lock_guard(_consumed_lock); if ((_amount - _consumed) < size) { PWRN("Quota exceeded! amount=%zu, size=%zu, consumed=%zu", _amount, size, _consumed); return Ram_dataspace_capability(); } Ram_dataspace_capability cap = Ram_session_client::alloc(size, cached); _consumed += size; return cap; } void free(Ram_dataspace_capability ds) { Lock::Guard _consumed_lock_guard(_consumed_lock); _consumed -= Dataspace_client(ds).size(); Ram_session_client::free(ds); } int transfer_quota(Ram_session_capability ram_session, size_t amount) { Lock::Guard _consumed_lock_guard(_consumed_lock); if ((_amount - _consumed) < amount) { PWRN("Quota exceeded! amount=%zu, size=%zu, consumed=%zu", _amount, amount, _consumed); return -1; } int result = Ram_session_client::transfer_quota(ram_session, amount); if (result == 0) _consumed += amount; return result; } size_t quota() { return _amount; } size_t used() { Lock::Guard _consumed_lock_guard(_consumed_lock); return _consumed; } }; } #endif /* _RAM_SESSION_CLIENT_GUARD_H_ */