/* * \brief Capability-selector allocator * \author Stefan Kalkowski * \date 2010-12-06 * * This is a Fiasco.OC-specific addition to the process enviroment. */ /* * Copyright (C) 2010-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. */ /* Genode includes */ #include #include #include #include /* Fiasco.OC includes */ namespace Fiasco { #include #include } using namespace Genode; /** * First available capability selector for custom use * * Must be initialized by the startup code */ static unsigned long __first_free_cap_selector = Fiasco::Fiasco_capability::USER_BASE_CAP; /** * Low-level lock to protect the allocator * * We cannot use a normal Genode lock because this lock is used by code * executed prior the initialization of Genode. */ class Alloc_lock { private: int _state; public: enum State { LOCKED, UNLOCKED }; /** * Constructor */ Alloc_lock() : _state(UNLOCKED) {} void lock() { while (!Genode::cmpxchg(&_state, UNLOCKED, LOCKED)) Fiasco::l4_ipc_sleep(Fiasco::l4_ipc_timeout(0, 0, 500, 0)); } void unlock() { _state = UNLOCKED; } }; /** * Return lock used to protect capability selector allocations */ static Alloc_lock *alloc_lock() { static Alloc_lock alloc_lock_inst; return &alloc_lock_inst; } addr_t Capability_allocator::alloc(size_t num_caps) { alloc_lock()->lock(); int ret_base = _cap_idx; _cap_idx += num_caps * Fiasco::L4_CAP_SIZE; alloc_lock()->unlock(); return ret_base; } void Capability_allocator::free(addr_t cap, size_t num_caps_log2) { // PWRN("Not yet implemented!"); } Capability_allocator::Capability_allocator() : _cap_idx(__first_free_cap_selector) { /* initialize lock */ alloc_lock(); } Capability_allocator* Capability_allocator::allocator() { static Capability_allocator inst; return &inst; }