genode/base-foc/src/base/env/cap_sel_alloc.cc

108 lines
2.0 KiB
C++

/*
* \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 <base/cap_sel_alloc.h>
#include <base/native_types.h>
#include <base/printf.h>
#include <cpu/atomic.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/ipc.h>
#include <l4/sys/consts.h>
}
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;
}